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, Ed, biapar, Willr, Ingo, swaiba

nested dataobject in template


Go to End
Reply


3 Posts   1441 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 %>