5098 Posts in 1518 Topics by 1115 members
|Go to End|
1 August 2009 at 12:58pm Last edited: 4 August 2009 2:18am
Hello, I needed the functionality to inherit widgets from parent pages . 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,
 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
// collect widgets
$widgets = new DataObjectSet();
// add widgets of this page
if($pageWidgets = $this->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()))
// get range of sidebar
$widgets = $widgets->getRange(0, (int)$num_widgets);
// return new sidebar
$this->sidebar = new WidgetArea();
2 August 2009 at 10:48pm Last edited: 2 August 2009 10:49pm
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');
else if ($this->parent()->exists() && $this->parent()->WidgetArea()->Widgets()->Count())
$home = DataObject::get_one("Page", "URLSegment = 'home'");
I apologise in advance if this has syntax errors - I am not near a SS install to test.
ps: my indentations are not showing. Grr...
4 August 2009 at 2:17am Last edited: 4 August 2009 2:19am
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.
4 August 2009 at 8:43am
FYI, there was a bug in the version. I put the corrected version up.
4 August 2009 at 9:49am
Something like this should work (untested, sorry - again, not at near a Silverstripe install):
// Create a new object
$widgets = new DataObjectSet();
// Push this page's widgets into it
// Push the parent widgets into it too
if ($this->parent()->exists() && $this->parent()->WidgetArea()->Widgets()->Count())
// ** 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)
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!
4 August 2009 at 9:51am
That's brilliant, thanks for sharing!
4 August 2009 at 9:57am
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 .
4 August 2009 at 10:01am
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.
|Go to Top|