10

How can this be done inside of a template? I have done it with ArrayData using the key in the template loop to access values from the template, but if I have an arbitrary array of strings with no keys, what variable do I use to access the values?

If in my controller I have this:

public function ArrayList()
{
    $ArrayList = new ArrayList(array('this', 'is', 'a', 'test'));
    return $ArrayList;
}

And this in my template:

<% loop $ArrayList %>1<% end_loop %>

What do I put in place of 1 to get the template to spit out "this is a test"?

danbroooks
  • 2,477
  • 4
  • 18
  • 39

2 Answers2

15

as far as I know this is not possible, you need to wrap each item into a ArrayData object

public function ArrayList()
{
    $ArrayList = ArrayList::create(array(
        ArrayData::create(array('Text' => 'this')),
        ArrayData::create(array('Text' => 'is')),
        ArrayData::create(array('Text' => 'a')),
        ArrayData::create(array('Text' => 'test')),
    ));
    return $ArrayList;
}

and the template:

<% loop $ArrayList %>$Text<% end_loop %>

// NOTE: ___::create() is the new ___() on steroids

Zauberfisch
  • 3,690
  • 15
  • 23
  • This is wrong. The ArrayData wrapping is not necessary. Items in the ArrayList can be simple associative arrays. – Neets Jun 21 '17 at 09:52
  • 1
    I'm afraid it is not. Yes, regular arrays will work, however I would strongly advise not to use them, as this is actually inconsistently handled and may result in different or even undefined behaviour in different SilverStripe versions. One example of this, which is still present in SilverStripe 4 alpha7, is https://github.com/silverstripe/silverstripe-framework/issues/2636 – Zauberfisch Jun 21 '17 at 14:54
  • 1
    Though I grant you this: for an individual developer working on individual projects, this bug will most likely never occur and thus using regular arrays will work. – Zauberfisch Jun 21 '17 at 14:59
7

Rather than creating a new ArrayData instance each time, you can just use $Me. So you would have:

public function ArrayList()
{
    $ArrayList = new ArrayList(array('this', 'is', 'a', 'test'));
    return $ArrayList;
}

And, in your template:

<% loop $ArrayList %>$Me<% end_loop %>

$Me refers to the current item in the loop. In this case, it'll be the strings in the array.

  • 1
    unfortunately this solution leads to inconsistent behavior in certain cases and thus is unreliable. I would advise against using this approach until the bug has been fixed. See https://github.com/silverstripe/silverstripe-framework/issues/2636 for further details. – Zauberfisch Apr 29 '14 at 14:05
  • That only matters if you want to then access fields. With straight strings, it doesn't make sense to have to construct an `ArrayData` for every item in the list. –  Apr 29 '14 at 22:24