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

How to create a Smarty 3 compiler plugin?
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    Smarty Forum Index -> Smarty 3
View previous topic :: View next topic  
Author Message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

PostPosted: Sun Nov 08, 2009 11:48 pm    Post subject: How to create a Smarty 3 compiler plugin? Reply with quote

Hi guys,

I'm currently trying out Smarty 3 and want to try-out the creating of new plugins. And I have some questions. Let's say I want to create a compiler plugin for static images. I want to use the following syntax {static_image src=".." ..}. I have some ideas for this plugin, but for this example I will keep it just simple and the only thing I want is that it creates <img src=".." .. />.

I created a file with the name "compiler.static_image.php". In the file I have following class:

Code:

class Smarty_Compiler_Static_Image extends Smarty_Internal_CompileBase {
   public function execute($args, $compiler) {
      $this->compiler = $compiler;
      $this->required_attributes = array('alt', 'src');
      $this->optional_attributes = array('class', 'id', 'height', 'title', 'width');

      //check and get attributes
      $_attr = $this->_get_attributes($args);

      //$this->_open_tag('img',$_attr);
      //$this->_close_tag('img'));

      $_output = '';

      foreach ($_attr as $key => $value) {
         $_output .= sprintf(' %s=%s ', $key, $value);
      }

      return sprintf('<img%s/>', $_output);
   }
}


Is this the way to do this? And what is the purpose of $this->_open_tag and $this->_close_tag? Am I missing something and can I use some function to generate the '<img .. />' tag after using $this->_open_tag and / or $this->_close_tag?

Thnx !
Back to top
View user's profile Send private message
U.Tews
Administrator


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

PostPosted: Mon Nov 09, 2009 8:25 pm    Post subject: Reply with quote

Yes, store compiler.static_image.php in your plugins folder.

However your output is not correct as the attribute values may have as source also Smarty varibles or expressions.

For this simple example the code should look like this:


Code:

      foreach ($_attr as $key => $value) {
         $_output .= sprintf(' %s=%s ', $key, '"<?php echo ' . $value . ';?>"');
      }


The methodes _open_tag and _close_tag are used only for block tags to track nesting and optionally pass data from the opening tag to the closing tag compiler code.
Back to top
View user's profile Send private message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

PostPosted: Mon Nov 09, 2009 10:22 pm    Post subject: Reply with quote

Thnx. If I want to support nocache, do I have to add that to the optional attributes?
Back to top
View user's profile Send private message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

PostPosted: Mon Nov 09, 2009 10:47 pm    Post subject: Reply with quote

Let's say I have a template variable $image with the value "img/pic.jpg" and I do the following:

{static_image alt="" src=$image}

Now, with the value of $image I want to do some things while compiling. Let's say I want to calculate the width and the height and add those things as extra attribute (only when they are not already set). How can I access the value of $image? Because now I get $smarty_tpl->getVariable('image')->value as string.
Back to top
View user's profile Send private message
U.Tews
Administrator


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

PostPosted: Tue Nov 10, 2009 4:24 pm    Post subject: Reply with quote

I think your approach is completely wrong. A compiler pluging shall produce compiled code, but not do calculations based on attribute values and returning the results as output.

In your case you would calculate width and height at compile time which would be used on all display calls. If you later assign a different value to $image or change your image the attributes will not get recalculated and the values from compile time will be used by mistake.

What you need is a function plugin which gets executed on every display call.
Back to top
View user's profile Send private message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

PostPosted: Wed Nov 11, 2009 11:00 am    Post subject: Reply with quote

That's the reason why I want it to calculate it at compiler time, because the size of that image does not change so I think it's not necessary to calculate it everytime over and over again. It's also the reason why I call it static_image. The image should not be changed, never. And if I want to change that image for a reason I will force a compile manually. Is my approach still wrong then?
Back to top
View user's profile Send private message
U.Tews
Administrator


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

PostPosted: Wed Nov 11, 2009 5:20 pm    Post subject: Reply with quote

It is breaking rules for a general approach. But if you are aware of all the restrictions you can do it.

Normally the compiler must not know the content of variables used at attributes. To get these you have to do the following:

$_smarty_tpl = $compiler->template; // set up template enviroment

eval('$value = ' . $_attr['key'] . ';');

After that $value will contain the value of attrinute 'key'.
Back to top
View user's profile Send private message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

PostPosted: Thu Nov 12, 2009 6:48 pm    Post subject: Reply with quote

I did that and it worked fine, until I updated to beta 2. Now it returns

"".$_smarty_tpl->getVariable('image')->value.""

instead of

$_smarty_tpl->getVariable('image')->value

and the eval does not work anymore.
Back to top
View user's profile Send private message
U.Tews
Administrator


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

PostPosted: Thu Nov 12, 2009 6:56 pm    Post subject: Reply with quote

If your filename is a variable it should be

{.... file=$image} not {.... file="$image"}
Back to top
View user's profile Send private message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

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

I knew that. So I feel really stupid now Embarassed
Back to top
View user's profile Send private message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

PostPosted: Thu Nov 12, 2009 8:31 pm    Post subject: Reply with quote

Hmz, still doesn't work .. After eval $src is just empty.


Code:
$_smarty_tpl = $compiler->template;

var_dump($_attr['src']); // output = string(41) "$_smarty_tpl->getVariable('image')->value"

eval('$src = ' . $_attr['src'] . ';');

var_dump($src); // output = NULL



If I do a var_dump of $_smarty_tpl->getVariable('image') then it returns object(Undefined_Smarty_Variable)#60 (0) { }

But image is defined, if I do {$image} in a template then the path is printed.
Back to top
View user's profile Send private message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

PostPosted: Thu Nov 12, 2009 8:38 pm    Post subject: Reply with quote

Now, the tpl file where I'm testing this is a file that is included in another tpl file, and that file extends another file.

I have following files:

  • container.tpl
  • test.tpl (extends container.tpl, includes test_a.tpl)
  • test_a.tpl


If I use {static_image src=$image} in container.tpl, everyting is ok.
If I use {static_image src=$image} in test.tpl (in a block that overrides a block in container.tpl), I get an Undefined_Smarty_Variable object. If I print $image it prints out the path.
Back to top
View user's profile Send private message
U.Tews
Administrator


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

PostPosted: Thu Nov 12, 2009 8:43 pm    Post subject: Reply with quote

Do you assign your Smarty variable $image in your script with
$smarty->assign('image','foo.jpg');

or do you assign it in the template with {$image='foo.jpg} or {assign var='image' value='foo.jpg'} ?

If you assign it in your template it can not work, as it has no value at compile time.
Back to top
View user's profile Send private message
caoimhin
Smarty Rookie


Joined: 08 Nov 2009
Posts: 24
Location: Lebbeke, Belgium

PostPosted: Thu Nov 12, 2009 8:47 pm    Post subject: Reply with quote

I assign it in my php file.

$oTemplate->assign('image', 'img/test.jpg');
Back to top
View user's profile Send private message
U.Tews
Administrator


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

PostPosted: Thu Nov 12, 2009 8:52 pm    Post subject: Reply with quote

Okay that will not work. You can't use that in a child {block}... {/block} definition, because when that is compiled it does not have any sort of scope to variables.

That was one of the reasions why I said it could not work in all situations before. Again the compiler was not intended to interpret values at compile time.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Smarty 3 All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
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