Getting rendered body - php

I've been working with slim framework and I found a problem. I'm using mpdf library to generate pdf files out of the html content I'm passing to it. I'm also using Twig Templating Engine for (I think) obvious reasons. My problem is that I can't access body rendered by Slim Twig View, at the time the controller is working, because the data is still in the output buffer. I've made a workaround by creating middleware class intercepting a request with specific route and generating the pdf file from it's body but I don't think that's the way it's supposed to be done. I was also trying not to mess with ob_get_contents in the controller because that's like working against the framework.
So here is my question: Is there a better way to do what I did?

Twig's core library contains a class called Twig_Environment, which is used for rendering views. This class has these methods:
$twig->display('view.html.twig', $variables);
This will immediately output the generated content, which is not what you want for your PDF. You want this method:
$content = $twig->render('view.html.twig', $variables);
This method will return the generated HTML and won't echo it. You can then pass $content to your PDF library to convert it to PDF.
I don't know the framework you're using, you'll need to find a way to access the instance of the Twig_Environment class.

Related

Laravel View::make after filter?

Is there a way to someone have an after filter for the View::make? What im trying todo is to run the content from View::make that is returned, through an HTML minifier.
I already have App::after that minifies the final html doc. But see, im putting the View::make response into a json object (for ajax requests) and i need the response to be minified.
After filters generally work after the response has been sent to the user.
So to minify the HTML that the user will see need to be processed before it is sent.
But before filters will not work here either. As they are called before the controller method is processed.
So you will have to your process to be used within your controller, a possible solution could be to use a helper function with your minify code, or as a function within your BaseController, which is accessible to all your controllers which called the helper function.
You can do the following within your controller;
$view = View::make('view.path', $data)->render()
This will render and process the view into the HTML the user will see.
You can then pass this to the function you have to minify the HTML and insert it into the JSON response.

Injecting CSS into the layout from within a zf2 module

I'm almost done writing a very simple module for zf2. One thing I'd like my module to do is to inject some css to the layout so that the HTML it generates displays in a nicer way.
Is this possible to do from within a module? If so, how?
EDIT: Thank you all for the prompt responses. However I think I probably didn't explain myself very clearly. When I say "inject some css" I mean taking a string of css and having it actually rendered INSIDE the layout. I didn't mean linking to an external css file or having an asset manager publish my files like the answers so far have suggested.
See Publishing assets from modules in Zend Framework 2 or How to merge Zend Framework 2 module public directories for discussion of the options you have for pushing public assets from a module.
And in addition to pushing your module assets to public, you could put the append into a triggered method like onBootstrap:
public function onBootstrap($e) {
$sm = $e->getApplication()->getServiceManager();
$headLink = $sm->get('viewhelpermanager')->get('headLink');
$headLink->appendStylesheet('/assets/MyModule/css/mystylesheet.css');
}
Try to use something like:
$sm = $this->getEvent()->getApplication()->getServiceManager();
$helper = $sm->get('viewhelpermanager')->get('headLink');
$helper->prependStylesheet('/css/mystylesheet.css');
in Your module controller.
EDIT:
If you want to store css style in module, You can either render it in Your layout file (head section) or, the better way, create another route in module, for example /get/style/[:name]. This route point to another action which returns only plain text/css document. More or less :)
Add a variable to your layout for where you'd like the CSS to be inserted:
Some Link
Then in your Controller, load and assign it however you'd like:
$this->layout()->CSS = "CSS";
$this->layout()->CSS = $this->getRequest()->getPost('CSStoInject');
$this->layout()->CSS = fopen(), curl(), etc.

Can I pass data to the Codeigniter output class without displaying it?

I'm working on a way for users to be able to generate PDF copies of invoices and other tabular data. To do this, I've wrapped dompdf into a library that I can use with CI and created a method that will generate a PDF based on the return value of CI's output->get_output(). The wrapper is similar to this one on Github.
The problem is, I can't figure out a way to get the view (and HTML/CSS needed for the PDF) into CI's output class other than load->view(), which is going to write to the browser.
My only other choice would be to use curl to request the page, but that seems so silly to do since I can get it right from the output buffer. I just don't want the HTML sent to the browser, since I set headers telling the browser to expect a PDF.
To be clear, this is what I want to accomplish (in the order that I want to accomplish it):
Do everything I'd normally do to prepare the view for display
Load the view into the CI output class, but not display it
Pass the return value of output->get_output() to my dompdf library
Set the appropriate headers
Execute my dompdf method that will send the PDF to the browser
I don't see any way of doing step 2 based on the output class documentation.
Is it possible to get a view into the output class without displaying it? If so, how? I'm using CI 2.0.3.
Edit
The very helpful Anthony Sterling pointed out that I can just get what I want from the loader class by setting the third argument telling it to return a string rather than render the view to TRUE. E.g.:
$lotsaHtml = $this->load->view('fooview', $somearray, TRUE);
And that would be better in my particular instance since I don't need to load partials. However, this is still a valid and (I think) interesting question, it would also be handy to know if I could get the same from the OB, perhaps if I did have a bunch of partials. Those could be concatenated, but yuck.
It seems like I should be able to get the output class to not render anything (else, why does get_output() exist?) so I can do something else with everything it knows about. I just can't find a way to make that happen.
Edit 2
Some pseudo (but not far from reality) code illustrating what I hope to do, by showing what I did and then explaining what I actually wanted to do.
Let's say I have a public method genpdf($id) in a controller named invoice using a model named inv:
public function genpdf($invoiceId) {
$this->load->library('dompdflib');
$this->pagedata['invoice_data'] = $this->inv->getInvoice($invoiceId);
$html = $this->load->view('pdfgen', $this->pagedata, TRUE);
$this->dompdflib->sendPdf($html);
}
That is almost identical to code that I have that works right now. There, I ask the loader to parse and give me the results of the pdfgen view as a string, which I pass to the function in my dompdf wrapper that sets headers and sends the PDF to the browser.
It just seemed like this would be easy to do by just getting the output buffer itself (after setting headers correctly / etc).
Or do I just have to call the output class append_output() in succession with every partial I load?
Multiple methods loading a plethora of models need to work together to generate these (they're going in as an afterthought), so I was hoping to just collect it all and retrieve it directly from the output class. It could be that I just have to talk gradually to output->append_output() to make that happen.
...so - do I understand correctly - you want to get the whole final output (not just the view) as a string AND not display it to the user? Why dont you just overload the controllers _output() function?
class Your_controller extends CI_Controller
{
function stuff()
{
// do whatever - prep $data etc
$this->load->view('your_view', $data);
}
function _output($output)
{
// send $output to your library - get results blah blah
$result_pdf_file = $this->your_pdf_library_generator($output);
// Show something else to the user
echo "hi - I'm not what you expected - but here is your PDF";
echo $result_pdf_file; // or something like that
}
}
This means you can send ANYTHING you like to the output class - but nothing is displayed except what you want.
There are ways to improve this idea (i.e. hooks, variables to turn output on/off etc) - but the simplest would be to have this controller specifically for your pdf_generation command.
I don't see any way of doing step 2 based on the output class documentation. Is it possible to get a view into the output class without displaying it? If so, how? I'm using CI 2.0.3.
The controller _output() documentation is actually in the CI controller documentation, which is why it eluded you.

Zend Framework : Incuding other controllers in index view

I am new to Zend FW. I am looking to write a simple feedparser in a controller named Feedparsercontroller's indexAction. but i want to display the parsed feed output as a widget on my index page. how can i drive the output/ variable data to my indexview?
The below is my parser.
class FeedparserController extends Zend_Controller_Action {
public function init() {
/* Initialize action controller here */
}
public function indexAction() {
$feedUrl = 'http://feeds.feedburner.com/ZendScreencastsVideoTutorialsAboutTheZendPhpFrameworkForDesktop';
$feed = Zend_Feed_Reader::import ( $feedUrl );
$this->view->gettingStarted = array ();
foreach ( $feed as $entry ) {
if (array_search ( 'Getting Started', $entry->getCategories ()->getValues () )) {
$this->view->gettingStarted [$entry->getLink ()] = $entry->getTitle ();
}
}
}
}
i want to implement the same with my login , register controllers as well.
Perhaps I'm not understanding your question fully.
But, it seems the best approach here would be to create a separate feed controller that is solely responsible for the business logic associated with feeds (retrieving, massaging, setting to view, etc).
Then, create a partial which contains javascript code to call the feed controller, which then outputs the widget you're desiring. This does a few things very well.
It centralizes feed-related logic
It allows you to place the feed widget wherever you want
It is a SOA approach which is generally a good thing
Hope this helps!
I think the best logic with widgets is ajax.
Use some js widgets libraries (maybe jQuery ui for example), then make these widgets be loaded by some ajax queries, returning HTML, this allow you as well simple widgets reloading behviours (without relaoding the whole page).
In the server Side you'll need to allow your controller/Action to be called via ajax requests and to send only html snippets (not a whole page with all the layout).
To do that check ContextSwitch and AjaxContext Action Helpers. You will tell your FeedparserController that the index action can be called with /format/html in an XMLHHTTPRequest, and that in this case the view helper will be index.
In the init part you will say the indexAction can be called in ajax mode, rendering html snippets ('html'):
$Ajaxcontext = $this->_helper->getHelper('AjaxContext');
$Ajaxcontext->addActionContext('index', 'html')
->initContext();
Now simply rename your view script feedparser/index.phtml to feedparser/index.ajax.phtml
In the indexAction, do your stuff and output what you want on your view script, do not think about layout composition problems, you're working alone with your own layout part and the composition is done on the js side.
In the javascript part, ensure you're calling via ajax ($.load or $.ajax with jQuery maybe) the url with format/html added as parameters (so http://example.com/feedparser/index/format/html)
Note that in my opinion you should use json responses and not html, maybe json with some html inside. But that's a matter on how you want to control your ajax communication (and handle errors, redirection and such, and it's another subject).
What about a view helper ?
You can read about it View Helpers in Zend Framework

GWT RequestBuilder - Changin URLs

I'm using GWT to dynamically load html snippets from php script. I define the snippet i want the php script to return in the url (test.php?snippet=1). Now in GWT i have a function "getSnippet(int snippet id)" that uses a RequestBuilder to retrieve the snippet. It works perfectly fine, but it bothers me that i have to create a new RequestBuilder everytime getSnippet gets called. I'd rather have one ReqestBuilder and just change the url when getSnippet is called...
Is there a way to do this ?
Thank you !
In looking at the source code, I can't see a good reason why they are doing this. I would like to think that the GWT developers decided to leave out the setUrl method for a reason and included it in the constructor instead.
If you really want to do it, one way around this would be to extend the class and add a setUrl(String url) method. Modify all your current uses of RequestBuilder to use your newly extended class and see if anything breaks.

Categories