Jump to:

22977 Posts in 11806 Topics by 2826 members

General Questions

SilverStripe Forums » General Questions » Templates - Accessing an object within an object

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

Page: 1
Go to End
Author Topic: 210 Views
  • Double-A-Ron
    Avatar
    Community Member
    599 Posts

    Templates - Accessing an object within an object Link to this post

    So I have a TestimonialPage, which has Testimonial dataobject as a has_many relationship. The Tesitmonial also has a Tour page type as a has one relationship. This Tour page type already exists.

    TestimonialPage.php

    class TestimonialsPage extends SmartPage {

    ...
       static $has_many = array(
          'Testimonials' => 'Testimonial'
       );
    ...

    }

    Testimonial.php

    class Testimonial extends DataObject {
    ...
       static $has_one = array(
          'Image' => 'Image',
          'TestimonialsPage' => 'TestimonialsPage',
          'Tour' => 'Tour'
       );
    ...
    }

    On the TestimonialPage template, I am looping Testimonials and displaying them. Works fine. Until I attempt to access any of the properties in the linked Tour object:

    TestimonialPage.ss

    <% if Testimonials %>
          <% control Testimonials %>

    $Tour.Title // Doesn't display anything

    <% end_control %>
    <% end_if %>

    Is that even possible? There is no relationship linking to the Testimonial object from Tour, as it's rather optional.

  • Bereusei
    Avatar
    Community Member
    94 Posts

    Re: Templates - Accessing an object within an object Link to this post

    Did you try this?:

    <% if Testimonials %>
    <% control Testimonials %>

    <% control Tour %>
    $Title
    <% end_control %>

    <% end_control %>
    <% end_if %>

  • Double-A-Ron
    Avatar
    Community Member
    599 Posts

    Re: Templates - Accessing an object within an object Link to this post

    Cheers for the reply mate.

    I did think about that, but I was worried about load, as I would be using that control block 6-7 times in various locations.

    On top of that, I later realised that some of these Tour objects are VirtualPages, and hence not returning true data of the ContentSource. (this may be a 2.4.5 way of thinking, I have no idea if 2.4.11, which I just upgraded to, fixed that issue since I found another solution)

    So I created a static helper method to work this out for me:

    TourAdapter.php

    class TourAdapter extends ViewableData {
    public static function getRealTour($TourID = null) {
          
          $object = DataObject::get_by_id("SiteTree", $TourID);

          if($object->ClassName == "VirtualPage") {
             $realId = $object->ContentSource()->ID;
             return DataObject::get_by_id("SiteTree", $realId);
          } else {
             return $object;
          }
       }
    }

    Then, I created a getTour method in the Testimonial DataObject:

    Testimonial.php

    class Testimonial extends DataObject {
    static $cachedTour = null;
       
       public function getTour() {
          
          // Only call the helper once. Store in object state for later use
          if(is_null(self::$cachedTour)) {
             self::$cachedTour = TourAdapter::getRealTour($this->TourID);
          }
          
          return self::$cachedTour;
       }
    }

    Note that it only calls the helper once. And everything is perfect in the template when I call $getTour.Title etc. Right withing the <% control Testimonials %> loop.

    Although I am wondering if I just re-invented the wheel after your suggestion. I really have no idea on load if I call <% control Tour %> multiple times, or if it would sort out the VirtualPage's content source. Haven't had time to test.

    But thanks

    210 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.