| View previous topic :: View next topic |
| Author |
Message |
XadmozX Smarty n00b
Joined: 14 Sep 2004 Posts: 4
|
Posted: Thu Apr 14, 2005 10:37 am Post subject: Merging templates by smarty compiler |
|
|
Is there any way to have the layout splited into many templates (for usibility reasons) and have the compiled version of this layout in just one (for performance reasons - includes are time consuming)? I mean a simple merge funcionality on compiler side.
Or maybe there is another solution that enables:
- multi templates
- no includes |
|
| Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 5537 Location: Lincoln Nebraska, USA
|
Posted: Thu Apr 14, 2005 1:15 pm Post subject: |
|
|
The compiler doesn't work that way, it compiles each physical template to its own physical file so that any template can be included from any other template. However, with caching enabled you get one cache file per display() or fetch() call, avoiding the compiled file includes altogether. _________________ Monte
http://www.phpinsider.com/
http://mohrt.blogspot.com/ |
|
| Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5608 Location: Toronto, Canada
|
Posted: Thu Apr 14, 2005 2:30 pm Post subject: |
|
|
| I think an inlining function would be nice. It occurs to me that another template engine does this (Flexy?) but I can't recall. |
|
| Back to top |
|
messju Administrator

Joined: 16 Apr 2003 Posts: 3327 Location: Oldenburg, Germany
|
Posted: Thu Apr 14, 2005 2:35 pm Post subject: |
|
|
some time ago i wrote a prefilter that does this. i never used it in a production environment, so use it on your own risk
prefilter.inline.php
[php:1:6a112e197a]<?php
/**
* Smarty inline prefilter plugin
*
* File: prefilter.inline.php<br>
* Type: prefilter<br>
* Name: inline<br>
* Date: Dec 5, 2003<br>
* Purpose: resolve inlcuded templates at compile-time and include them
* Use: <code>$smarty->load_filter('pre','script_name');</code>
* from application.
* @author Messju Mohr <messju@lammfellpuschen.de>
* @version 0.3
* @param string (the template's sourcecode)
* @param Smarty_Compiler (the compiler)
*/
/*
* - tags like {inline file="foo.php"} are resolved
* - {inline file="foo.tpl" assign="foo"} assigns the contents
* instead of displaying them
* - {inline file="foo.tpl" var1=foo var2=bar} defines custom template
* variables to be used in the included tpl.
*/
function smarty_prefilter_inline($source, &$compiler) {
$ld = $compiler->left_delimiter;
$rd = $compiler->right_delimiter;
if (empty($compiler->_inline_depth)) {
$compiler->_inline_depth = 0;
/* make compiler visbile to inline_callback-function */
$GLOBALS['__compiler'] =& $compiler;
}
$compiler->_inline_depth++;
$source = preg_replace_callback('!' . preg_quote($ld, '!') . 'inline(.*)'
. preg_quote($rd, '!') . '!Us'
, 'inline_callback', $source);
if (--$compiler->_inline_depth==0) {
/* clean up */
unset($GLOBALS['__compiler']);
}
return $source;
}
function inline_callback($match) {
global $__compiler;
$ld = $__compiler->left_delimiter;
$rd = $__compiler->right_delimiter;
$source_content = '';
/* get attributes to {inline...} */
$_attrs = $__compiler->_parse_attrs($match[1]);
/* "file" */
if (!isset($_attrs['file'])) {
$this->syntax_error('[inline] missing file-parameter');
return false;
}
$resource_name = $__compiler->_dequote($_attrs['file']);
unset($_attrs['file']);
/* "assign" */
if (isset($_attrs['assign'])) {
$assign = $_attrs['assign'];
unset($_attrs['assign']);
} else {
$assign = null;
}
/* handle all other attributes as custom-vars */
if (!empty($_attrs)) {
$source_content .= $ld.'php'.$rd;
$source_content .= '$this->assign(array(';
$_sep = '';
foreach ($_attrs as $_name=>$_value) {
$source_content .= "$_sep'$_name'=>$_value";
$_sep = ',';
}
$source_content .= ')); '.$ld.'/php'.$rd;
}
/* read tpl-file */
$params = array('resource_name'=>$resource_name);
if ($__compiler->_fetch_resource_info($params)) {
/* recursion */
$source_content .= smarty_prefilter_inline($params['source_content'], $__compiler);
/* handle assign */
if (isset($assign)) {
$source_content = $ld.'php'.$rd . 'ob_start();' . $ld.'/php'.$rd
. $source_content
. $ld.'php'.$rd . '$this->assign(' . $assign . ', ob_get_contents()); ob_end_clean();' . $ld.'/php'.$rd;
}
}
/* return inline-replacement of tpl-file */
return $source_content;
}
?>
[/php:1:6a112e197a] |
|
| Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5608 Location: Toronto, Canada
|
Posted: Thu Apr 14, 2005 3:02 pm Post subject: |
|
|
| @messju: very interesting -- I'll have to give it a whirl. thanks! |
|
| Back to top |
|
pt2002 Smarty Regular
Joined: 05 May 2003 Posts: 89 Location: Porto, Portugal
|
Posted: Sun Dec 18, 2005 11:58 pm Post subject: |
|
|
Hi
This piece of code is very nice, thanks.
There is only one problem that i found and would like to know if it possible to fix it.
I have one main.tpl where i include other templates.
{inline file="header.tpl"}
....
....
{inline file=$content}
...
...
{inline file="footer.tpl"}
The tpl var $content is assigned in php
i.e. $tpl->assign("content", "news.tpl") but can be any other template.
With {include file=$content} it's everything ok but with {inline file=$content}, the template is not being included.
Looking at the code, line 92
| Code: |
$params = array('resource_name'=>$resource_name);
|
and echoing $resource_name I see the name of the templates and
($this->_tpl_vars['content']) for the template name assigned in php but it isn't beeing fetched in line 93
| Code: |
if ($__compiler->_fetch_resource_info($params)) {
|
Is there any workaround for this?
Best regards |
|
| Back to top |
|
messju Administrator

Joined: 16 Apr 2003 Posts: 3327 Location: Oldenburg, Germany
|
Posted: Mon Dec 19, 2005 12:03 am Post subject: |
|
|
| pt2002 wrote: | | Is there any workaround for this? |
no, there isn't. "$this->_tpl_vars['content']" should be evaluated at display time, but the inlining is done at compile time (thus way before display time).
{inline} is static, {include} is dynamic. it seems you want something dynamic if your controller assigns the name of the template.
regards
messju |
|
| Back to top |
|
pt2002 Smarty Regular
Joined: 05 May 2003 Posts: 89 Location: Porto, Portugal
|
Posted: Mon Dec 19, 2005 12:12 am Post subject: |
|
|
Hi
thanks for answering so quickly.
No problem. It reduced seven tpl files to two. Nice work
best regards |
|
| Back to top |
|
mucill Smarty n00b
Joined: 12 Nov 2006 Posts: 3
|
Posted: Mon Nov 13, 2006 12:49 pm Post subject: try this |
|
|
i do not know that my methode will answer this question...but you can try it
i've tried to split many template in my html file and merge them in one mian template
this is the html code
--------------------------------------------------------
[index.html]
<html>
<body>
{$leftcontent}
{$content}
{$rightcontent}
</body>
</html>
[leftcontent.html]
<div>
Put your left content here. You can put such a {$menu} here
</div>
[rightcontent.html]
<div>
Put your right content here. You can put such a {$maillogin} here
</div>
[content.html]
<div>
Put your content here. You can put such a {$news} syntax here
</div>
--------------------------------------------------------
put all html files inside your template folder
this is the php code
----------------------------------------------------------------------
[index.php]
<?
# define template contanta
define ('SMARTY_DIR', './smarty/');
include (SMARTY_DIR . "Smarty.class.php");
# declare template constructor
$smarty = new Smarty;
$smarty->assign(array(
"menu" => "Menu1<br>Menu2<br>Menu3",
"maillogin" => "Put with your own mail form","news" => "News List will show here"));
$smarty->assign(array(
"leftcontent" => $smarty->fetch("leftcontent.html"),
"content" => $smarty->fetch("content.html"),
"rightcontent" => $smarty->fetch("rightcontent.html")
));
$smarty->display("index.html");
?>
---------------------------------------------------------
it's works for me ......  |
|
| Back to top |
|
selaz Smarty Rookie
Joined: 04 Feb 2007 Posts: 14
|
|
| Back to top |
|
Celeb Administrator
Joined: 17 Apr 2007 Posts: 1025 Location: Vienna
|
Posted: Mon Feb 25, 2008 7:57 am Post subject: |
|
|
| selaz wrote: | | BTW, why this functionality isn't included in Smarty by default. I use lets say 30 different tiny includes per page and inline prefilter can really help you increase performance. |
So can enabling caching and using {insert} (which will not be cached) for dynamic output.
What messju's prefilter does is replace
| Code: | | {inline file='inline.tpl' value='assigned value'} |
by something similar to
| Code: | {php}$this->assign('value','assigned value');{/php}
[contents of inline.tpl] |
I guess you could change the prefilter to add an additional
| Code: | | {php}$this->clear_assign('value');{/php} |
But note, that if $value has been assigned before the {inline} call it's gone for good. You could further change the filter to act like {include} but I'd rather just use {include} then. _________________ Darn computers always do what I tell them to instead of what I want them to do. |
|
| Back to top |
|
selaz Smarty Rookie
Joined: 04 Feb 2007 Posts: 14
|
Posted: Tue Feb 26, 2008 9:35 am Post subject: |
|
|
Thanks for your reply.
| Celeb wrote: |
So can enabling caching and using {insert} (which will not be cached) for dynamic output. |
The thing is I always need fresh output data, every page displays some db data. My idea was to save up some (open/read/close) file accesses to multiple compiled files and gain some performance. The only drawback I see is the fact the primary file won't be recompiled after some subtemplate is changed.
Still, I need a trick to make inline templates act like includes - variables passed !only! to included template and its subtemplates.
Thanks
Last edited by selaz on Wed May 05, 2010 10:39 pm; edited 1 time in total |
|
| Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 2316 Location: Hamburg / Germany
|
Posted: Tue Feb 26, 2008 5:56 pm Post subject: |
|
|
The problem is that {inline...} is merging all templates together and the result is then interpreted by Smarty as one big template. Therefor the scope of all Smarty variables like $value is global. The only chance I see is that you use different variable names for the parmeter of each subtemplate.
And yes you are right modifications of the subtemplates will not be automatically detected. |
|
| Back to top |
|
selaz Smarty Rookie
Joined: 04 Feb 2007 Posts: 14
|
Posted: Tue Feb 26, 2008 6:24 pm Post subject: |
|
|
I thing like:
| Code: |
<?php $_tmp_tpl_vars=$this->_tpl_vars;
$this->assign(array('a'=>'123'));?>
This is a subtemplete value: a=<?php echo $this->_tpl_vars['a']; ?>
<?php $this->_tpl_vars=$_tmp_tpl_vars;?>
|
for every inline template would do the trick, but I'm not sure if there's a more elegant way to do it.
Last edited by selaz on Wed May 05, 2010 10:39 pm; edited 1 time in total |
|
| Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 2316 Location: Hamburg / Germany
|
Posted: Tue Feb 26, 2008 6:34 pm Post subject: |
|
|
Well but this will work only for one level of {inline... } tags. But I think the prefilter does support anyway just one level.
You could also just save and restore just the parameter variable and shuffel not too much of data arround. |
|
| Back to top |
|
|