View previous topic :: View next topic |
Author |
Message |
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Fri Aug 21, 2015 7:15 am Post subject: Fetch sub template and keep the {nocache} section program. |
|
|
I want to fetch a sub template inside a template being rendered, which has a {nocache} section.
main.tpl:
Code: |
<html>
<body>
{load_sub_template}
</body>
</html>
|
Code: |
function smarty_function_load_sub_template($params, $template) {
return $template->smarty->fetch(__DIR__.'/sub.tpl');
}
|
sub.tpl
Code: |
{nocache}
{$smarty.now}
{/nocache}
|
The {nocache} is being ignored while rendering the main.tpl in caching-mode. This feature works when using {include file="sub.tpl"}, but not using the fetch() method. I tried also to pass the parent template:
Code: |
function smarty_function_load_sub_template($params, $template) {
return $template->smarty->fetch(__DIR__.'/sub.tpl',null,null,$template);
}
|
But that doesn't work either.
Are there any other ways to do that programatically what {include} does? |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Sat Aug 22, 2015 7:53 pm Post subject: |
|
|
1. If you call Smarty::fetch() the template will be rendered in its own context.
In your case 'sub.tpl' will create its own cache file which is not the case when you use {include}.
2. The main reason for result is that {load_sub_template} runs in cache mode just once when the cache of 'main.tpl' is being created. It returns the content of 'sub.tpl' at that time.
Code: | {load_sub_template nocache} |
would solve that problem. But this solution has bad performance compared to {include} because of what I did say under 1. |
|
Back to top |
|
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Sun Aug 23, 2015 3:29 pm Post subject: |
|
|
AnrDaemon wrote: | I don't see, why would you want to do that programmatically.
Please provide a use case. |
The use case is quite simple: In my CMS, the editor can select from a list of snippets and add them to the site as he wants and change their order.
full_site.tpl
Code: |
{include file="head.tpl"}
{dynamic_section}
{include file="foot.tpl"}
|
There are some snippets available for the editor to include into the {dynamic_section}. e.a.
world_clock.tpl
newest_blog_entries.tpl
financial_status.tpl
user_menu.tpl
Using {include} is what the template designer would normally do. But the editor is not able to change the template. The order of these snippets comes from the database.
Code: |
$query = 'SELECT snippet_file_name FROM snippets WHERE template=:current_template ORDER BY order';
$dynamicContent='';
while(($row=$pdo->fetchAll($query))) {
$dynamicContent .= $smarty->fetch($row['snippet_file_name']);
}
return $dynamicContent;
|
This is what I have currently implemented and it works well, until I want to use the {nocache} section inside user_menu.tpl. Because the main template doesn't know anything about its sub templates. And that is the reason I want to do the same as {include} but programatically. Because {include} knows about its template hierarchy.
Dont you think this is a realistic feature request?
There is currently a workarround, by implementing the counterpart of {nocache}, namely {cache}. So I could to the following:
full_site.tpl
Code: |
{include file="head.tpl"}
{dynamic_section nocache}
{include file="foot.tpl"}
|
newest_blog_entries.tpl
Code: |
<h2>Newest blog entries</h2>
{cache ttl=360}
{load_newest_blog_entries}
{/cache}
|
|
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Sun Aug 23, 2015 6:41 pm Post subject: |
|
|
Just another thought.
You could assign an array with the snippet files names and
Code: | {nocache}
{foreach $snippets as $name}
{include file=$name}
{/foreach}
{/nocache} |
you could extend the snippets array to contain not just the name but also individual caching parameter if the included snippets shall be cached.
This should have much better performance. |
|
Back to top |
|
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Mon Aug 24, 2015 7:38 am Post subject: |
|
|
U.Tews wrote: | Just another thought.
You could assign an array with the snippet files names and
Code: | {nocache}
{foreach $snippets as $name}
{include file=$name}
{/foreach}
{/nocache} |
you could extend the snippets array to contain not just the name but also individual caching parameter if the included snippets shall be cached.
This should have much better performance. |
Good point. I will give this a try. But It would be nice if the template designer could just write instead of
Code: | {dynamic_section assign="snippets"}
{foreach}{include}{/foreach}
{/dynamic_section}
|
|
|
Back to top |
|
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Mon Aug 24, 2015 11:01 am Post subject: |
|
|
Many thanks to U.Tews. Your tip solved my problem. It's still a little templating issue, but the feature I've implemented works now as expected:
Code: |
{area id="test" assign="area"}
{foreach $area as $snippet}
{include file=$snippet.src}
{/foreach}
{/area}
|
And the snippet: current_time.tpl
Code: |
<h2>Current time is</h2>
{$smarty.now|date_format:'%c' nocache}
|
can has {nocache} code as well. This is afaik the best solution currently possible with smarty. |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Mon Aug 24, 2015 5:03 pm Post subject: |
|
|
have you ever thought of template functions?
See http://www.smarty.net/docs/en/language.function.function.tpl
They are good to call smaller snippets of template code. Example
Code: |
{function name='d_section'}
{foreach $snippets as $name}
{include file=$name}
{/foreach}
{/function}
|
Perhaps you can place it in an location the designer does not touch?
You could create a library of template functions in a subtemplate and just include it at the start of main template.
Normally you would call it like
But now here is my secret wrapper plugin ... lol
Code: | function smarty_function_dynamic_section ($tpl, $params) {
$tpl->callTemplateFunction ('d_section', $tpl, array(), $true);
}
|
Now you can call just {dynamic_section}.
Note that the template function has a different name to avoid ambiguities. |
|
Back to top |
|
|