smarty
smarty copied to clipboard
template handling order with extendsall: vs file: as default resource type
I've prepared exampe which demonstrates the occured problem: https://www.chilan.com/smarty-test-3.tar.xz
You have two possible variants:
- With commented out the following lines:
//$SMARTY->setMergeCompiledIncludes(true);
//$SMARTY->setDefaultResourceType('extendsall');
In this variant header.html and footer.html files are handled with order as I expect - first found file is loaded.
- After uncommenting earlier mentioned lines header.html and footer.html files are handled in reverse order - I mean files from within last template directory are loaded.
Is it possible in this variant to get effect in which I have:
$SMARTY->setMergeCompiledIncludes(true);
$SMARTY->setDefaultResourceType('extendsall');
and header.html and footer.html are handled in the same order as handling of content.html files?
Reference: https://github.com/chilek/lms-plus/issues/291
Sorry for the laate reply. I was longer term ill.
Call the header and footer by explicit specifing the file: resource.
{include file="file:header.html"}
{block name="content"}
classic content
{/block}{include file="file:footer.html"}
@uwetews but this doesn't resolve the problem, because in plugins we use template inheritance also for header.html and footer.html, as we want to modify their contents.
Okay
Do not call $SMARTY->setDefaultResourceType('extendsall');
Use the extendsall: resource only when calling $smarty->display();
$smarty->display('extendsall:content.html');
I think this should be the solution
But this would require a lot of changes - a few hundred files :(
3.1.33:
$SMARTY->setMergeCompiledIncludes(true);
$SMARTY->setDefaultResourceType('extendsall');
Only included templates are loaded with 'extendsall:' prefix, I mean:
{include file="contents.html"}
impacts on compiled template as follows:
'includes' =>
array (
'file:[1]layout.html' => 1,
'extendsall:content.html' => 1,
'file:[1]content.html' => 1,
),
but:
```php
$SMARTY->display('layout.html');
uses only 'file:' resource type (as in above compiled template snippet). Tried to use:
$SMARTY->display('extendsall:layout.html');
and it doesn't fix the situation.
Would be perfect to work with and wihout 'extendsall:' resource type for display() method. @uwetews can you help me anyhow?
What you see is correct. The extendsall resource is a frame which holds all individual file resources for the templates with same name out of different folders. If you do not set the mergeCompiledInclude flag you will get for each template a compiled file and one additional for the extendsall frame resource. So if you have 2 templates with same name you get 3 files. It has not the best performance.
If you merge the includes some performance optimization is in effect. The first template found will create internally the extendsall resource which includes the file resource for the first template. However if no other template with same name will be found it falls back to a simple file resource to get rid of the not needed overhead reducing memory usage and execution time.
In your example you have just one layout.html file. for that reason will in the compiled file just as a simple file resource. The first of the included content.html template files will get extendsall resouce type we cause it must chain the rendering to the other template file with same name.
Its not a bug, but optimization feature.
The clue is that it doesn't find layout.html in other template dir.
I try to change template such way that I put template file with the same name as original but in other template directory (added to template dir collection), but Smarty always takes only original file for template pointed by:
$SMARTY->display('layout.html');
Subtemplates included from layout.html template uses extendsall resource type, but main layout.html not. Event if we prepend this template file name with 'extendsall:' resource type :(
In my problematic scenario we have 2 template files with the same name but located in different template directories - layout.html. Let's assume that 1:layout.html, 2:layout.html mean template files from related template directories configured with:
$SMARTY->AddTemplateDir(
array(
'directory_1',
'directory_2',
)
);
We expect to layout.html file load from directory_1, but it loads from directory_2 :(
addTemplateDir() will append the directories to whatever the template_dir setting was before (default value)? So 'directory_1' is not the first folder searched. use setTemplateDir() to look for sure just in the two folders in the correct order.
What but it should see both templates anyway. Are you sure that the template in directory_1 is readable?
What happens if you setTemplateDir just to 'directory_1'?
Strange does work at my place like a charm
I asked colleague to describe the problem with more details. Will update this issues when get answer from him.
@uwetews in mean time I'd like to appreciate your work more. Would you create paypal link for your regular personal donation? I donate [email protected] monthly with 20$ and the same amount I'd like to transfer for you ;-)
Ok - I've prepared problem isolated test:
index.php file:
$SMARTY = new Smarty;
$SMARTY->setMergeCompiledIncludes(true);
$SMARTY->setDefaultResourceType('extendsall');
$SMARTY->AddTemplateDir(array(
'directory_1',
'directory_2',
));
$SMARTY->display('test.html');
test.html from directory_1:
test_1
test.html from directory_2:
test_2
In web browser we have the output of:
test_2
The extendsall resource is a special form of template inheritance where templates with same name create parent child relation ships. the last template loaded will be the parent template. Like with the extends resource the parent template is the only template which also displays text and executes code outside from block tags. I think that's the reason why you see only the test_2 output
@uwetews so how could I fix the problem?
I need to know how your the template content looks like. And what you want to do. I remember from the older discussions that you used some very special solutions to merge and arrange the content of the templates. give me some examples please. It might be that the extendsall resource working similar like the normal extends resource is not the right solution and a new custom resource would do it. I need more details
I've prepared files for two test case scenarios. Here you have all files: https://www.chilan.com/smarty-test-4.tar.xz
- When you call /smarty-test-4/display.php you get
default content
. - When you call /smarty-test-4/extendsall.php you get
modified content
.
For my perspective it means that extendsall case causes that template file from earlier template directory is taken, and for display case file from later template directory is taken.
My goal to achieve is effect in which I get modified content
output indepdently from usage type.
It that the only way for that to inject content-display.html from templates-modified directory is to use:
{block name="content"}
...
{/block}
? It would mean that I should outfit all templates in blocks and all replacing templates should use these blocks. But I'd like to avoid this and simultaneously use both methods of replacing templates in earlier template directory.
@chilek this issue is 5+ years old. I'm closing this now to clean up. Hopefully you have found a solution. If not, please open a discussion.