Jump to:

5098 Posts in 1518 Topics by 1115 members

Customising the CMS

SilverStripe Forums » Customising the CMS » Inheriting widgets

Moderators: martimiz, Howard, Sean, Ryan M., biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 2543 Views
  • Anonymous user
    Avatar
    Community Member
    1 Post

    Inheriting widgets Link to this post

    Hello, I needed the functionality to inherit widgets from parent pages [1]. The one I came up with works, but seems a bit too hackadoodle for my own taste. Is there any "Right Way" solution for it?

    Thanks in advance,
    N.

    [1] NB: The point was to inherit widgets while still being able to add new ones, ie. a child page has all the parent widgets, plus a number of its own.

    The essential part is the following:

          static $has_one = array(
             'Widgets' => 'WidgetArea'
          );
          
          private $sidebar = null;
          
          public function Sidebar($num_widgets = null)
          {
             // return cached sidebar
             if($this->sidebar)
                return $this->sidebar;

             // collect widgets
             $widgets = new DataObjectSet();

             // add widgets of this page
             if($pageWidgets = $this->Widgets())
                $widgets->merge($pageWidgets->Widgets());

             // is the sidebar empty?
             $empty = ($widgets->Count() == 0);

             // check whether to get the parent sidebar
             $inherit = $empty ? ($this->InheritSidebar != 'Never') : ($this->InheritSidebar == 'Always');

             // inherit sidebar
             $parent = $this->getComponent('Parent');
             if($inherit && $parent && ($parentSidebar = $parent->Sidebar()))
                $widgets->merge($parentSidebar->Widgets());

             // get range of sidebar
             if($num_widgets)
                $widgets = $widgets->getRange(0, (int)$num_widgets);

             // return new sidebar
             $this->sidebar = new WidgetArea();
             $this->sidebar->Widgets()->merge($widgets);
             return $this->sidebar;
          }

    The full thing is here.

  • joshy
    Avatar
    Community Member
    57 Posts

    Re: Inheriting widgets Link to this post

    Hiya,

    Not sure this is the 'right' way but it certainly works with a lot less code!

    If the page you are viewing has widgets, it will use them. If it doesn't have any, it will try use the parent's widgets. If the parent has none it will use the widgets of the Homepage (URL segment = 'home').

    This presumes you call $Sidebar in the template and that you have set the $has_one like so:

    $has_one = array('WidgetArea' => 'WidgetArea');

    function Sidebar()
    {
    if ($this->WidgetArea()->Widgets()->Count())
    {
    return $this->WidgetArea();
    }
    else if ($this->parent()->exists() && $this->parent()->WidgetArea()->Widgets()->Count())
    {
    return $this->parent()->WidgetArea();
    }
    else
    {
    $home = DataObject::get_one("Page", "URLSegment = 'home'");
    return $home->WidgetArea();
    }
    }

    I apologise in advance if this has syntax errors - I am not near a SS install to test.

    Cheers,

    Josh

    ps: my indentations are not showing. Grr...

  • Anonymous user
    Avatar
    Community Member
    1 Post

    Re: Inheriting widgets Link to this post

    That code surely does the trick

    In fact, I had a very similar one before - my problem with it was just that I could not inherit widgets while still being able to add new ones for the children.

    I needed this functionality for a catalog type of page, where categories could have a "Featured Product" widget. As you descend down the category tree, I wanted the featured products to accumulate.

    I really should have added that to the initial post -- did that now.

  • Anonymous user
    Avatar
    Community Member
    1 Post

    Re: Inheriting widgets Link to this post

    FYI, there was a bug in the version. I put the corrected version up.

  • joshy
    Avatar
    Community Member
    57 Posts

    Re: Inheriting widgets Link to this post

    Something like this should work (untested, sorry - again, not at near a Silverstripe install):

    function Sidebar()
    {
       // Create a new object
       $widgets = new DataObjectSet();

       // Push this page's widgets into it
       if ($this->WidgetArea()->Widgets()->Count())
       {
          $widgets->push($this->WidgetArea());
       }
       // Push the parent widgets into it too
       if ($this->parent()->exists() && $this->parent()->WidgetArea()->Widgets()->Count())
       {
          $widgets->push($this->parent()->WidgetArea());
       }

       // ** You could potentially get the parent's parent or the homepage's or whatever too...

       // Uncomment the debug line to show the contents of the widget variable (so you know what to reference in the template)
       // Debug::show($widgets);
       return $widgets;
    }

    You'd then call this as a <% control Sidebar %> in your template and loop through the values (as shown in the Debug::show - currently commented out).

    I hope this helps!

    Cheers,

    Josh

  • Anonymous user
    Avatar
    Community Member
    1 Post

    Re: Inheriting widgets Link to this post

    That's brilliant, thanks for sharing!

  • joshy
    Avatar
    Community Member
    57 Posts

    Re: Inheriting widgets Link to this post

    It's alright - I've spent the last few weeks messing around with similar things and it did my head in - glad I can share my knowledge and make your life a bit easier .

    Cheers,

    Josh

  • Anonymous user
    Avatar
    Community Member
    1 Post

    Re: Inheriting widgets Link to this post

    You always recognize the good solutions by their simplicity -- the only thing I'd change is that I'd create the DataObject set, push the page widgets in, and then merge it with the parent sidebar. That should automatically inherit further up the tree. I'll incorporate this in the next days and post the result here, for reference.

    2543 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.