View previous topic :: View next topic |
Author |
Message |
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Sun Nov 08, 2009 11:48 pm Post subject: How to create a Smarty 3 compiler plugin? |
|
|
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 |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Mon Nov 09, 2009 8:25 pm Post subject: |
|
|
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 |
|
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Mon Nov 09, 2009 10:22 pm Post subject: |
|
|
Thnx. If I want to support nocache, do I have to add that to the optional attributes? |
|
Back to top |
|
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Mon Nov 09, 2009 10:47 pm Post subject: |
|
|
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 |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Tue Nov 10, 2009 4:24 pm Post subject: |
|
|
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 |
|
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Wed Nov 11, 2009 11:00 am Post subject: |
|
|
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 |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Wed Nov 11, 2009 5:20 pm Post subject: |
|
|
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 |
|
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Thu Nov 12, 2009 6:48 pm Post subject: |
|
|
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 |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Nov 12, 2009 6:56 pm Post subject: |
|
|
If your filename is a variable it should be
{.... file=$image} not {.... file="$image"} |
|
Back to top |
|
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Thu Nov 12, 2009 8:12 pm Post subject: |
|
|
I knew that. So I feel really stupid now |
|
Back to top |
|
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Thu Nov 12, 2009 8:31 pm Post subject: |
|
|
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 |
|
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Thu Nov 12, 2009 8:38 pm Post subject: |
|
|
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 |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Nov 12, 2009 8:43 pm Post subject: |
|
|
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 |
|
caoimhin Smarty Rookie
Joined: 08 Nov 2009 Posts: 24 Location: Lebbeke, Belgium
|
Posted: Thu Nov 12, 2009 8:47 pm Post subject: |
|
|
I assign it in my php file.
$oTemplate->assign('image', 'img/test.jpg'); |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Nov 12, 2009 8:52 pm Post subject: |
|
|
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 |
|
|