Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Fetch sub template and keep the {nocache} section program.

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General
View previous topic :: View next topic  
Author Message
DerRebell
Smarty Rookie


Joined: 10 Jul 2012
Posts: 15
Location: Dresden/Germany

PostPosted: Fri Aug 21, 2015 7:15 am    Post subject: Fetch sub template and keep the {nocache} section program. Reply with quote

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
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Fri Aug 21, 2015 4:13 pm    Post subject: Reply with quote

http://www.smarty.net/docs/en/language.function.include.tpl
http://www.smarty.net/docs/en/language.function.extends.tpl

I don't see, why would you want to do that programmatically.
Please provide a use case.
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Sat Aug 22, 2015 7:53 pm    Post subject: Reply with quote

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
View user's profile Send private message
DerRebell
Smarty Rookie


Joined: 10 Jul 2012
Posts: 15
Location: Dresden/Germany

PostPosted: Sun Aug 23, 2015 3:29 pm    Post subject: Reply with quote

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
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Sun Aug 23, 2015 6:41 pm    Post subject: Reply with quote

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
View user's profile Send private message
DerRebell
Smarty Rookie


Joined: 10 Jul 2012
Posts: 15
Location: Dresden/Germany

PostPosted: Mon Aug 24, 2015 7:38 am    Post subject: Reply with quote

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
Code:
{dynamic_section}
instead of
Code:
{dynamic_section assign="snippets"}
{foreach}{include}{/foreach}
{/dynamic_section}
Back to top
View user's profile Send private message
DerRebell
Smarty Rookie


Joined: 10 Jul 2012
Posts: 15
Location: Dresden/Germany

PostPosted: Mon Aug 24, 2015 11:01 am    Post subject: Reply with quote

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
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Mon Aug 24, 2015 5:03 pm    Post subject: Reply with quote

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
Code:
{call 'd_section'}


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
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP