smarty icon indicating copy to clipboard operation
smarty copied to clipboard

template handling order with extendsall: vs file: as default resource type

Open chilek opened this issue 7 years ago • 17 comments

I've prepared exampe which demonstrates the occured problem: https://www.chilan.com/smarty-test-3.tar.xz

You have two possible variants:

  1. 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.

  1. 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

chilek avatar Jun 29 '17 12:06 chilek

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 avatar Oct 07 '17 15:10 uwetews

@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.

chilek avatar Oct 09 '17 10:10 chilek

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

uwetews avatar Oct 10 '17 01:10 uwetews

But this would require a lot of changes - a few hundred files :(

chilek avatar Oct 10 '17 11:10 chilek

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?

chilek avatar Oct 02 '18 09:10 chilek

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.

uwetews avatar Oct 02 '18 11:10 uwetews

The clue is that it doesn't find layout.html in other template dir.

chilek avatar Oct 02 '18 11:10 chilek

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 :(

chilek avatar Oct 02 '18 11:10 chilek

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 :(

chilek avatar Oct 02 '18 12:10 chilek

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

uwetews avatar Oct 02 '18 12:10 uwetews

I asked colleague to describe the problem with more details. Will update this issues when get answer from him.

chilek avatar Oct 02 '18 13:10 chilek

@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 ;-)

chilek avatar Oct 02 '18 13:10 chilek

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

chilek avatar Oct 02 '18 13:10 chilek

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 avatar Oct 02 '18 15:10 uwetews

@uwetews so how could I fix the problem?

chilek avatar Oct 02 '18 16:10 chilek

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

uwetews avatar Oct 02 '18 18:10 uwetews

I've prepared files for two test case scenarios. Here you have all files: https://www.chilan.com/smarty-test-4.tar.xz

  1. When you call /smarty-test-4/display.php you get default content.
  2. 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 avatar Oct 02 '18 19:10 chilek

@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.

wisskid avatar Jan 31 '23 09:01 wisskid