Silverstripe - Looping over non-associative array in template
Asked Answered
S

3

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"?

Schroth answered 29/7, 2013 at 10:27 Comment(0)
P
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.

Proserpina answered 28/4, 2014 at 22:41 Comment(3)
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 github.com/silverstripe/silverstripe-framework/issues/2636 for further details.Wean
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.Proserpina
this doesnt work anymore. (ss4)Knar
W
17

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

Wean answered 29/7, 2013 at 10:58 Comment(3)
This is wrong. The ArrayData wrapping is not necessary. Items in the ArrayList can be simple associative arrays.Holliman
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 github.com/silverstripe/silverstripe-framework/issues/2636Wean
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.Wean
P
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.

Proserpina answered 28/4, 2014 at 22:41 Comment(3)
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 github.com/silverstripe/silverstripe-framework/issues/2636 for further details.Wean
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.Proserpina
this doesnt work anymore. (ss4)Knar
K
0

As @zauberfisch says this will generally work for app level code, here is what I'm using.

public function States(){      
    $ArrayList = ArrayList::create([
        ['Text' => "NSW"],
        ['Text' => "Qld"],
        ['Text' => "Vic"],
        ['Text' => "WA"],
        ['Text' => "SA"],
        ['Text' => "Tas"],
        ['Text' => "ACT"],
        ['Text' => "Distance"]       
    ]);           
    return $ArrayList;               
}    
Knar answered 20/9, 2023 at 12:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.