I use a basic setup which uses a layout.phtml for the HTML Layout and view scripts for the content part.
I want to control some variables in the layout in my controllers, i.e. the title of my site.
How can I access my layout to output variables from within the controller?
Thanks for your feedback!
Anything you assign to view in your controllers will be accessible both in view scripts and layout scripts - they use the same Zend_View.
As for setting the title of the page, simply use the HeadTitle view helper http://framework.zend.com/manual/en/zend.view.helpers.html#zend.view.helpers.initial.headtitle
$myLayout = Zend_Layout::getMvcInstance()->getView();
$myLayout->var = 'foo:bar';
in layout.phtml:
echo $this->layout()->var;
Related
Im new to October CMS
I read the documentation and its states that components can be used inside a layout on the PHP Section (https://octobercms.com/docs/cms/layouts)
i want to create a component that will be used as configuration file for my theme, declaring global variables, that will be used on all pages, but will also be used for all layouts i will create. but i cant find how to do it via code. Like include a file. i want this to used this parameters inside the PHP Section of the layout and the pages.
If components is not the best way, can you ppl sugest me what is the best way
I did before search a lot to find some way that I can share variables to all my layouts and pages but couldn't find anything.
So I tried my own trick and it worked.
In your frontend you must have header.htm partial. so in the code section in it write a onStart() function and set your global variables so you can access them from any layout or page which includes the header partial.
For example in your header.htm code section:
function onStart() {
$this['my_var'] = ['name' => 'Ahmed', 'age' => 17];
}
That way you can access my_var variable wherever you want in all your layouts and pages which header.htm partial is included.
I'm going through some of the code and projects provided here http://fatfreeframework.com/development. My goal is to create a lightweight MVC kickstarter projecting using F3. I know it's been done before, but I'm using this as a learning exercise and I hope to have something useful come out of it in the end.
The biggest stumbling block I'm coming across right now is the concept of layouts. I know the documentation mentions using templates within templates, but I'm struggling to implement it in practice. In the end, I want to have 1 or 2 layouts (default layout, maybe a custom one for modal popups, etc), and then have my views rendered wrapped inside of those layouts. I want a default layout and then the ability to override the default for the few pages that need custom ones. Here's the code I've been using:
// this is the handler for one of my routes, it's on a controller class called Index
public function index($f3, $params)
{
// this (or anything else) should get passed into the view
$f3->set('listOfItems',array("item1", "item2"));
// set the view
$f3->set('content', 'index.htm')
// render the layout
\Template::instance()->render('layout.htm');
}
Unfortunately, I keep getting a blank page. Am I going about this completely the wrong direction, or am I on the right track? Is there a way to set a default layout somewhere so it's used until it's overridden?
Well you could create a base class with a default layout. Then you extend it for each controller class. For example:
abstract class Layout {
protected $tpl='layout.htm';
function afterRoute($f3,$params) {
echo \Template::instance()->render($this->tpl);
}
}
Then:
class OneController extends Layout {
function index($f3,$params) {
$f3->set('listOfItems',...);
$f3->set('content','one/index.htm');
}
}
class AnotherController extends Layout {
protected $tpl='popup.htm';//override default layout here
function index($f3,$params) {
$f3->set('listOfItems',...);
$f3->set('content','another/index.htm');
}
}
In layout.htm:
<body>
<div id="content">
<include href="{{#content}}" if="isset(#content)"/>
</div>
</body>
Structure of the UI folder:
/ui
|-- layout.htm
|-- popup.htm
|-- one
|-- index.htm
|-- another
|-- index.htm
This is just one example of how you could organize your code. F3 is loose enough to let you organize it in a multitude of ways.
I had exactly the same problem - set everything up as required, rendered the layout, and kept getting a blank page. Also when I checked the HTML source of the rendered page it was completely empty.
If you look closely however rendering the layout is not enough, you have to also print it using the echo command. So rather than the following example which appears at first glance to be correct:
$f3->route('GET /',
function($f3) {
// Instantiates a View object
$view = new View;
// Render the page
$view->render('template/layout.php');
you actually need the last line to start with echo:
echo $view->render('template/layout.php');
For more examples see:
http://fatfreeframework.com/views-and-templates
https://www.digitalocean.com/community/tutorials/how-to-use-the-fat-free-php-framework
http://takacsmark.com/fat-free-php-framework-tutorial-4-database-models-crud/
Also for some reason (which I'm sure will become clear soon - I've only just started using the Fat Free Framework) you seem to also be able to render an .htm file which contain embedded PHP (i.e. they don't have to have the .php extension).
I'm trying to pass a variable from the master layout to the view, but I'm having no luck.
layout.phtml
$this->hadMessages = true;
myview.phtml
var_dump($this->hadMessages);
The var_dump always comes back with NULL. From what I've read, the layout is a view too, so it should be in the same context, right?
I'm using Zend Framework 1.11.
The layout is rendered after the view, so that's why this doesn't work. Depending on what you are trying to do you might be able to achieve the desired effect with the help of a controller plugin.
There is no way to pass variable from layout to view, because according to MVC pattern you shouldn't have tasks like this. Wether layout contains some messages or not should be decided on controller or bootstrap level, not in layout itself.
It means in controller you should make all needed assignments like $this->view->layout_messages_shown = true and get this variable value both in layout and view like echo ( $this->layout_messages_shown ? "messages shown" : "messages hidden" )
I can't understand when to use Layout's variables and when to use View's variables to get page segments on the page. Here is the picture form their Layout package tutorial ($this means the View instance everywhere):
Why Navigation, Content and Sidebar segments are got as Layout variables?
$this->layout()->nav;
But HeadTitle, HeadScript, HeadStylesheet are got straightly from View?
$this->headTitle(); // I know that this is a placeholder view helper.
// But this segment of the page logically belongs to Layout.
// and it has to be called smth like view->layout->placeholder
And why Header and Footer are from some partial method of the View but not Layout's properties?
$this->partial('header.phtml');
I've tried to change them and both ways work fine:
echo $this->nav; // I assigned navigation segment script to the View and it works;
I tried to assign Footer segment script to the Layout and it also works:
$layout->footer = $footer;
echo $this->layout()->footer; // it also works, it's displayed on the page
Any of the ways may be applied to any variable on the page. For example in Navigation segment I have a lot of variables to display and I can output them using both ways - one variable as Layout's property, another one sa View's property.
So what is the rule to use them right way? When should I use View's variables and when Layout's ones?
I agree that this isn't very clear from the documentation, and I don't think $this->layout()->nav is explained at all. A few points that might help:
$this->layout() is actually a call to the layout view helper, which returns the current instance of Zend_Layout.
Zend_Layout registers its own placeholder helper (with the key 'Zend_Layout'), and by default creates a 'content' variable in this.
the Zend_Layout class has a magic __get() method which proxies any member variable calls over to its registered placeholder container. So calling $this->layout()->content is another way of writing $this->placeholder('Zend_Layout')->content
the Zend_Layout class also has a magic __set() method that proxies stored data to the placeholder class. So $layout->footer = 'foo' is the same as calling $this->placeholder('Zend_Layout')->footer = 'foo' in the view
With that in mind:
Why Navigation, Content and Sidebar segments are got as Layout variables?
As these are accessing data stored in Zend_Layout's placeholder. You could also use $this->placeholder('Zend_Layout')->content
But HeadTitle, HeadScript, HeadStylesheet are got straightly from View?
These are view helpers.
And why Header and Footer are from some partial method of the View but not Layout's properties?
This is the standard way of accessing content from other templates.
In general, assume that using the view object is the correct way to access the data. Use the layout object/helper only if you know the data is in the layout placeholder.
The advantage of using placeholders over partials is that you can access and modify them in several different places, including in the view itself. For example say you had a sidebar which is stored in a partial. If you were to store this in the Zend_Layout placeholder instead (for example in a controller plugin), you can then override this for certain actions in the controller:
public function someAction()
{
$this->view->layout()->sidebar = 'Some other sidebar content';
}
or in the view script itself:
<?php $this->layout()->sidebar = 'Content for this page only'; ?>
Attempting to learn CI and going through the docs to get a better understanding. Without getting a separate library, I could make a template by including a list of views like so:
$this->load->view('header');
$this->load->view('navigation');
$this->load->view('sidenav_open');
$this->load->view('blocks/userinfo');
$this->load->view('blocks/stats');
$this->load->view('sidenav_close');
$this->load->view('content',$data);
$this->load->view('footer');
This makes sense but would I actually have that on each of my controllers (pages)? Not sure if there is a way to include this in the initial controller (welcome) and then in the others somehow reference it? Or perhaps there is something I am missing completely
You can load views from within a view file. for example, consider a generic page template called page_template.php:
<html>
<body>
<div id = "header">
<?php $this->load->view('header');?>
<?php $this->load->veiw('navigation');?>
</div>
<div id = "sidenav">
<?php $this->load->view('sidenav');?>
</div>
<div id = "content">
<?php echo $content;?>
</div>
<div id = "footer">
<?php $this->load->view('footer');?>
</body>
</html>
Load your more dynamic areas by making use of codeigniter's abiltiy to return a view as a variable in your controller:
$template['content'] = $this->load->view('content',$data,TRUE);
$this->load->view('page_template',$template);
By passing TRUE to the load function, CI will return the data from the view rather than output to the screen.
Your sidenav section could be it's own view file, sidenav.php, where you have your 'blocks' hard-coded or loaded similar to the above example.
I've done it both ways, including every stinking bit of views in each controller method, and by using a page template that loads sub-views and dynamic areas, and by far, the second method makes me happier.
Loading views from within views can lead to confusion.
Extending the Controller class hides much of the complexity that comes from that approach, but still utilises the idea of generating common views (footer, header, navigation bars, etc) by rendering them once on every page load.
Specifically, consult the CI User Guide and wiki for references to MY_Controller - you extend this by creating a MY_Controller.php file in the ./libraries directory.
In there you can call view fragments, also utilising the third-parameter=true feature of the load->view() call. You load these into $this->data - for example loading the footer into $this->data['footer']. In your various controllers, continue adding view data to $this->data. In your views - I typically use a template that does little other than skeleton HTML and some basic CSS, and then echos the entire header, footer, nav and main content lumps as variables taken from $this->data
Added bonus - if you're new to CI, you'll likely soon be looking for how to do other things that a MY_Controller will make easy for you :)
I've got a wiki page on simplifying the generation and display of view partials, as you're trying to do here, using MY_Controller at:
https://github.com/EllisLab/CodeIgniter/wiki/Header-and-Footer-and-Menu-on-every-page---jedd