I have a rendered view in my application and when I export to PDF I'd like to use the data that I rendered before. Now I'm using another way to do it, I load all things again to export. How can I do it?
I've used this code but don't had success:
array('label'=>'Export pdf', 'url'=>array($this->renderPartial(
'ViewPDF2', array('sessao' => $GLOBALS['session'],'name_project'=>$model->name_project,'id_project'=>$model->id_project,'dataStart'=>$model->data_start,'dataEnd'=>$model->data_end))))
I'm not sure how you've got that code in your view? You're passing that array as an argument to some function? All we can see right now is you're defining an array.
The general approach for rendering a view within in a view would be something like this (this is the container view file):
<?php //view code here ?>
<!-- some html in your view-->
<div id='included_view' >
<?php $this->renderPartial('viewName', array('argForView'=>$foo)); ?>
</div>
<!-- rest of view -->
Note that the use of $foo there means that you previously passed that variable to the container view (or that you defined $foo in a PHP code block before the renderPartial)
In url parameter you should use an URL Address which refer to an action which that action render the view that exporting to PDF.
The renderPartial method just render a view file in your self layout format.
Related
I have deployed an app using cakephp. Now i have some data which i want to render on some logic. This data should be showed as a page including some inputs and other fields.
One thing is to do this in javascript side but it will not be a suitable option to make a whole html in javascript.
Other solution on which i am working is to pass the data to the .ctp file. Get the html and pas this to my content.
I am trying to do this as
$html = $this->render('myview');
$this->set('html', $view);
but it render the myview as a page not as html to be shown to my view.
Follow the code to achieve the same, (this code in your controller's method/action)
//Variables used in view
$data = $this->Admins->newEntity();
// create a builder
$builder = $this->viewBuilder();
// configure as needed
$builder->setLayout('default');
$builder->setTemplate('/Admins/login'); //Here you can use elements also
$builder->setHelpers(['Html']);
// create a view instance
$view = $builder->build(compact('data')); //Pass the variables to the view
// render to a variable
$output = $view->render();
//Print output
pr($output);
die;
From what I understood from your question and comments, you want to render something in a certain place of your view, but you want to put code for that component in separate .ctp file. CakePHP already has built in tools to achieve this - Elements and Cells.
Elements are reusable pieces of code, which resides in src/Template/Element directory. To create an element, simply create new .ctp file (eg. myelement.ctp) in this directory, and output it in your main view using:
<?= $this->element("myelement") ?>
Elements have access to variables passed to view from which are called, but if needed, one can also pass variables as second argument:
<?= $this->element("myelement", ["somevariable" => "somevalue"]) ?>
On the other hand, you have also Cells, which should be used in need to create an reusable component which depends on some logic which should be separated from controller code. Cell consists of two parts - a Cell class, which is equivalent for controller, and template file. It can be baked by:
bin/cake bake cell Sample
This command will create src/View/Cell/SampleCell.php and src/Template/Cell/Sample/display.ctp files. In first of them, a standard controller logic can be performed. In second, you can put HTML and access to passed variables. Cell can be rendered into a view by using:
<?= $this->cell("Sample") ?>
More info can be found in docs:
Elements
View Cells
I have Zend Framework MVC application with module structure like that above:
/application
/layouts
/sripts
/layout.phtml
/modules
/default
/controllers
/IndexController.php
/OtherController.php
/views
/scripts
/index
/index.phtml
/second.phtml
/third.phtml
/fourth.phtml
/other
/index.phtml
/second.phtml
/third.phtml
/fourth.phtml
In my layout.phtml i have a line
<div id="main">
<?= $this->layout()->content ?>
</div>
I want to wrap rendered action views in every action of IndexController and OtherController, except fourth, with some code, like <div id='top'></div> at the beggining, and <div id='bottom'></div> at the end of rendered action view.
I don't want to do it manually in every action view *.phtml file. There are too many in real application, besides code looks messy with that solution.
How to do it?
In a layout file, you can echo a layout variable. This is usually where we put the html rendered by an action. You can append the rendering from several actions into a single layout variable, and they will be displayed in LIFO order. Here is how that variable is inserted into the layout file:
<?php echo $this->layout()->myLayoutVariable; ?>
You can also set up a placeholder variable inside your layout file:
<?php echo $this->placeholder('myPlaceholderVariable'); ?>
In one of your view files, you can then provide the html content for this placeholder variable:
<?php
$this->placeholder('myPlaceholderVariable')->append('<p>HTML GOES HERE</p>');
?>
If you don't set any value for the placeholder variable, nothing will be rendered in the layout file. But if you do set a value for that placeholder variable, it will be inserted into the html.
You could set a different layout only for IndexController and OtherController : in the init() method of each controller, you can add the following:
Zend_Layout::getMvcInstance()->setLayout('some other layout');
Try this:
$(document).ready(function(){
$("#main").before(//insert header html here);
$("#main").after(//insert footer html here);
});
I'm not sure what you mean by the fourth, but if you want to target a specific controller/action you could grab the window.location.href and make your function dependent on a specific URL you want to look for.
Hope that helps.
How does Zend link $this->layout()->content with scripts/index/index.phtml?
I think I'm failing to understand the basics of how the pages are supposed to stick together. I've looked at the quick start on the zend site but it's far too simplistic.
So as Tomáš Fejfar explained that's how the $this->layout()->content works. Yet what is interesting is that 'content' is not just a variable in the layout. In fact, 'content' is a key in a View placeholder called 'Zend_Layout'. For this reason, the following snippets are equivalent to echo $this->layout()->content in your layout.phtml:
$placeHolder = Zend_View_Helper_Placeholder_Registry::getRegistry()->getContainer('Zend_Layout');
echo $placeHolder['content'];
// or
echo $this->placeholder('Zend_Layout');
// or
echo $this->placeholder('Zend_Layout')->content;
This can be very useful. What I mean is that you can define some places in your layout.phtml that will be display values of your custom keys from 'Zend_Layout' placeholder. For instance, imagine that you would like to have a layout.phtml and you want to be able to modify text in your footer. You could do this by defining layout.phtml which will contain the following in the footer:
<div id="footer">
<?php echo $this->layout()->myFooterText; ?>
</div>
You could setup a default value for this footer in e.g. your Bootstrap.php. However, if you wanted you could modify this text in your actions as follows;
$this->view->placeholder('Zend_Layout')->myFooterText = 'Some text only for this action';
That's it what I wanted to add. Off course one could think of other scenerios, because $this->view->placeholder('Zend_Layout') is an instance of Zend_View_Helper_Placeholder_Container so you could do other things with Zend_Layout placeholder.
EDIT:
Key 'content' is a default name. You can change it to something else using setContentKey method of Zend_Layout, e.g.:
protected function _initSetNewLayoutContentKey() {
$layout = $this->bootstrap('layout')->getResource('layout');
// instead of 'content' use 'viewoutput'
$layout->setContentKey('viewoutput');
}
With this change, in your layout.phtml you would use echo $this->layout()->viewoutput; instead of echo $this->layout()->content;.
What's rendered in your view (the PHTML file) is saved into the content variable. That can be echoed in the layout template (another phtml file - preferably layout.phtml). And that'S the 'final product' :) (or maybe you want to specify you question more).
Layout is nothing more then a controller plugin which creates its own view after all dispatching has been done so it can take final response object and sets the content property of its view to response body .
So basically in your case buffer of index.phtml , gets stored in response object first then later layout takes this value and change it its own view buffer .
I have a navigation menu inside a CakePHP element file (views/elements/nav_default.ctp).
The file is included inside another element that is the header (views/elements/header_default.ctp) which is then included in the layout file (views/layouts/default.ctp).
I am trying to tell Cake to load a js file (webroot/js/mega_drop.js) from within the nav element like so:
<?php
$this->addScript('mega_drop');
?>
It does not get included. I looked at the documentation for addScript which just says:
Adds content to the internal scripts
buffer. This buffer is made available
in the layout as $scripts_for_layout.
This method is helpful when creating
helpers that need to add javascript or
css directly to the layout. Keep in
mind that scripts added from the
layout, or elements in the layout will
not be added to $scripts_for_layout.
This method is most often used from
inside helpers, like the Javascript
and Html Helpers.
The key part:
Keep in mind that scripts added from the layout, or elements in the layout will not be added to $scripts_for_layout.
So how do I do it then?
I guess I could add a <script src="/js/mega_drop.js"></script> to the default.ctp layout. That doesn't feel right though as it would tightly tie the layout and the element together.
Whats the CakePHP best practice way to do this?
addScript() does not load a file; it adds actual code to the $scripts_for_layout variable. The idea being that the layout is a good, common place to load your JavaScript files and code. That way you can output all the code in one location - in the head block or at the end - either way it's together. So if you are in a situation where you've got JavaScript code in the view, rather than output it inline, you can pass it up to the layout.
The best way to load a script file is with the HTML Helper- echo $this->Html->script("script or array('of', 'scripts')"); With that in mind, you could $this->set('scripts', 'mega_drop'); in the element and then call the Html Helper with that $scripts variable from the layout.
The problem with that: it won't work if your nav_default.ctp is called from the layout. $this->set() works inside of a view (or an element called from a view) because the View is rendered before the Layout. If you are calling your element from the layout, then it is too late to be setting viewVars for use in the layout. The best thing to do is set() the scripts variable from the Controller and use a if(isset($scripts)) { echo $this->Html->script($scripts); } in the layout.
Correct and valid 1.3.x CakePHP 2.0 Dev is from example.ctp file:
$this->addScript($this->Javascript->link('tab_enabler'));
$this->addScript($this->Html->css('jquery.tabs'));
This is an example of how to properly include CSS and JS files from the view and adding in the variable $scripts_for_layout to not generate validation error with the W3C as it is not correct to add the link to a css file in <BODY></BODY>
try
$this->Html->script('mega_drop', $inline=false);
in your element without the echo.
The Second parameter says to add it to the $scripts_for_layout variable.
You should be able to do this in your element, so that the javascript is only included when the element is.
So I had a question on general organization of code for the Zend framework with regard to the layout.
My layout is basically this:
(LAYOUT.PHTML)
<div id='header'>
<?= $this->Layout()->header ?>
</div>
<div id='main'>
<?= $this->Layout()->main ?>
</div>
<div id='footer'>
<?= $this->Layout()->footer ?>
</div>
and so on and so forth. Now, in order to keep my code in my header separate from the code of my main and the code of my footer, I've created a folder for my view that holds header.phtml, main.phtml, footer.phtml. I then use this code to assign the content of header.phtml into $this->layout()->header:
(INDEX.PHTML)
$this->Layout()->header = file_get_contents('index/header.phtml');
$this->Layout()->main = file_get_contents('index/main.phtml');
$this->Layout()->footer = file_get_contents('index/footer.phtml');
That was working great, but I've hit a point where I don't want main to be static HTML anymore. I would like to be able to insert some values with PHP. So in my Controller in indexAction, I want to be able to load from my database and put values into index/main.phtml. Is there a way to do this without restructuring my site?
If not is there a way to do it so that I can have:
The ability to put code into different sections of my layout, such as Layout()->header, Layout->footer.
Separate these pieces into different files, so that they're easy to find and organize, like my index/footer.phtml, index/main.phtml etc.
Not have to put that code into quotes unnecessarily to turn it into a string to pass it to Layout()->header etc.
Thank you guys so much for your help.
-Ethan
Here is an idea:
Assign layout()->header the filename instead of the contents.
Put your code in this file
In your layout file, include() or require() the layout->header().
Since your layout headers/footers are now parsed, you can use them just like a view.
The ->header in $this->layout()->header is response segment. You can render parts of response using $this->_helper->viewRenderer->setResponseSegment('header'); in an action.
If you use
$this->layout()->header = $this->render('index/header.phtml');
It will even use the view, therefore keeping all your variables defined when rendering the header.
I would suggest using something like
<?php echo ($header = $this->layout()->header)?
$header : $this->render('headerDefault.phtml'); ?>
in your layout file - it will render a default header from the layout folder if the view script doesn't override it.
Have you tried looking at view helpers. They are a way of structuring view logic into reusable and modular code. In this case you would use a view helper to generate each of your required segments. So your example view script would look like
$this->Layout()->header = $this->header();
$this->Layout()->main = $this->main();
$this->Layout()->footer = $this->footer();
The benefit of using view helpers over include and require statements is that all of the file handling and name resolution is handled by the framework. The manual has more information on how to set up the paths and usage examples etc.
helpers are good. Another option is like the above, putting filenames in header/footer - put the template names and use $this->render($this->layout()->header)), etc etc. This is just like the include/require above, but more consistent.