Page 1 of 1

multi-dimensional iteration in Smarty

Posted: Thu Aug 03, 2006 11:43 pm
by Luke
Is it possible to iterate through an array that is three or more levels deep with smarty? If so... how? My brain just isn't working real well tonight. :(

Posted: Fri Aug 04, 2006 3:36 am
by Jenk
I don't think you can iterate within an interation, however could be wrong..

Though as you are probably aware, you use associative arrays like so:

Code: Select all

{section name=i loop=$array}
    <p>{$array[i].val1} {$array[i].val2}</p>
{/section}
Just maybe you can nest the sections with something like:

Code: Select all

{section name=i loop=$array}
  {section name=j loop=$array[i]}
    <p>{$array[i][j].val}</p>
  {/section}
{/section}
untested and unsure.. not got anything to test on here.

Posted: Fri Aug 04, 2006 10:35 am
by Luke
I stilll can't seem to get it to work... maybe I'm going about it wrong. Say I have an array like:

Code: Select all

Array
(
    [title] => Array
        (
            [0] => Must be between 1 and 100 characters in length.
            [1] => Must contain only letters.
        )

    [body] => Array
        (
            [0] => Must be between 1 and 5000 characters in length.
            [1] => Must contain the word "Chicken".
        )

)
I do not want to have to assign $Template->assign('title', $errors['title']) for every field... isn't there a way to traverse this with smarty?

Posted: Fri Aug 04, 2006 10:44 am
by RobertGonzalez
Yes, you can. You can foreach or section the arrays (or switch in between the two). Try it, it ispretty easy to do and pretty cool.

Posted: Fri Aug 04, 2006 10:45 am
by Jenk
I guess for that you would use:

Code: Select all

<p>{$title.body.0}</p>

Posted: Fri Aug 04, 2006 11:09 am
by Luke
I've got this:

Code: Select all

{foreach name=outer from=$form_errors item=errors}
	  	{foreach from=$errors.body item=error}
		  <tr>
		   <td colspan="2" class="error">{$error}</td>
		  </tr>
	  	{/foreach}
	  {/foreach}
But it doesn't work...
This works, but it prints all the errors and not just the body errors:

Code: Select all

{foreach name=outer from=$form_errors item=errors}
	  	{foreach from=$errors item=error}
		  <tr>
		   <td colspan="2" class="error">{$error}</td>
		  </tr>
	  	{/foreach}
	  {/foreach}

Posted: Fri Aug 04, 2006 11:10 am
by AshrakTheWhite

Code: Select all

arraykey1.arraykey2
in smarty means the same as

Code: Select all

$arraykey1['arraykey2']

Posted: Fri Aug 04, 2006 11:10 am
by Luke
then how come the first example doesn't work? :(

Posted: Fri Aug 04, 2006 11:13 am
by Luke
:oops: Nevermind I figured it out

Code: Select all

{foreach name=outer from=$form_errors.body item=errors}
	  	{foreach from=$errors item=error}
		  <tr>
		   <td colspan="2" class="error">{$error}</td>
		  </tr>
	  	{/foreach}
	  {/foreach}

Posted: Fri Aug 04, 2006 11:15 am
by RobertGonzalez
Way to go Ninja.

Posted: Fri Aug 04, 2006 11:45 am
by AKA Panama Jack
Smarty or Template Lite has a really weird array syntax.

The following will work with multi-dimensional arrays.

Code: Select all

{ $myvar.$element.$element2 }

{ $myvar[$element][$element2] }

{ $myvar.element.element2 }
While this will not work...

Code: Select all

{ $myvar[element][element2] }

{ $myvar['element']['element2'] }
The element and element2 in the $myvar[element][element2] variable will be processed like Smarty/Template Lite constants.

The 'element' and 'element2' in the $myvar['element']['element2'] variable will be processed like text and not array elements. They don't quite follow the PHP convention for array variables inside a template.

If you want to be safe you should always use a period (.) between each element position in a multi-dimensional array instead of brackets ([]) when working inside templates.

You CAN use brackets ([]) like this $myvar[$element][$element2] in a multidimensional array in a template as long as the element inside the bracket is another variable. But like I said before it is best to use periods (.) to be safe.