I will share with you a secret known only to eZ Publish gurus: persistent variables are not that hard to learn :). Of course, learning depends on good materials so hopefully this blog post will help clarify some things.
Just for test I spent 30 seconds on google (usually enough time) to find some good learning content about persistent variables and I found no such page on ez.no ecosystem. I did found 2 short blog posts (first and second) about the topic, not counting several forum posts. Interesting though, from both blogs you can see that authors haven’t been aware of persistent variables possibilities (second one even calls it mythical) but realised quickly how useful they are.
Before proceeding to the good stuff there is an important thing to know to successfully master persistent variables (advanced users can skip the next part).
The Execution Order
Sometimes while you are learning a technology you get misled and learn things the wrong way. When you reach a certain point and look back you can only hit the wall with your head because of the time you wasted. I admit, when starting with eZ, it took me a while to understand in which order templates are executed. Probably the fact that pagelayout.tpl includes the $module_result.content was misleading so I thought pagelayout is executed first. Don’t make the same mistake.
The right clue was under my nose all the time: check the debug log templates list, node/view/full template is the first :)
Why is this important? You can’t transfer variables from the layout to the module, of course. But you can do it in the other direction, although, that usage is not obvious as you may think.
Persistent variables
First let see what documentation specifies about these variable:
“A variable set in one of the templates used by the view that was executed. Regardless of the caching mechanisms used, this variable will be available in the pagelayout. The type of the persistent variable depends on the value it contains. If the variable is not set, it will simply return a boolean FALSE” (link). Not clear enough, I would say, so lets help out here.
Setting a persistent variable
You can find the simplest example in full frontpage template of the ezwebin extension:
{set scope=global persistent_variable=hash('left_menu', false(), 'extra_menu', false(), 'show_path', false())}
Here you enable or disable certain parts in the ezwebin pagelayout. The problem with this code is that:
- all variables can be set only once, if you call the above line the second time it will reset all variables set before
- hash array can’t be created dynamically so you can’t set more combinations without nested “if” nightmare..
Solutions is the ezpagedata_set() operator from the ezwebin extension. You can simply set each variable like this:
{ezpagedata_set('key', 'value')}
{ezpagedata_set('key2', 'value2')}
More elegant, of course.
Using persistent variable
After you set a persistent variable it can be used where needed in pagelayout templates. There are 2 ways:
- via module_result variable:
{$module_result.content_info.persistent_variable.key}
- via ezpagedata() operator from ezwebin extension:
{def $pagedata = ezpagedata()}
{$pagedata.persistent_variable.key}
Simple is that.
Few simple scenarios
- controlling things shown in layout like path, menus and similar
- showing some information from $node so it's not needed to fetch it again
- replacing some default info with current node specific stuff (e.g. <title>, meta description, meta keywords, etc.)
Advanced usages
1. Override a template with persistent variable:
[foo_layout]
Source=pagelayout.tpl
MatchFile=pagelayout_foo.tpl
Subdir=templates
Match[persistent_variable]=foo
2. Transfer bigger chunk of html. Use set-block and persistent variable to transfer bigger chunk of code.
{set-block variable=$foo}
<div class=”box”>
{node_view_gui content_node=$child view=’line’}
</div>
{/set-block}
{ezpagedata_set('foo', $foo)}
3. Doing some really cool stuff like setting Varnish TTL via custom headers (via @jeanvoye).
Things to remember
Persistent variables are usually generated in full views and as such are part of view cache. They will expire with the view cache of the view. Of course, if used within a cache-block in pagelayout they will be cached again. So don’t get confused.
You can’t store complex data types like objects, but usually numbers, strings, arrays and hashes are enough.
Any feedback on this topic would be useful. Thanks.