|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
bluejester Smarty Regular
Joined: 26 Apr 2012 Posts: 55
|
Posted: Thu Apr 26, 2012 9:49 am Post subject: Pbs with the extends function |
|
|
Hi !
I just found a bug within Smarty's template inheritance.
For several reasons, I have to put the parent template's filename into an assigned variable, that I use into the {extends} function.
The {extends} function works well with {extends $ParentTemplate}, the only thing I can't explain is that it only works once, and doesn't work again when the $ParentTemplate value is changed.
How to reproduce it ? Let's create 4 files. The main PHP file, a child template, and 2 different templates to extend.
PHP file :
Code: | <?
error_reporting(E_ALL ^ E_WARNING ^ E_NOTICE);
# Constant definitions for PHP Files
define('MAIN_PATH', getcwd());
define('INC_PATH', MAIN_PATH . '/inc');
define('SMARTY_CLASS_PATH', INC_PATH . '/Smarty/libs');
define('TEMPLATES_PATH', MAIN_PATH . '/tpl');
# Main inclusions
require_once(SMARTY_CLASS_PATH . '/Smarty.class.php');
# Smarty Configuration
$Smarty = new Smarty();
$Smarty->setTemplateDir(TEMPLATES_PATH);
$Smarty->setCaching(Smarty::CACHING_OFF);
# Smarty rendering
$Smarty->display('Child.tpl');
|
Note that I turned off the Smarty cache, of course.
Parent1.tpl :
Code: | I am Parent1.tpl
{block 'MainContent'}
{/block}
|
Parent2.tpl :
Code: | I am Parent2.tpl
{block 'MainContent'}
{/block}
|
And Child.tpl
Code: | {extends 'Parent1.tpl'}
{block 'MainContent'}
<br/> I am Child.tpl
{/block}
|
OK, now, let's see what's the display is :
Quote: | I am Parent1.tpl
I am Child.tpl
|
Perfect. Let's change the static {extends 'Parent1.tpl'} to {extends 'Parent2.tpl'}. Hit F5, Smarty now displays :
Quote: | I am Parent2.tpl
I am Child.tpl |
Great! Smarty now extends correctly Parent2.tpl.
Now, assign the parent template name in a variable, just before the display() method.
Code: | # Smarty rendering
$Smarty->assign('ParentTemplate', 'Parent1.tpl');
$Smarty->display('Child.tpl'); |
Change the first line of your Child.tpl :
Code: | {extends $ParentTemplate}
{block 'MainContent'}
<br/> I am Child.tpl
{/block} |
Hit F5 in your browser, now it looks like this :
Quote: | I am Parent1.tpl
I am Child.tpl |
That worked perfectly.
Now, change the value of $ParentTemplate :
Code: | # Smarty rendering
$Smarty->assign('ParentTemplate', 'Parent2.tpl');
$Smarty->display('Child.tpl'); |
Hit F5 :
Quote: | I am Parent1.tpl
I am Child.tpl |
Wtf ? Hit F5 again :
Quote: | I am Parent1.tpl
I am Child.tpl |
The rendering is blocked on Parent1.tpl, though Parent2.tpl should be rendered.
Waiting (long) minutes sometimes fixes the problem, but this should not happen, since my Smarty Cache has been turned off.
In my PHP files, I have to condition which master template to use, that's why I use a variable. But... I just can't go further until this is fixed
Thanks a lot !
Ben
PS : I tested it on Smarty v3.0.6 and 3.1.8 |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Apr 26, 2012 2:39 pm Post subject: |
|
|
Note that template inheritance is a compile time process.
If you use variable filenames the filename must included in a compile_id. See http://www.smarty.net/docs/en/language.function.extends.tpl
Code: | # Smarty rendering
$Smarty->assign('ParentTemplate', 'Parent1.tpl');
$Smarty->compile_id = 'Parent1.tpl';
$Smarty->display('Child.tpl'); |
Or instead using the {extends} tag you could use the extends resource to define parent/child relations.
Code: | $smarty->display('extends:Parent1.tpl|Child.tpl'); |
|
|
Back to top |
|
bluejester Smarty Regular
Joined: 26 Apr 2012 Posts: 55
|
Posted: Thu Apr 26, 2012 3:57 pm Post subject: |
|
|
U.Tews,
You just saved my life.
Viele Danke !! |
|
Back to top |
|
bluejester Smarty Regular
Joined: 26 Apr 2012 Posts: 55
|
Posted: Fri Apr 27, 2012 9:27 am Post subject: |
|
|
Hello U.Tews,
I'm sorry to be back.
Yesterday night, it worked fine.
Then I did just a little mod on my child template (just swapping two <tr>/<td>, with static content).
Smarty then rendered a blank page, without any error displayed.
This morning, I couldn't fix it. So I turned my smarty and my php code up and down for one hour, rolling back to a static {extends}, disabling all cache and compiled files with $smarty->clearCompiledTemplate(); and $smarty->clearAllCache();... nothing succeed.
So, I took an old version of my scripts and coded back "from scratch" everything, step by step, and that finally works fine : child template extending different master templates with a variable.
However, 2 minutes ago, I had to modify something in my child template... and the blank page is back.
I'm losing my hair !
What have I done wrong ?
Thanks in advance,
Ben |
|
Back to top |
|
bluejester Smarty Regular
Joined: 26 Apr 2012 Posts: 55
|
Posted: Fri Apr 27, 2012 9:54 am Post subject: |
|
|
If it can help, here's an overview of my code:
PHP File :
Code: | <?
# Creating a $Params array of the user request
[...]
# Smarty & Cache settings
$smarty -> setTemplateDir(SERVER_ROOT_PATH . 'Templates');
$smarty -> setCaching(Smarty::CACHING_LIFETIME_CURRENT);
$smarty -> setCacheLifetime(60 * 60 * 24 * 365);
$CacheId = (string) md5(json_encode($Params));
$CacheExists = (bool) $smarty->isCached('DashBoard/DataTable.tpl', $CacheId, 'Index.tpl');
if (!$CacheExists) :
# If no user ever did this request, we fetch some heavy data, for 1-2 minutes...
[...]
endif;
# Now, we want to render the result in different ways, and cache them
$smarty -> assign('ParentTemplate', 'DashBoard/XLSExport.tpl'); // XLS template
$smarty -> compile_id = 'XLSExport.tpl';
$XLS = $smarty->fetch('DashBoard/DataTable.tpl', $CacheId, $smarty->compile_id);
$smarty -> assign('ParentTemplate', 'DashBoard/PDFExport.tpl'); // PDF template
$smarty -> compile_id = 'PDFExport.tpl';
$PDF = $smarty->fetch('DashBoard/DataTable.tpl', $CacheId, $smarty->compile_id);
$smarty -> assign('ParentTemplate', 'DashBoard/Index.tpl'); // HTML template
$smarty -> compile_id = 'Index.tpl';
$HTML = $smarty->fetch('DashBoard/DataTable.tpl', $CacheId, $smarty->compile_id);
# Now, wether the user wants to display the XLS, the PDF or the HTML :
if ($_GET['FileFormat'] == 'XLS') :
header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=DashBoard - " . date("Y-m-d H-i-s") . ".xls");
echo $XLS;
elseif ($_GET['FileFormat'] == 'PDF') :
require_once('html2pdf_PHP5_v4.03/html2pdf.class.php');
header('Content-Type: application/pdf; charset=ISO-8859-15');
$FileName = 'PDF_DashBoard - ' . date("Y-m-d H-i-s") . '.pdf';
$HTML2PDF = new HTML2PDF('L','A4','fr', false, 'ISO-8859-15', Array(3, 3, 3, 3));
$HTML2PDF -> WriteHTML($PDF);
$HTML2PDF -> Output($FileName, 'I');
else :
echo $HTML;
endif; |
Child template DashBoard/DataTable.tpl :
Code: | {extends file=$ParentTemplate}
{block 'DashBoard'}
<table>
<thead>
<tr>
<td colspan="6">Some data...</td>
</tr>
</thead>
<tbody>
<tr>
<td>Some data...</td>
<td>Some data...</td>
<td>Some data...</td>
<td>Some data...</td>
<td>Some data...</td>
<td>Some data...</td>
</tr>
</tbody>
</table>
{/block} |
Parent Template Index.tpl (HTML view)
Code: | {extends 'MasterTemplate.tpl'}
{block 'Title'}
<title>Dashboard</title>
{/block}
{block 'CSSFiles' append}
<link rel="stylesheet" type="text/css" href="/css/Dashboard.css" />
{/block}
{block 'Content'}
<h1>Dashboard</h1>
<form>
<!-- Some input fields -->
</form>
{block 'DashBoard'}{/block}
<!-- Footer -->
{/block} |
Other Parent Template PDFExport.tpl (PDF view)
Code: | <page backtop="15mm" backbottom="7mm" backleft="10mm" backright="10mm" style="font-family: Arial" orientation="landscape">
<page_header>
<img src="/img/Logo.png" />
</page_header>
{block 'DashBoard'}{/block}
</page> |
Other Parent Template XLSExport.tpl for the XLS view (just for rendering the Dashboard.tpl template with a Content-type: application/vnd.ms-excel)
Code: | {block 'DashBoard'}{/block} |
Thanks,
Ben |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Fri Apr 27, 2012 9:55 am Post subject: |
|
|
Did you use the {extends} tag and compile_id or the extends: resource?
I think something must be wrong with your template code, but no idea why you don't see an error message.... |
|
Back to top |
|
bluejester Smarty Regular
Joined: 26 Apr 2012 Posts: 55
|
Posted: Fri Apr 27, 2012 10:27 am Post subject: |
|
|
No, I'm using the {extends $ParentTemplate} in the TPL code, $ParentTemplate is a string assigned in the PHP code, depending of the view the user wanted.
Now that I use a cache Id and a compile Id into my isCached() and my fetch() methods, erverything works fine, until I modify something in my TPL files.
That's disturbing since I often have to modify things in my TPL files...
No error message, indeed... |
|
Back to top |
|
|
|
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
|
|