How to display many_many objects in page template in Silverstripe
Asked Answered
G

3

5

Our site has an object called "TrailNotice" which has a many_many relationship with the page type "TrailSection".

class TrailNotice extends DataObject {

  private static $many_many = array(
    'TrailSections' => 'TrailSection'
  );

This allows a single TrailNotice to be applied across multiple TrailSections via checkboxes in the CMS:

$fields->addFieldToTab('Root.Main', new CheckboxSetField('TrailSections', 'Applies to which trail sections?', DataObject::get('TrailSection')->map('ID', 'Title')));

How do I display the TrailNotices attached to a TrailSection in the TrailSection page controller?

I started with the following code:

class TrailSection_Controller extends Page_Controller {

  public function TrailNotices(){
    $TrailNotices = DataObject::get('TrailNotice');
    return $TrailNotices;
  }

But this will get all TrailNotice objects. How do I filter them so only TrailNotices attached to the TrailSection are displayed?

Granjon answered 15/4, 2015 at 1:16 Comment(0)
P
7

You need to define a many_many on both ways, then you can access it from both sides. One side has a $many_many

class TrailNotice extends DataObject {

  private static $many_many = array(
    'TrailSections' => 'TrailSection'
  );

on the other side you have to define $belongs_many_many

class TrailSection extends DataObject {

  private static $belongs_many_many = array(
    'TrailNotices' => 'TrailNotice'
  );

Then in your template you can just call the relation list and loop over it:

<% loop $TrailNotices %>
    $Title
<% end_loop %>

See infographic for all possible relations (thanks to @nightjar for providing the graphics).

Pascoe answered 15/4, 2015 at 7:26 Comment(0)
Y
3

You have to implement a $belongs_many_many into your TrailSection model, something like that:

class TrailSection extends DataObject {

  private static $belongs_many_many = array(
    'TrailNotices' => 'TrailNotice'
  );

}

Then you can simply loop over $TrailNotices into TrailSection.ss template, without doing anything into your controller:

<% loop $TrailNotices %>
    $Title<br>
<% end_loop %>

You can check the Mentor sample in Stephen's link Dataobject Relationship Management

Yingyingkow answered 15/4, 2015 at 7:35 Comment(0)
B
0

SilverStripe stores many_many relations RelationList that can be access on the object using $this->RelationName() (in this case $this->data()->TrailNotices()). The RelationList is a subclass of DataList so you can treat it a lot like a DataObject::get() for filtering the list.

class TrailSection_Controller extends Page_Controller {

  public function TrailNotices(){
    $TrailNotices = $this->data()->TrailNotices();
    return $TrailNotices;
  }

There is more information about SilverStripe's ORM and DataObject Relations in the help section Dataobject Relationship Management and (newer content) SilverStripe Lessons

Bainbridge answered 15/4, 2015 at 1:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.