View previous topic :: View next topic |
Author |
Message |
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Wed Sep 14, 2016 8:04 pm Post subject: Fetch sub templates like include (without output filters) |
|
|
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 |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Wed Sep 14, 2016 8:36 pm Post subject: |
|
|
Are you sure your templates architecture is sane? O.o |
|
Back to top |
|
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Thu Sep 15, 2016 4:53 am Post subject: |
|
|
AnrDaemon wrote: | Are you sure your templates architecture is sane? O.o |
It's highly professional. |
|
Back to top |
|
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Thu Sep 15, 2016 6:31 am Post subject: |
|
|
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 |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Thu Sep 15, 2016 12:39 pm Post subject: |
|
|
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 |
|
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Thu Sep 15, 2016 2:43 pm Post subject: |
|
|
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 |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Thu Sep 15, 2016 4:26 pm Post subject: |
|
|
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 |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Sep 15, 2016 9:19 pm Post subject: |
|
|
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 |
|
DerRebell Smarty Rookie
Joined: 10 Jul 2012 Posts: 15 Location: Dresden/Germany
|
Posted: Thu Sep 15, 2016 9:42 pm Post subject: |
|
|
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 |
|
|