In the new edition of Confessions of an apprentice we will show you how to easily change layouts on a portion or portions of your website.
In the last two articles we have covered the creation of a custom module and a custom view of that module. Based on this, you can really customize eZ Publish to your heart's desire. And that's basically the whole point of creating your own websites, isn't it? Now we will make a turn, and look at all the ways you can change layouts on a portion of your website.
Creation of a custom page layout in eZ Publish
The need for an extra layout
Sometimes there arises a need for the developer to create a new page layout inside an existing page for a client. It's almost always based on the need to create a different look and feel on a section of a page which is used for all kinds of purposes (mobile web, different section of a page, etc.). When I say a different look and feel, I'm referring to a radical change in the layout of a page. New header, body, elements, footer, the works. There are actually three ways to do that, and we will cover them all.
Overriding a pagelayout template
Looking back on Ivo Lukač's post on persistent variables a while ago, we can see that it's relatively easy to set them using the ezpagedata_set() operator built in ezwebin. Also, there is a set-block function which we can use to set a persistent variable if the ezpagedata_set() operator is not available. We will show you how to override a layout and define it's persistent variable key, where to put the overridden template, and how to activate it.
So, open your project, and go to the settings/siteaccess folder. In it, find your siteaccess, and open it, and when you do, you will see, among all of your INI files, one called override.ini.append.php. In this file, if you recall, you override the templates which already exist in your project with custom ones. When you open the file, input the following lines of code:
[new_pagelayout]
Source=pagelayout.tpl
MatchFile=new_pagelayout.tpl
Subdir=templates
Match[persistent_variable]=new_pagelayout
What did we do here? We created a new persistent variable key in the override.ini, and linked it to a template called new_pagelayout.tpl. Now, in order for the template to work, you need to create it. So, of course, go to your extension. Open the mypage/design/mypage/override/templates/ folder and in it, create a file called new_pagelayout.tpl. Bear in mind that this layout has to be set up as your original layout in the extent that you define everything from scratch. If you need a reference, just go to the original layout in your extension (mypage/design/mypage/templates/pagelayout.tpl), and look at how it is set up. After that, clear the INI and override caches and just put whatever elements you'd like in your new layout.
To determine what templates will use this new layout, enter the following lines at the beginning of your template to set up your persistent variable like so:
{ezpagedata_set('new_pagelayout', true())}
or:
{set scope=global persistent_variable=hash('new_pagelayout', true())}
if the ezpagedata_set() operator is not available to you.
Then you can look at the object using the layout to see your results. It's important to notice that only the view view of the content module is able to set persistent variables in such a manner.
When you use a persistent variable, you decide which templates are going to use the overridden layout. The same applies to usage with nodes, classes, etc. Which means that, for example, you can create a class (let’s call it custom_class for the purposes of this article), and just use it in your override.ini like so:
[new_pagelayout]
Source=pagelayout.tpl
MatchFile=new_pagelayout.tpl
Subdir=templates
Match[class_identifier]=custom_class
Now, the new_pagelayout.tpl will be used on every object of the class you’ve defined for this purpose.
Of course, the overriding doesn’t stop at classes because you can use a big list of override conditions for your new layout. You can find the whole reference fore the override conditions here.
After you clear all caches and display an object of your custom class, you will see that the new_pagelayout.tpl will be used! Isn’t that neat? In addition, there is no big hassle in creating new sub-domains, instances of eZ Publish, and whatnot. The stuff just works and that’s the most important thing.
Also, it’s important to notice that overriding a pagelayout template is only possible with the override rules applicable in the content module. Other modules (e.g. user/login) are unable to apply this type of change to their layouts. On the other hand, no unnecessary strings need to be added to the URL. So I would recommend this method only if you need to change the look and feel of the content module.
Setting up a new layout template using the layout module
Another way of setting up a new layout for a page is through the layout module. This is a more universal way than the one previously described, because it will work for all of the modules, but you need to have an extra part in the URL.
If you have examined all of the INI files in your eZ Publish project, you may have noticed that there is a layout.ini file. This file defines all of the different layouts you can use at a given portion of your site. And when you want to use the layout you define in this INI file, you just need to enter the following lines in your address bar: /layout/set/new_pagelayout/url_of_the_node. This gives an order to eZ Publish to use a new layout instead of the default one.
To set up your layout in the INI, go to your extension. In the mypage/settings folder, create a new PHP file called layout.ini.append.php and put the following settings in it:
<?php /* #?ini charset="utf-8"?
[new_pagelayout]
PageLayout=new_pagelayout.tpl
*/ ?>
As you can see, we have set up an alias for our layout in the square brackets and determined that when you type '/layout/set/new_pagelayout', eZ Publish overrides the default pagelayout and uses everything in the template you've accessed in a new layout.
After you set up your INI, put the new_pagelayout.tpl in the mypage/design/mypage/templates folder and clear all caches. If you then try to access your object in the previously described manner, you will see that your new layout is set up correctly.
Setting up a new layout using a new module
If you remember, in the article before last we have shown you how to create a new module. This is actually a quick, surefire way to set up a new layout using a module. And it is useful only in the cases when the previous two ways we’ve described are not enough, because you can make custom PHP additions and changes.
Let's say, for example, that you have created a new module called 'get'. In it, you have created a view called 'layout'. Now, in the layout.php file in your module, just put following lines of code:
<?php
$tpl = eZTemplate::factory();
$data = new eZPageData();
$data->modify($tpl, 'ezpagedata', null, null, null, $pagedata);
$tpl->setVariable( 'pagedata', $pagedata );
$tpl->setVariable( 'pagestyle', $pagedata['css_classes'] );
$tpl->setVariable( 'pagedesign', $pagedata['template_look'] );
$tpl->setVariable( 'current_node_id', $pagedata['node_id'] );
$tpl->setVariable( "access_type", $GLOBALS['eZCurrentAccess'] );
$pagelayoutResult = $tpl->fetch( 'design:new_pagelayout.tpl' );
echo( $pagelayoutResult );
eZExecution::cleanExit();
?>
So, in here we have set up an instance of our template, and set the persistent variables for the view, also, we have set up the CSS files we are going to use, as well as the node id we wish to set for our pagedata. After everything is set up, we fetch our page layout and use it in the view. To access this view, you need to type in the address bar the following: '/get/layout/', and there you have it, a new layout for your page!
As you can see, setting up a new page layout is really not that big of a deal once you get the hang of it, and this newfound knowledge can really help you in your future projects.
Until next time, I wish you happy coding,
Tomislav