View previous topic :: View next topic |
Author |
Message |
c0dex Smarty n00b
Joined: 21 Jan 2016 Posts: 3
|
Posted: Fri Jan 22, 2016 11:52 am Post subject: Extending layout and function visibility scope |
|
|
Hello.
I have a stupid question ;(. I've updated from 3.1.21 to 3.1.29 and web site in several places now gets broken with: Unable to find template function 'some_function'.
Our front-end developer used the approach as pseudo-code:
layout.tpl
Code: | {include file='function.tpl'} |
in function.tpl i have
Code: | {function name='test_func' caller=$caller}
function exists in {$caller}
{/function} |
caller1.tpl
Code: | {extends 'layout.tpl'}
{call test_func caller='caller1'}
|
caller2.tpl
Code: | {include file='caller1.tpl'}
{call test_func caller='caller2'}
|
caller3.tpl
Code: | {include file='caller2.tpl'}
{call test_func caller='caller3'}
|
When i do fetch('caller1.tpl') everithing is ok. And when fetch('caller2.tpl') or fetch('caller3.tpl') i get <Unable to find template function 'test_func'>
If i replace {extends 'layout.tpl'} by {include file='function.tpl'} in my caller1.tpl - all works as expected.
What should i do? The web site using this approach is a very complicated one. |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Sat Jan 23, 2016 4:28 am Post subject: |
|
|
That does look complicated, not sure what is trying to be accomplished. Can caller1.tpl, caller2.tpl, caller3.tpl all do the same thing? (extend layout.tpl then call the function with the appropriate args) |
|
Back to top |
|
c0dex Smarty n00b
Joined: 21 Jan 2016 Posts: 3
|
Posted: Tue Jan 26, 2016 9:05 am Post subject: |
|
|
mohrt wrote: | That does look complicated, not sure what is trying to be accomplished. Can caller1.tpl, caller2.tpl, caller3.tpl all do the same thing? (extend layout.tpl then call the function with the appropriate args) |
No. I tried to show the template inheritance. If it could be called so. I need to call (display) only the caller3 (final-template).
I need to call only caller3,
Code: |
caller3.tpl > includes caller2.tpl
caller2.tpl > includes caller1.tpl
caller1.tpl > extends layout.tpl
layout.tpl > includes function.tpl
|
And when i tried to call the function - is can not be found. The problem with {extends} in caller1.
Sorry, probably my explanation is rather poor. English is not my native language =( |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Tue Jan 26, 2016 12:28 pm Post subject: |
|
|
You should rewrite your inheritance to use {extend} over {include}.
Use {include} only for blocks not directly related to page purpose.
Instead of
article includes page
-> page includes layout
-> layout includes all sort of headers and stuff common for entire theme
make it
article extends page
-> page extends layout
-> layout includes all sort of headers and stuff common for entire theme
And a second question, can't you turn your template function into a Smarty tag?
That'll save you A.LOT of hassle. |
|
Back to top |
|
c0dex Smarty n00b
Joined: 21 Jan 2016 Posts: 3
|
Posted: Tue Jan 26, 2016 1:07 pm Post subject: |
|
|
The rewrite is not possible =\
The system has over 500 template files.
And the structure is normal and worked prior to 3.1.21+ update.
Fixed the issue with some changes in templates (moved tpl-defined function from one inner template to another). |
|
Back to top |
|
paulgolovin Smarty Rookie
Joined: 27 Jan 2016 Posts: 5
|
Posted: Wed Jan 27, 2016 3:19 pm Post subject: |
|
|
Hi, guys, i have the same problem, i'll try to explain easier.
It's very important, please, help.
I have a base template base.tpl, it has html structure:
Code: |
<!doctype html>
<html>
<head>...</head>
<body>
<main>
{block name='main'}
...
{/block}
</main>
</body>
</html>
|
and i have index.tpl
Code: |
{extends file='base.tpl'}
{block name='main'}
{function do_smth}
bla-bla-bla
{/function}
{call do_smth}
{/block}
|
I open index file of my site and have error:
Error message: Unable to find template function 'do_smth'
And I've updated from 3.1.21 to 3.1.29 too. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Wed Jan 27, 2016 5:43 pm Post subject: |
|
|
In templates, which are extending other templates, everything that isn't {extends} or {block} is ignored now.
There's very little reason to use template functions. Write a proper Smarty function, and you'll have a much easier life. |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Wed Jan 27, 2016 10:11 pm Post subject: |
|
|
Before 3.1.28 resolving the {block} replacements between parent and child templates was a compile time process which had many restrictions and short comings.
Since 3.1.28 this is a run time process.
Please read the NEW_FEATURES.txt and INHERITANCE_RELEASE_NOTES.txt files.
c0dex
In your example caller1.tpl is an inheritance child template root.
Before 3.1.28 any code outside {block}{/block} was simply ignored. So
Code: | {call test_func caller='caller1'} |
Never had any function
Since 3.1.28 code outside {block}{/block} tags in child templates is executed, but it's output is ignored. This has benefits like assigning vars in child templates or making {block}{/block} sections conditional with surrounding {if} tags etc
Now test_func gets called in caller1.tpl but it is not know because function tpl is not known at that time.
It's a design flaw of your template structure.
paulgolovin
I have tested your example under 3.1.29 and it does work. |
|
Back to top |
|
paulgolovin Smarty Rookie
Joined: 27 Jan 2016 Posts: 5
|
Posted: Thu Jan 28, 2016 2:39 pm Post subject: |
|
|
U.Tews wrote: | paulgolovin
I have tested your example under 3.1.29 and it does work. |
Yep, sorry, i've tested other example. Just try to add 'inline' to {extends file='base.tpl'} and error will occur. |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Jan 28, 2016 10:07 pm Post subject: |
|
|
See http://www.smarty.net/docs/en/language.function.extends.tpl
The {extends} tag has no inline option.
For versions before 3.1.28 there was no need for it as template inheritance was a compile time process and {block} replacements done at that time resulting already in a single compiled file.
Since 3.1.28 it is a run time process so each template has its own compiled template. So adding this option will make sense. I will look into it.
But you can set $smarty->merge_compiled_includes = true;
This will create a single compiled template file including also all sub-templates included by {include}.
This provides always a very large performance boost when rendering compiled templates, if you use inheritance or not. If caching is enabled this option still affects performance when the cache needs to be refreshed. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Thu Jan 28, 2016 11:04 pm Post subject: |
|
|
Probably {extends} could determine, if it is called with variable arguments, and assume "inline" if not?
At least that's (I imagine) the most common use case for it. |
|
Back to top |
|
|