Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.

Possible bug in the block function compiler

 
Post new topic   Reply to topic    Smarty Forum Index -> Smarty 3
View previous topic :: View next topic  
Author Message
Michael White
Smarty Rookie


Joined: 08 Oct 2009
Posts: 20

PostPosted: Sun Nov 08, 2009 6:43 am    Post subject: Possible bug in the block function compiler Reply with quote

It is possible that my understanding of block function behavior is off but I have a feeling there is a bug in the block function handling in the compiler.

Here is the behavior that currently happens when a block function is compiled:

(I used pseudo code for clarity)
Code:

$repeat = true;
$smarty->runPlugin(); // The plugin checks permissions and sets $repeat = false
while($repeat) {
    // code that should not run when user does not have permissions
    $repeat = false;
    echo $smarty->runPlugin();
}


Some things to keep in mind:

    * My permissions plugin allows one of the parameters to specify alternate content if the user does not have permission.

    * The code inside the while() loop should never be allowed to run if the permissions check fails. Part of that code loads some JavaScript and CSS that are targeted at authenticated users only.

    * Currently, I am not able to simply return alternate content on the first run of the block function and have it rendered. I can only return content to be rendered on the second run of the plugin.

    * I cannot use the second run of the plugin to render the alternate content because if I did that then the JS and CSS would also be loaded into the page since everything within the while() loop would run.

I believe that the fix could be one of the two options below.

    * Set the compiler to render an "echo" statement in front of the first call to the block function.
    * OR move the second call to the block function outside of the while loop so that it always runs the block function twice.


Performance-wise I would think the first option would be the most efficient.


Example fixed code - first option from above (also in pseudo code):
Code:

$repeat = true;
echo $smarty->runPlugin(); // The plugin checks permissions and sets $repeat = false
while($repeat) {
    // code that should not run when user does not have permissions
    $repeat = false;
    echo $smarty->runPlugin();
}



For now I implemented a workaround where I simply call "echo $content;" directly from my block function plugin if I need to render output the first time the plugin is called.

--- Michael
Back to top
View user's profile Send private message Visit poster's website
U.Tews
Administrator


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

PostPosted: Sun Nov 08, 2009 5:14 pm    Post subject: Reply with quote

This is not a bug. The block function is intended for implementation of loops or fuctions where the rendered block content needs processing befor it gets output.

The first call to the block function (before the while loop) is intended for initialization like assigning loop variables etc. Nothing will be output here.
It's identified by a 'null' value of the $content parameter.

The second call (which may be repeated on loops) gets the rendered content of the block body may process the content and return it for output.


What you are looking for is more a 'if .... else ....' construct. Even the block function was not originally intended for that you can still use it:

Simply return of the first call ($content == null) without doing anything.
Check your permissions on the second call and return the desired result for output.
Back to top
View user's profile Send private message
Michael White
Smarty Rookie


Joined: 08 Oct 2009
Posts: 20

PostPosted: Sun Nov 08, 2009 5:38 pm    Post subject: Reply with quote

hmmm....

I can accept that it is not designed for what I want it to do. Smile


I was trying to reduce the amount of template code required to do a permissions check and run different code depending on the result. That is why I created the plugin instead of using and if/else statement.


In a normal block function where the direct output of the block code is all that matters, the usual method of only rendering content on the second call would work. In my case this does not work as the permissions must be checked prior to running the block code.

No matter what, allowing the second call to the block function causes the code within the block to run which violates the permissions check.

Note: Now that Smarty can run PHP code directly within the standard Smarty templates, this allows the code within the block to do things behind the scenes that do not necessarily have to do with rendering content within the block itself. This code could, for example, add new JS/CSS assets, etc. that are rendered elsewhere.

Another system I am working with has something like this implemented with a block function in Smarty 2. That is why I believe the behavior here is different and possibly buggy if BC is being maintained for things like this.

Are there any major side-effects of allowing the first call to the block function to render output with "echo" like in my previous example?

Note: I have not examined the compiled templates that the other system based on Smarty 2 outputs. However, I do know that that system does not extend Smarty directly and the copy of Smarty used is always downloaded from the Smarty site for each project to make sure the latest updates are present. From this I know that the Smarty 2 codebase it uses remains unaltered.
Back to top
View user's profile Send private message Visit poster's website
U.Tews
Administrator


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

PostPosted: Sun Nov 08, 2009 7:25 pm    Post subject: Reply with quote

I forgot to mention: It's the same behaviour as in Smarty2.
Back to top
View user's profile Send private message
Michael White
Smarty Rookie


Joined: 08 Oct 2009
Posts: 20

PostPosted: Sun Nov 08, 2009 8:12 pm    Post subject: Reply with quote

I went in an stripped out the excess code inserted within the while() loop that makes up the block in the compiled templates (both Smarty 3 and Smarty 2).

I see now that they are logically identical (though syntactically different).

I really cannot figure out how the permission plugin behaves properly on the other system I'm using and does not work the same in my current Smarty 3 project.

For now I'm sticking with just using that "echo" statement inside the permission plugin itself which actually works identically to echoing the first call's output. I will also return null after echoing so that if, in any future release, the behavior changes, my plugin will not break.

I'm sure there is some subtle difference in the framework on the Smarty 2 project from the one I am using on this Smarty 3 project that is allowing it to behave properly.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Smarty 3 All times are GMT
Page 1 of 1

 
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