Dynamic variable names in Smarty

Ben Everard picture Ben Everard · Jan 24, 2010 · Viewed 8.3k times · Source

I want to be access some variables I've assigned dynamically from PHP in Smarty, here is an example:

$content_name = 'body'
$smarty->assign('content_name',$content_name);
$smarty->assign($content_name.'_title',$title);
$smarty->assign($content_name.'_body',$body);

// assigned values
// $content_name = home
// $home_title = $title
// $home_body = $body

The reason I want to access these dynamically is because I call multiple versions of a function that includes the code above, they all use the same template and therefore don't want to simply use $title, $body etc as their valus will conflict with each other.

Given that I know I want to access the title and body variables based on the content_name I set, how can I achieved this within smarty?

Answer

Dwza picture Dwza · Feb 6, 2018

Even if this post is very old, the given answere is accpeted but not an answere for the question. Its only an other oppertunity to handle main problem.

The question is how to use dynamic variables...

for the given sample, it should be something like

PHP

$content_name = 'body';
$title        = 'hello ';
$body         = 'world';
$smarty->assign('content_name',$content_name);
$smarty->assign($content_name.'_title',$title);
$smarty->assign($content_name.'_body',$body);

Smarty

{$content_name}          //body
{${$content_name}_title} //hello
{${$content_name}_body}  //world

{${$content_name}_title}{${$content_name}_body} my {$content_name} is awesome
//hello world my body is awesome

This is the dynamic way to use it. Even if its not the best way in this case :)

If you have kind of objects or multidimensional array... and you like to iterate them, you have to care about the whole string and not just the number...

For example:

PHP

$arr = [
    "attr1" => "hello ",
    "attr2" => "world ",
    "attr3" => "my body is awesome"
];
$smarty->assign('foobar', $arr);

Smarty

{for $i=1 to 3}
    {$foobar.{"attr$i"}}   //works (whole name must be string var mix)
    //{$foobar.attr{"$i"}} //fails
    //{$foobar.attr{$i}}   //fails
{/for}

But using {$foobar{$i}} on a simple array would work.

For all who need it, enjoy.