Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.

Fetch sub templates like include (without output filters)

 
Post new topic   Reply to topic    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: Wed Sep 14, 2016 8:04 pm    Post subject: Fetch sub templates like include (without output filters) Reply with quote

Since Smarty > 3.1.17, there were many changes in template caching, compiling, rendering sub templates via fetch () and running output filters.

And since the method fetch () doesn't support the $no_output_filters flag anymore, the behaviour of my application has changed.

I used it to fetch templates as kind of includes in the context of the parent template and prevent calling all output filters on this sub template.
Pseudo-Code
Code:

public function fetchSubTemplate ($template) {
    return parent::fetch ($template, $parent=$this, $no_output_filters=true);
}


But now, all my registered output filters are called for every fetch (). This is currently a performance bottleneck and breaks my application under some circumstances.

I need to render templates as sub templates of the context of a parent template but skipping the output filters programatically. I can't use {include file="sub template.tpl"} in this situation because I'm not in the context of a template being rendered.

Is it possible to simulate this by calling?
Code:

fetch ('string:{include file="sub template.tpl"}');


Or is there any other possibility to reach this?
Back to top
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1646

PostPosted: Wed Sep 14, 2016 8:36 pm    Post subject: Reply with quote

Are you sure your templates architecture is sane? O.o
Back to top
View user's profile Send private message
DerRebell
Smarty Rookie


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

PostPosted: Thu Sep 15, 2016 4:53 am    Post subject: Reply with quote

AnrDaemon wrote:
Are you sure your templates architecture is sane? O.o

It's highly professional.
Back to top
View user's profile Send private message
DerRebell
Smarty Rookie


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

PostPosted: Thu Sep 15, 2016 6:31 am    Post subject: Reply with quote

It seems i fixed that by overriding the default template class.

Code:

<?php
class TemplateRenderer extends \Smarty {
   public function __construct() {
      $this->template_class = SmartyInternalTemplate::class;
   }
   public function fetchSubTemplate($templateCode) {
      return parent::fetch($templateCode, null, null, $this);
   }
}
/**
 * A custom internal smarty template that prevents running output filters on sub templates
 */
class SmartyInternalTemplate extends \Smarty_Internal_Template {
   private $_noOutputFilters = false;
   public function __construct($template_resource, \Smarty $smarty, $_parent, $_cache_id, $_compile_id, $_caching, $_cache_lifetime) {
      parent::__construct($template_resource, $smarty, $_parent, $_cache_id, $_compile_id, $_caching, $_cache_lifetime);
      $this->_noOutputFilters = ($_parent!==null);
   }
   public function render($no_output_filter = true, $display = null) {
      return parent::render($no_output_filter||$this->_noOutputFilters, $display);
   }
}
Back to top
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1646

PostPosted: Thu Sep 15, 2016 12:39 pm    Post subject: Reply with quote

DerRebell wrote:
AnrDaemon wrote:
Are you sure your templates architecture is sane? O.o

It's highly professional.

May be I'm not so much a professionalů I can't imagine the circumstances, under which I'd be running an output filter NOT on a WHOLE page.
Back to top
View user's profile Send private message
DerRebell
Smarty Rookie


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

PostPosted: Thu Sep 15, 2016 2:43 pm    Post subject: Reply with quote

AnrDaemon wrote:
DerRebell wrote:
AnrDaemon wrote:
Are you sure your templates architecture is sane? O.o

It's highly professional.

May be I'm not so much a professionalů I can't imagine the circumstances, under which I'd be running an output filter NOT on a WHOLE page.


It's quit simple. Imagine you want to collect template code at position X and output at on position Y. You can't capture template code and output it before the {capture} started.

Does this work?
Code:

<head>
{$smarty.capture.banner}
</head>
<body>
{capture "banner"} {* short-hand *}
  {include file="get_banner.tpl"}
{/capture}
</body>


Therefor I'm using:
Code:

<head>
{output_capture name="banner"}
</head>
<body>
{do_capture name="banner"} {* short-hand *}
  {include file="get_banner.tpl"}
{/do_capture}
</body>


This works well using output filters.

Edit: I'm sorry that I misunderstood you. Here is the right explanation:
If you want to render multiple templates programatically like:
Code:

smarty_function_render_something($params, $template) {
   $smarty = $template->smarty;
   $code = '';
   $code .= $smarty->fetch('snippet1.tpl');
   $code .= $smarty->fetch('snippet2.tpl');
   $code .= $smarty->fetch('snippet3.tpl');
   $code .= $smarty->fetch('snippet4.tpl');
   return $code;
}


In this case, every fetch() calls the output filters, but I only want to run these after the template which contains {render_something} has been rendered.
In a Smarty-only environment, this is not a real case. But I'm migrating the render engine of an legacy system to Smarty. And this doesn't support native smarty rendering under some circumstances.

Smarty ~ 3.1.17, the fetch() method had an option to skip running the output filters. This was for compat reasons.
Back to top
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1646

PostPosted: Thu Sep 15, 2016 4:26 pm    Post subject: Reply with quote

IMO, capture is not a very good idea.
It indicates a problem with your business logic, or inheritance model, to me.
And syntactic sugar in general is a very bad and confusing practice.
Back to top
View user's profile Send private message
U.Tews
Administrator


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

PostPosted: Thu Sep 15, 2016 9:19 pm    Post subject: Reply with quote

Code:
smarty_function_render_something($params, $template) {
   $smarty = clone $template->smarty;
   unset( $smarty->registered_filters['output']);
   $code = '';
   $code .= $smarty->fetch('snippet1.tpl');
   $code .= $smarty->fetch('snippet2.tpl');
   $code .= $smarty->fetch('snippet3.tpl');
   $code .= $smarty->fetch('snippet4.tpl');
   return $code;
}
Back to top
View user's profile Send private message
DerRebell
Smarty Rookie


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

PostPosted: Thu Sep 15, 2016 9:42 pm    Post subject: Reply with quote

U.Tews wrote:
Code:
smarty_function_render_something($params, $template) {
   $smarty = clone $template->smarty;
   unset( $smarty->registered_filters['output']);
   $code = '';
   $code .= $smarty->fetch('snippet1.tpl');
   $code .= $smarty->fetch('snippet2.tpl');
   $code .= $smarty->fetch('snippet3.tpl');
   $code .= $smarty->fetch('snippet4.tpl');
   return $code;
}


It's needs to be the same context, not a clone. Anyway I found the solution already as described on top.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    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