Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

3.1 Assigning variables after display or fetch in PHP

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General
View previous topic :: View next topic  
Author Message
cristiana
Smarty n00b


Joined: 03 Nov 2011
Posts: 2

PostPosted: Thu Nov 03, 2011 12:57 pm    Post subject: 3.1 Assigning variables after display or fetch in PHP Reply with quote

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
View user's profile Send private message
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7368
Location: Lincoln Nebraska, USA

PostPosted: Thu Nov 03, 2011 3:12 pm    Post subject: Reply with quote

inside your method how are you getting the smarty object assigned to $smarty ?
Back to top
View user's profile Send private message Visit poster's website
cristiana
Smarty n00b


Joined: 03 Nov 2011
Posts: 2

PostPosted: Thu Nov 03, 2011 3:50 pm    Post subject: Reply with quote

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
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Thu Nov 03, 2011 6:06 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
U.Tews
Administrator


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

PostPosted: Thu Nov 03, 2011 6:25 pm    Post subject: Reply with quote

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
View user's profile Send private message
SlasherZ
Smarty n00b


Joined: 17 Feb 2012
Posts: 4

PostPosted: Fri Feb 17, 2012 9:57 am    Post subject: Reply with quote

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 Confused)
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Fri Feb 17, 2012 6:53 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
SlasherZ
Smarty n00b


Joined: 17 Feb 2012
Posts: 4

PostPosted: Sat Feb 18, 2012 11:13 am    Post subject: Reply with quote

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
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Sat Feb 18, 2012 12:44 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
SlasherZ
Smarty n00b


Joined: 17 Feb 2012
Posts: 4

PostPosted: Sat Feb 18, 2012 2:13 pm    Post subject: Reply with quote

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
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Sat Feb 18, 2012 2:16 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
SlasherZ
Smarty n00b


Joined: 17 Feb 2012
Posts: 4

PostPosted: Sat Feb 18, 2012 2:38 pm    Post subject: Reply with quote

It did Smile

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
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General 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