View previous topic :: View next topic |
Author |
Message |
cristiana Smarty n00b
Joined: 03 Nov 2011 Posts: 2
|
Posted: Thu Nov 03, 2011 12:57 pm Post subject: 3.1 Assigning variables after display or fetch in PHP |
|
|
In previous versions of Smarty, I was able to call php methods inside the template and have php run the ->assign smarty method to add new variables to the page. However, in 3.1, that functionality does not seem to work.
For example:
TPL:
Code: |
{$var->callMethod(1,2,3)}
{$123}
|
PHP Method:
Code: |
function callMethod($a,$b,$c){
$smarty->assign($a.$b.$c,'test');
}
|
Display Function:
Code: |
echo $smarty->fetch('tpl_file.tpl');
|
In 3.x the template would display 'test' however in 3.1, it gives me this error:
Undefined index: 123 in COMPILED_TEMPLATE_FILE
I tried several options in the fetch method, but nothing worked. Is there a set of options I can add to the fetch or in the smarty constructor to restore this functionality? |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Thu Nov 03, 2011 3:12 pm Post subject: |
|
|
inside your method how are you getting the smarty object assigned to $smarty ? |
|
Back to top |
|
cristiana Smarty n00b
Joined: 03 Nov 2011 Posts: 2
|
Posted: Thu Nov 03, 2011 3:50 pm Post subject: |
|
|
In my actual code it looks like
Code: |
$this->smarty->assign(....
|
The smarty object is instantiated and attached as a property of my own object
The above example was just the minimum amount of code needed to produce the error. |
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Thu Nov 03, 2011 6:06 pm Post subject: |
|
|
Uwe, we should note this in the docs… seems to be occuring more often :/
christina, you're doing the following Quote: | $smarty = new Smarty();
$smarty->display('eval:{xy()}');
function xy() {
global $smarty;
$smarty->assign(…);
} |
what you need to be doing is
Quote: | $smarty = new Smarty();
$tpl = $smarty->createTemplate('eval:{xy()}');
$tpl->display();
function xy() {
global $tpl;
$tpl->assign(…);
} |
The reason for this is Smarty::fetch() and display() clone the Smarty instance internally. Uwe can probably tell you more about why this is done. _________________ Twitter |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Nov 03, 2011 6:25 pm Post subject: |
|
|
See www.smarty.net/forums/viewtopic.php?t=20263
Why this happens. Object methods must assign values to a template object, not Smarty object.
This restriction will be removed in the next comming major release 3.2 which we are currently working on. Before you ask we don't have tofay a date for that release. |
|
Back to top |
|
SlasherZ Smarty n00b
Joined: 17 Feb 2012 Posts: 4
|
Posted: Fri Feb 17, 2012 9:57 am Post subject: |
|
|
My team has the same problem. But I guess, there is noting to do other than to leave 3.0.9 until this is implemented. (hopefully soon ) |
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Fri Feb 17, 2012 6:53 pm Post subject: |
|
|
Uwe and me just revisited this issue and realized that the solution we had in mind for 3.2 wasn't the thing to roll with. We've traced the source of this issue to the very bad `global $smarty;` design. We realize this was necessary to obtain a reference to the Smarty object from within arbitrary functions (being those not registered as plugins).
As this actually is a minor change (enabling you to do what you need, but without breaking BC) we've decided to include this in the upcomming Smarty 3.1.8. Smarty 3.2 is too far away to name a date.
This change will allow you to do something along the lines of Code: | {foo("bar", 123, $smarty_template_instance)} | and Code: | function foo($a, $b, Smarty_Internal_Template $template)
{
$template->assign($a, $b);
} |
So Smarty will provide a reference to the current template object, if you ask it to. (Note that `$smarty_template_instance` will not be the name of said variable). This eliminates the need for any `global $smarty` crap and allows you to access Smarty's templates where you need them.
If this is a nogo for you, please elaborate on why that is. _________________ Twitter |
|
Back to top |
|
SlasherZ Smarty n00b
Joined: 17 Feb 2012 Posts: 4
|
Posted: Sat Feb 18, 2012 11:13 am Post subject: |
|
|
I think this should work.
Here is a simplified way how my structure looks like:
Code: |
class MyTemplateEngine
{
static private $smarty;
function __constructor()
{
self::$smarty = new Smarty();
self::$smarty->registerPlugin("function", "_", "MyTemplateEngine::translate_me");
}
function translate_me($params)
{
$t = translator($params['str']);
$var = $params['var'];
$this->_assign($var, $t);
}
function _assign($var, $value)
{
self::$smarty->assign($var, $value);
}
function display()
{
self::$smarty->display($template);
}
}
|
Now the template:
Code: |
{* a call from inside the template to a registered smarty plugin that translates the string and stores its value inside 'hello' variable*}
{_ str="Hello" var="hello"}
<p>{$hello}</p>
|
|
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Sat Feb 18, 2012 12:44 pm Post subject: |
|
|
The given setup can be properly executed with current Smarty 3.1.
Your MyTemplateEngine class is bogus. The constructor initializes a new Smarty instance into a static variable. Were MyTemplateEngine instantiated twice, you'd lose the first Smarty instance (including the data).
Anyway, your mistake is ignoring the second parameter passed to your plugin function "_": Code: | function translate_me($params, Smarty_Internal_Template $template)
{
$t = translator($params['str']);
$var = $params['var'];
$template->assign($var, $t);
} |
Plugin functions are passed a reference to the current template object, so they know what to operate on. You neglected this and tried to grab a global instance reference. _________________ Twitter |
|
Back to top |
|
SlasherZ Smarty n00b
Joined: 17 Feb 2012 Posts: 4
|
Posted: Sat Feb 18, 2012 2:13 pm Post subject: |
|
|
Ow..my mistake, it seems I've missed that in the documentation because it worked without that in 3.0.9.
Still I'm having some problems. Lets say I call my translator function from with a included template. The assign function just assigns the value to current template file, making it unavailable to the rest of included template files.
When I tried to use assignGlobal function on Smarty_Internal_Template object it didn't work, no variables were assigned; while in 3.0.9 an assigned template variable was available to other included tpl files. |
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Sat Feb 18, 2012 2:16 pm Post subject: |
|
|
Code: | function translate_me($params, Smarty_Internal_Template $template)
{
$t = translator($params['str']);
$var = $params['var'];
// assign to current template
$template->assign($var, $t);
// assign to parent template (or smarty instance)
$template->parent->assign($var, $t);
// assign to smarty instance
$template->smarty->assign($var, $t);
} |
may help _________________ Twitter |
|
Back to top |
|
SlasherZ Smarty n00b
Joined: 17 Feb 2012 Posts: 4
|
Posted: Sat Feb 18, 2012 2:38 pm Post subject: |
|
|
It did
I'll do more testing in next few days, we've got over 30 themes with over 200 template files to go through.
Thank you rodneyrehm for all your help! |
|
Back to top |
|
|