View previous topic :: View next topic |
Author |
Message |
eadz Smarty Regular
Joined: 30 Apr 2003 Posts: 61 Location: Auckland, New Zealand
|
Posted: Fri Jan 09, 2004 4:00 am Post subject: how to eval smarty template code in php varible ? |
|
|
Say I have a string, but I want to be able to put smarty tags in it.
So how would I evaluate the string for smarty tags within php?
E.g.
$smarty->assign('test','Testing');
$var = 'hello {$test}';
$evald = $smarty->eval($var);
.... so $evald = "hello Testing";
So is there something like $smarty->eval() which can evaluate a "template" ?
Like $smarty->fetch but you pass the template directly to it rather than it fetching it. _________________ bBlog - Smarty based blogging software
I work for Webforce web site design ( Auckland, NZ ) |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Fri Jan 09, 2004 9:27 am Post subject: |
|
|
there is the {eval}-tag. you can use a dummy template that just consists of
eval.tpl Code: | {eval var=$tpl_code} |
and then do
[php:1:735ca86571]
$var = 'hello {$test}';
$smarty->assign('tpl_code', $var);
$evald = $smarty->fetch('eval.tpl');
[/php:1:735ca86571]
but eval is highly disencouraged. you have to compile the template-source on each request. i wouldn't wonder if it's about 10 times slower than "normal" templates.
maybe you can write a resource-plugin to solve your problem. than depends on where the $var came from. |
|
Back to top |
|
eadz Smarty Regular
Joined: 30 Apr 2003 Posts: 61 Location: Auckland, New Zealand
|
Posted: Fri Jan 09, 2004 10:14 am Post subject: |
|
|
Hi,
I should have mentioned that I have the dummy template.. but It kind of seems silly to do that. I would prefer a pure php method..
The reason is so I can evaluate a blog post for smarty tags.
Eadz _________________ bBlog - Smarty based blogging software
I work for Webforce web site design ( Auckland, NZ ) |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
|
Back to top |
|
eadz Smarty Regular
Joined: 30 Apr 2003 Posts: 61 Location: Auckland, New Zealand
|
Posted: Sun Jan 11, 2004 11:27 am Post subject: |
|
|
The thing is... the template usually looks like
{getposts num=20 section=news assign=posts}
{foreach from=$posts item=post}
<h2>{$post.title}</h2>
<p>{$post.body}</p>
{/foreach}
.. to have a template resource for a singe post is a lot of sql calls and stuff. Also the code does a lot to the posts, ie meta data gathering ( like number of comments ). Also, using smarty tags in posts is optional, so you don't really want to be editing templates to change an option.
what I'm looking for is to really get into the code and use the same functions that the eval plugin uses...
so I'm not sure if something like this would work :
[php:1:c5dc065756]
$smarty->assign('a','there');
$text = 'hello {$a}';
$smarty->_compile_source('evaluated template', $text, $_var_compiled);
ob_start();
$smarty->_eval('? >' . $_var_compiled);
$_contents = ob_get_contents();
ob_end_clean();
[/php:1:c5dc065756]
will $_contents contain 'hello there' ?
( there is a space between ? and > but there shouln't be.. some phpbb thing. ) _________________ bBlog - Smarty based blogging software
I work for Webforce web site design ( Auckland, NZ ) |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Sun Jan 11, 2004 12:08 pm Post subject: |
|
|
your resource-plugin does not necessarily have to get the contents from the db. it could ask the result-set of {getposts} for the data.
the blogpost-resource-plugin needs a way to look into the result-set of {getposts} and obtain the modification-time and the contents of the post from there. no need to query the post twice. you just need an application-wide uniq resource-name (maybe the id of the post) so smarty can manage the compiled-tpl in templates_c correctly.
your code may work but it:
- relies on an internal method ("_compile_source")
- compiles the contents every time you display them. |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Tue Jan 13, 2004 10:32 am Post subject: |
|
|
sorry if it seems that i want to push you to a resource-plugin. it's just that i'm sure you won't be satisfied by {eval} on a heavy loaded site.
IMHO {eval} is only acceptable if you employ caching on your pages. or on less frequently used templates like email-templates. |
|
Back to top |
|
eadz Smarty Regular
Joined: 30 Apr 2003 Posts: 61 Location: Auckland, New Zealand
|
Posted: Tue Jan 13, 2004 11:00 am Post subject: |
|
|
The code I posted above worked btw...
Hmm i seem to remember php's eval() was slow too. But we'll have to see. If peformance is a problem i can use the resource thing, but it'll mean quite a bit of recoding. _________________ bBlog - Smarty based blogging software
I work for Webforce web site design ( Auckland, NZ ) |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Tue Jan 13, 2004 11:44 am Post subject: |
|
|
eadz wrote: | The code I posted above worked btw... |
yes, but only with 2.6.0. not with 2.5.0. and if it won't work with 2.7.0 anymore you won't be notified before because _compile_source() is an internal function.
i'd prefer something like:
[php:1:2da43ed58e]require_once $smarty->_get_plugin_filepath('function', 'eval');
$result = smarty_function_eval(array('var'=>$var), $smarty);
[/php:1:2da43ed58e]
(please don't ask me why it's named "_get_plugin_filepath" and not "get_plugin_filepath", i don't know)
Quote: | Hmm i seem to remember php's eval() was slow too. |
but php doesn't compile it's code. compare your site with $smarty->force_compile = false and force_compile = true. using {eval} is like force_compile is true. |
|
Back to top |
|
eadz Smarty Regular
Joined: 30 Apr 2003 Posts: 61 Location: Auckland, New Zealand
|
Posted: Sat Jan 17, 2004 8:48 am Post subject: |
|
|
I was thinking about the resource plugin..
If I could do
{include file="post:`$post.id` contents=`$post.body` timestamp=`$post.modified`}
that would mean it could compile the smarty tags in posts, but I wouldn't have to change any internals... _________________ bBlog - Smarty based blogging software
I work for Webforce web site design ( Auckland, NZ ) |
|
Back to top |
|
Fabien Smarty n00b
Joined: 10 Jun 2004 Posts: 1
|
Posted: Thu Jun 10, 2004 5:16 pm Post subject: What we did... |
|
|
Hello.
We had quite the same goal, except that we just wanted to pass the template through the variable. Below is what we did:
We create the resource file {resource.meta.php} that we save into the plugin directory.
Then we did a standard assignation in our php file
$smarty->assign('title',$title);
And fetch like the result as follow : $smarty->fetch("meta:".$description)
$description contains for example: "The title of my page is {$title}."
Finally, we fetch into the "real" template this result:
$smarty->fetch('my_template.tpl');
And it works.
What do you think? |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Thu Jun 10, 2004 5:46 pm Post subject: |
|
|
I just thought that I would add that when using custom resources, your filename parsing is in your control. For example, I have a plugin that uses the following convention:
{include file="userdb:TABLE/FIELD?condition1&condition2&condition3...."}
The fact that you can do this makes it very convenient to follow alternate processing paths since you can pass arbitrary parameters. Custom resources are a significant tool, IMHO.
@Fabien: hmm. If $title already exists in the PHP namespace, then there is no need for any of that. Something like the following should evaluate properly using PHP's standard string parsing.
$smarty->assign('title', "The title of my page is {$title}.");
If you are doing more complicated things that use Smarty specifics, then: if the "meta" resource simply reads from a variable, then I don't think it is a good solution. Despite being a resource, you will be forced to always recompile since you can't generate an appropriate timestamp. I wrote such a resource ages ago and had that very issue. |
|
Back to top |
|
oschonrock Smarty Rookie
Joined: 08 Aug 2003 Posts: 13
|
Posted: Sun Jun 13, 2004 1:28 pm Post subject: |
|
|
Hi boots
I am working with fabien on the same project:
$title does exsits in php namespace, but it contains a smarty template (ie {if.....} {$somesmartyvar} {/if}...etc)
you are right that we always have to recompile. here is our plugin resource (has been renamed to "var" since fabien's post:
Code: |
function var_content_source($tpl_name, &$tpl_source, &$smarty)
{
// pass into the variable
$tpl_source = $smarty->get_template_vars($tpl_name);
return true;
}
function var_content_timestamp($tpl_name, &$tpl_timestamp, &$smarty)
{
// must always recompile because the variable that hold the content could have changed
$tpl_timestamp = time();
return true;
}
function var_content_secure($tpl_name, &$smarty)
{
// assume all templates are secure
return true;
}
function var_content_trusted($tpl_name, &$smarty)
{
// not used for templates
return true;
}
?>
|
The template code does originally come out of a db. But it has already been loaded into php namespace by the time the code that fabien posted runs. So it didn't seem logical to retrieve it again out of the db just to retrieve the last_modofied_date (which does exist in a columns of that table). The typical template is very small (maybe 500bytes), so we thought the compilaltion penalty was not that significant given we are saving a db query and total page parse time of this application is as high as 200ms anyway.
What did you think of using smarty->assign in the main code and $smarty->get_template_vars($tpl_name); in the resource to make the template source available in the resource handler functions?
Did you give up on your own "var" resource because of performance or other reasons? What did you replace it with? |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Sun Jun 13, 2004 5:19 pm Post subject: |
|
|
hi oschonrock.
I only created my "var" resource as a test (I think that's what it is called, even--its at the wiki, anyhow and it reads from global vars)--so I didn't really need to replace it.
In your case, it sounds like you are trying to "cache" the template code. There are other ways of doing this, of course, for example using shm or mmcache or such. There are also caches that work in front of dbs which makes repeated calls to them fairly inexpensive. In fact, there is even one such cache that is distributed, though that is obviously intended for high load/availability sites.
Anyways, since you are able to get a timestamp from your db, a possible refinement to your resource is to grab the time stamp and put it in a private array somewhere that your resource can access. Use the template name as the record key to lookups very simple. Then again, you may not really care that a template has been updated in the time it takes to run a single script and in fact, it may not be appropriate to have multiple versions in a single call.
Quote: | What did you think of using smarty->assign in the main code and $smarty->get_template_vars($tpl_name); in the resource to make the template source available in the resource handler functions? |
Unless you want to display the original template code, I think it is better to keep this data out of the template namespace.
Cheers!
EDIT: there was a thread on the smarty-dev ML awhile back (2.5 timeframe??) that tried to consider "re-using" often called templates by caching them. Monte started an implementation of it, but eventually it was discarded as it introduced new complexity and proved to be less performant than orignally hoped. You may want to try to find that thread and see if you have any new ideas that might make it workable. |
|
Back to top |
|
|