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.

General Questions

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

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

nested dataobject in template


Reply

3 Posts   940 Views

Avatar
tv

11 October 2012 at 12:01pm Community Member, 44 Posts

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

13 October 2012 at 12:54am (Last edited: 15 October 2012 1:52pm), Community Member, 44 Posts

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

15 October 2012 at 1:57pm (Last edited: 15 October 2012 1:58pm), Administrator, 685 Posts

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 %>