Search code examples
templatesvariablesgroupingsilverstripehas-one

Silverstripe Grouped List DataObjects - get variable from has_one in template


I'm struggling to get a variable in a template which contains a GroupedList of DataObjects that have a has_one relation to another DataObject.

Example: I have the DataObject Team belongs to one region. When I get a GroupedList of the teams, grouped by the RegionID, I can't figure out how to access the Region.NAME in the template.

class Region extends DataObject {
private static $db = array (
    'NAME'    =>  'Varchar(128)',
    'INFO'    =>  'Varchar(128)',
    'PUBLIC'  =>  'Boolean'
);

public static $has_many = array(
    'Teams' => 'Team'
 );
}

class Team extends DataObject {
private static $db = array (
    'NAME'   => 'Varchar(255)',
    'LEAGUE' => 'Varchar(255)',
    'SORTNO' => 'Int'
);

 public static $has_one = array(
    'Region' => 'Region'
 );
}

class TeamRegionPage extends Page {
public function getRegionGroupedTeams(){
    return GroupedList::create(Team::get()->filter(array('PUBLIC' => 1))->sort('RegionID, SORTNO'));
}
}

TeamRegionPage.ss

<% loop $getRegionGroupedTeams.GroupedBy(RegionID) %>
<h2>Region name from has_one here: {$Region.NAME}</h2>

<% loop $Children %>
    $NAME<br>
<% end_loop %>

$Region.NAME is not working in the template and I tried a few other things. I have the feeling the solution is quite obvious but I can't see it and I'm stuck.


Solution

  • As a workaround you can grab the first element of the current group's elements (aka $Children) and check the current region like this:

    <% loop $getRegionGroupedTeams.GroupedBy(RegionID) %>
        <h2>Region name from has_one here: 
            <% with $Children.First %>
                $Region.NAME
            <% end_with %>
        </h2>
    
        <% loop $Children %>
            $NAME<br>
        <% end_loop %>
    <% end_loop %>
    

    Sidenote: please name your '$db` fields more like the standard, 'CamelCase' instead of 'UPPERCASE'.