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   1030 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, 685 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 %>