Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Function declaration needed
Goto page 1, 2  Next
 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Smarty 3
View previous topic :: View next topic  
Author Message
ldrut
Smarty Rookie


Joined: 22 Dec 2009
Posts: 11

PostPosted: Tue Dec 29, 2009 6:21 pm    Post subject: Function declaration needed Reply with quote

Apologies if I am misreading the situation (first time using the syntax) or if this is addressed in the docs somewhere, but I can't find it.

It appears that functions must be defined before referenced at the parser level. For instance the following generates a parser error on the function call line (parser, not execution error):

{test}

{function name=test}
...some code...
{/function}

Reversing the declaration and call order removes the error.

The problem is that include files are not taken into account. This means functions may not be embedded in include files and function libraries are hard to implement as the following also fails with a parser error (on hte last line of file2).

{* file1.tpl *}
{function name=test}
...some code...
{/function}

{* file2.tpl *}
{include name="file1.tpl"
{test}

Am I seeing this right?

I presume that a pre-scan of the include files for function definitions is problematic. If so, could we get a declaration syntax of some kind to declare an external function definition? Something like

{function name=test /}
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Tue Dec 29, 2009 8:46 pm    Post subject: Reply with quote

Currently the following does work:

{* file1.tpl *}
{function name=test}
...some code...
{/function}

{* file2.tpl *}
{function name=test}{/function}
{include name="file1.tpl"
{test}

The dummy function test gets overloaded when {include} is being executed.
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Tue Dec 29, 2009 9:38 pm    Post subject: Reply with quote

We will implement {call name="funcname" ...} to allow calls to externally declared functions in the next couple of days.
Back to top
View user's profile Send private message
ldrut
Smarty Rookie


Joined: 22 Dec 2009
Posts: 11

PostPosted: Wed Dec 30, 2009 4:18 am    Post subject: Reply with quote

Thanks. Your solution sounds fine. I'll wait for Beta 6, not too much of a problem to code around for now.

BTW, is that ability to redefine a function by overwrite part of the specification or just "the way it works right now"? I can think of a couple of other places where an ability to redefine functions could come in useful. Not so useful I could not do without it though so I just want to know which way to plan.
Back to top
View user's profile Send private message
ldrut
Smarty Rookie


Joined: 22 Dec 2009
Posts: 11

PostPosted: Wed Dec 30, 2009 5:12 am    Post subject: Reply with quote

I know its hardly urgent but while we are here, the documentation example for the {function} tag probably has an error in it. It looks to me like a function that should have two parameters, 'level' and 'data' but 'data' is missing in the declaration ('level' is missing in the call, but I presume you intended that to illustrate default values).

Confused me for a bit as from a quick glance I assumed that the syntax of a call was going to be {funcname data=gar1,arg2,...}
Back to top
View user's profile Send private message
douglassdavis
Smarty Junkie


Joined: 21 Jan 2008
Posts: 541

PostPosted: Wed Dec 30, 2009 11:33 am    Post subject: Reply with quote

U.Tews wrote:
We will implement {call name="funcname" ...} to allow calls to externally declared functions in the next couple of days.


Instead of dynamic function calls, forcing people to use two different styles for functions based on where the include is, and not being able to check if a function exists in the compiler how about having people put this at the top of the template:

Code:

{uses file='library.tpl'}


Which would just go through and compile all functions in library.tpl.

Are there any other definitions in the templates besides with inheritance? Can't think of any, but if there are in the future, then this would become even more useful.

Another thing. Does {call name="funcname"} work for compiler functions? If not, that could be mentioned in the docs when they are written.


btw: if the functions library.tpl depend on includes in that file, this idea might not work. So, if not, nevermind.
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Wed Dec 30, 2009 11:49 am    Post subject: Reply with quote

What did you mean by compiler function? compiler plugins?

An idea would be to call functions defined by the {function} only by
{call name="funcname" ...} and remove the {funcname} syntax for these type of functions. It would remove also ambiguity with a possible plugin with same name.
Back to top
View user's profile Send private message
douglassdavis
Smarty Junkie


Joined: 21 Jan 2008
Posts: 541

PostPosted: Wed Dec 30, 2009 12:10 pm    Post subject: Reply with quote

U.Tews wrote:
What did you mean by compiler function? compiler plugins?

An idea would be to call functions defined by the {function} only by
{call name="funcname" ...} and remove the {funcname} syntax for these type of functions. It would remove also ambiguity with a possible plugin with same name.



I was thinking at first that it might be possible to call all types of functions through the dynamic call syntax, although maybe the intent was it's only to be used for functions defined in smarty code. Either way, to cut down on confusion, in the docs, the type of functions that can be called with the dynamic call syntax needs to be specified out of:
1. compiler/plugin functions such as http://www.smarty.net/manual/en/plugins.compiler.functions.php
2. plugin functions defined in PHP such as http://www.smarty.net/manual/en/plugins.functions.php
3. template functions defined in smarty code(as mentioned in this thread)

(I may have used the wrong terms)

I have no preference as far as removing the {funcname} syntax

I'm still not sure if {uses file= would work or not... I guess I just don't know enough about how the compiler works.
Back to top
View user's profile Send private message
ldrut
Smarty Rookie


Joined: 22 Dec 2009
Posts: 11

PostPosted: Wed Dec 30, 2009 4:38 pm    Post subject: Reply with quote

Pretty much any solution is fine by me. Id' have to say though that the {funcname ...} syntax strikes me as a name collision generator. Every time you add new functionality it is bound to conflict with function names in user programs and force rewrites. Either you should carefully make a reserved keyword list before V3 release or go to the {call ...} syntax. Were it my program, I'd go to the {call ...} syntax.

No rush for me though - I'm using your suggested code as a workaround for now. Take your time and be sure it is the way you want it to be.


One suggestion I would make though is to reconsider all those name= attributes. They do make it nice in that there is no need to reserve keywords and I'm sure simplifies matters for code generation programs, but since you have already started down that road with the simplified {foreach} syntax, you may as well go all the way.

There is no reason the syntax could not just be {call funcname param1=value param2=value ...}, but leave the name= syntax available to make it easier for automatic code generation.

{include} is another one whose name attribute seems unnecessary and annoying.
Back to top
View user's profile Send private message
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7368
Location: Lincoln Nebraska, USA

PostPosted: Wed Dec 30, 2009 4:42 pm    Post subject: Reply with quote

Quote:
Id' have to say though that the {funcname ...} syntax strikes me as a name collision generator.


It would only collide with plugins or registered functions, and it must be unique within those anyways.
Back to top
View user's profile Send private message Visit poster's website
ldrut
Smarty Rookie


Joined: 22 Dec 2009
Posts: 11

PostPosted: Wed Dec 30, 2009 7:29 pm    Post subject: Reply with quote

If you say - I am pretty new to Smarty and the internals are still pretty much a mystery to me. I do think though that making some of the 'name=' optional where the parameter is required anyway bears looking at.

But then as I said, the internals are a mystery to me. It may be more trouble than it is worth. As well, that does increase the chance of name collision (with parameter names) so maybe the idea does not have merit.

Just my usual over-analyzing.

On the whole though I'd say I rather like Smarty. I'm in the process of rewriting my company website using it. It has bother been an easy process and has eliminated some really ugly PHP.
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Wed Dec 30, 2009 8:49 pm    Post subject: Reply with quote

The implementation of
Code:
{uses file='library.tpl'}
would be very tricky.

{include...} is processed at render time. {uses...} would work only if it gets loaded in the same template which contains the call to the template function.
If {uses...} is included for example in a subtemplate it will fail because that subtemplate may get compiled at a different time. It' making things ver complicated.

There was another request to implement variable template function calls like {call name=$foo}. This implementation would work also for externally defined template functions as all the checks will be done at render time.

To avoid two diffrent calling syntaxes we could just drop {funname...} syntax and use always {call name=funname...}.

That would be similar the defun plugin in the wiki for Smarty2.
Back to top
View user's profile Send private message
douglassdavis
Smarty Junkie


Joined: 21 Jan 2008
Posts: 541

PostPosted: Wed Dec 30, 2009 8:53 pm    Post subject: Reply with quote

U.Tews wrote:
The implementation of
Code:
{uses file='library.tpl'}
would be very tricky.

{include...} is processed at render time. {uses...} would work only if it gets loaded in the same template which contains the call to the template function.
If {uses...} is included for example in a subtemplate it will fail because that subtemplate may get compiled at a different time. It' making things ver complicated.

There was another request to implement variable template function calls like {call name=$foo}. This implementation would work also for externally defined template functions as all the checks will be done at render time.

To avoid two diffrent calling syntaxes we could just drop {funname...} syntax and use always {call name=funname...}.

That would be similar the defun plugin in the wiki for Smarty2.


thought about the compile time/render time difference after i posted (hence the deletion)... Anyway, the way you said it sounds good.
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Thu Dec 31, 2009 4:47 pm    Post subject: Reply with quote

External declared template functions are now working.

Like:
{* file1.tpl *}
{function name=test}
...some code...
{/function}

{* file2.tpl *}
{include name="file1.tpl"
{test}

So you can now create a library with template functions, include it and use the functions as usual.

The update is in the SVN now.
Back to top
View user's profile Send private message
douglassdavis
Smarty Junkie


Joined: 21 Jan 2008
Posts: 541

PostPosted: Thu Dec 31, 2009 5:09 pm    Post subject: Reply with quote

U.Tews wrote:
External declared template functions are now working.

Like:
{* file1.tpl *}
{function name=test}
...some code...
{/function}

{* file2.tpl *}
{include name="file1.tpl"
{test}

So you can now create a library with template functions, include it and use the functions as usual.

The update is in the SVN now.


I'm impressed. Very Happy

I'm wondering if the compiler just looks at the name of functions in file1.tpl and turns those calls into dynamic calls, or if all calls are dynamic (or, i guess not checked at compile time) now? I would just like to know in advance the restrictions involved in using the current approach, and make sure they are documented.


I was just wondering about scenarios such as the following, and if they would result in compile or runtime errors or work fine:


A:

file1.tpl
Code:

{if $x==1}
   {function name=test}
   ...some code...
   {/function}
{/if}

file2.tpl
Code:

{$x=2}
{include file="file1.tpl"}
{test}




B:

file1.tpl
Code:

   {function name=test}
   ...some code...
   {/function}

file2.tpl
Code:

{$x=2}

{if $x==1}
  {include file="file1.tpl"}
{/if}

{test}



C:

Code:

  {function name=test}
   ...some code...
  {/function}

Code:

{filename="file1.tpl"}
{include file=$filename}
{test}
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Smarty 3 All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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
Protected by Anti-Spam ACP