Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

nested dataobject in template


Go to End


3 Posts   1926 Views

Avatar
tv

Community Member, 44 Posts

11 October 2012 at 12:01pm

I have a CatalogItem DataObject that has_many VinylSlots and VinylSlot DataObject has_many Thumbnails.

class CatalogItem extends DataObject {
static $has_many = array(
'VinylSlots' => 'VinylSlot'
)
}

class VinylSlot extends DataObject {
static $has_many = array(
'Thumbnails' => 'VinylSlotPhoto'
)
}

I have a Page on which I would like to loop through a filtered set of CatalogItems and get the VinylSlots' Thumbnails.

Here is what I have that is not working:

class SCBPage_Controller extends Page_Controller {
public function getReleases() {
$releases = DataObject::get('CatalogItem', 'ShoolChoirRelease = 1');
$covers = new DataObjectSet();
foreach($releases as $release) {
$covers->push(new ArrayData(
array(
'Vinyl' => new DataObjectSet($release->VinylSlots())
)
));
}
return $covers;
}
}

And in the template:

<% control Releases %>
<% control Vinyl %>
$Thumbnails
<% end_control %>
<% end_control %>

Any thoughts on how I can pull the urls of the VinylSlots Thumbnails using a function in the SCB Controller?

Thanks.

Avatar
tv

Community Member, 44 Posts

13 October 2012 at 12:54am

Edited: 15/10/2012 1:52pm

this is how I was able to get this to work. I used two DataObject::get call, so I imagine this may not be the most eloquent way to handle this. If anyone has any suggestions on how to refactor this, I'm all ears!

public function getReleases() {
        $releases =  DataObject::get('CatalogItem', 'ShoolChoirRelease = 1');
        $doSet = new DataObjectSet();
      
        foreach($releases as $release) {
            $id             = $release->ID;
            $slot          = DataObject::get('VinylSlot', 'CatalogItemID =' . $id );
            $thumb      = $slot->First()->VinylSlotThumb();
            $fullsize     = $slot->First()->VinylSlotFull();
            
            $doSet->push(new ArrayData(
                        array(
                            'Band'          => $release->ArtistName,
                            'CatalogNum'    => $release->CatalogNumber,
                            'CatalogTitle'  => $release->CatalogTitle,
                            'Format'        => $release->Format,
                            'Thumb'         => $thumb,
                            'FullImg'       => $fullsize
                        )
                    ));
        } 
        
        return $doSet;
    }

note that VinylSlotThumb() and VinylSlotFull() are functions on the VinylSlot class that grab associated Imgs:

public function VinylSlotThumb() {
            $covers = $this->Thumbnails(null,null,null,1);
            return $covers->First();
}

Avatar
Sam

Administrator, 690 Posts

15 October 2012 at 1:57pm

Edited: 15/10/2012 1:58pm

One thing I notice you got wrong in your first example was this:

array( 
'Vinyl' => new DataObjectSet($release->VinylSlots()) 
) 

It should be this:

array( 
'Vinyl' =>$release->VinylSlots() 
) 

Alternatively, you can just return $releases and then put <% control VinylSlots %> into your template. This would be the way that I would most likely do it:

class SCBPage_Controller extends Page_Controller { 
  public function Releases() { 
    return DataObject::get('CatalogItem', 'ShoolChoirRelease = 1'); 
  }
}

And in the template:

<% control Releases %> 
<% control VinylSlots %> 
$Thumbnails 
<% end_control %> 
<% end_control %>

In SilverStripe 3, you could follow the relation and therefore get the data without nested DataObject::get calls:

class SCBPage_Controller extends Page_Controller { 
  public function Vinyl() { 
    return CatalogItem::get()->filter('ShoolChoirRelease', 1)->relation('VinylSlots'); 
  }
}

Your template would then become:

<% loop Vinyl %> 
$Thumbnails 
<% end_loop %>