Jump to content

"blocks" or "slots", with inheritance


mindplay.dk
 Share

Recommended Posts

Just starting to look into PW, and really liking the concept so far.

I think this question may have been asked, possibly here or here - but maybe not quite the same issue.

I'm looking for a way to do a "portal"-style block-system, but with inheritance. Drupal doesn't really do this (or doesn't do it well) and I'm not sure it's quite what was asked for in those other two threads, so let me try to explain.

Basically, I want to allow the content administrator to place arbitrary blocks in, say, a left and right sidebar.

These blocks could be anything from just a title and some static HTML, or something more complex like a Google Map or some kind of calendar or "social" widget.

Blocks should "fall down" through the hierarchy (perhaps optionally) - meaning if you put a block on a parent page, child pages should inherit it automatically.

The blocks should be prioritized, perhaps using a simple "weight" or "priority" number for sorting.

The point is not to compose pages or build articles (such as is done in Concrete5, for example) - but something more along the lines of what StackBox CMS does, where content-locations ("positions" or "slots" or whatchawannacallit) can be shared... somehow ;-)

Make sense?

Is there a sensible (performant) way to approach this in PW?

I'm thinking of one possible approach, which is to have these "blocks" actually be hidden "pages" with various templates, one for each kind of "block" or "widget" - located under a pair of hidden "left column" and "right column" pages in the hierarchy, which would determine the "block" order/priority by simply sorting them under these two parents. The page-templates can simply use the API to fetch the list of "block pages" for reach column, and render each of them in order.

What I can't figure out is how you would achieve the "inheritance" effect - blocks "falling down" to subpages, based on the page-hierarchy itself. One idea that comes to mind, is to use tags - so for instance, if I tag a page with "advertising", any "block page" tagged with "advertising" would be fetched and displayed.

To find inherited tags, however, I would have to actually walk up the page hierarchy and look for additional tags for which to query blocks. I suppose that would result in more overhead the deeper the page is nested - so maybe that's not a good idea?

Can you think of better way (or more in tune with the "PW mindset") to approach this?

Thank you for making this CMS available! I'm pretty excited about this, and I have a feeling this might be the (sane) Drupal-alternative I've been waiting for! ;-)

Link to comment
Share on other sites

Hm, i think i would approach this like this:

  • Create all your blocks as children of a "Blocks" page (this page can be wherever you want on the pages tree).
  • The blocks can have different templates, and should be not visible on site.
  • Create two fields with Type "Page". One named "left" and one named "right". Make them "multiple pages" and set the "Parent of selectable page(s)" to "Blocks".
  • Add those two fields to the templates of the pages where you want the sidebars.

Now anyone editing those pages can add the blocks to any of the sidebar fields.

You can render them like this:

echo "<ul id='sidebar-left>";
foreach ($page->left as $block) {
echo "<li class='{$block->title}'>";
$block->render();
echo "</li>";
}
echo "</ul>";

For the inheritance, you can iterate all the ascendant pages, and check if they have any blocks. If they do, and if they are not on your array already, prepend them to it.

$left = $page->left; // all the blocks from this page

foreach ($page->parents as $parent) { // all the parent pages down to the root
foreach ($parent->left as $block) { // all the blocks on each parent page
	if (!$left->has($block)) {
		$left->prepend($block); // if this ancestor has a different block, prepend it
	}
}
}

// now we can do the same as above but with all blocks since the root page (not repeated)

echo "<ul id='sidebar-left>";
foreach ($left as $block) {
echo "<li class='{$block->title}'>";
$block->render();
echo "</li>";
}
echo "</ul>";

Just a rough draft to give the idea. Not tested (and broken for sure) and not considering lots of aspects, like checking if fields exist for instance.

Link to comment
Share on other sites

That sounds reasonable, definitely gives me something to go on, thanks!

Perhaps better would be an extension of the page field-type, adding UI-level support for sorting and inheritance?

Do you think that would be meaningful, or would I be swimming against the current?

Link to comment
Share on other sites

Perhaps better would be an extension of the page field-type, adding UI-level support for sorting and inheritance?



The page fieldType already allows you to sort by dragging. Just choose the option "pageListSelectMultiple" under "input field type" on the "input" tab.
As for inheritance, I think it should be more clear what you pretend before deciding the method, But for what I understand, it would make more sense to do it automatically on the template.
Link to comment
Share on other sites

I know you can sort pages in a single list - but that doesn't account for sorting when blocks can be inherited from parent nodes. You need a priority/weight, so that parent nodes can add blocks both before or after page-specific blocks. At least that's how block-systems traditionally work.

Keep in mind, the priority is not specific to the block "types" (templates) - you could have a "static HTML" block for instance, used in different places, with different priority...

Link to comment
Share on other sites

Well the great thing about PW is your driving the output. Look at your template. It can pull content in from anywhere via the API. You can add whatever fields to a template you need, then write the logic using standard PHP and the easy to leverage PW API. So rendering could be simple or more complex based on your business needs.

Sometimes the hardest part a flexible framework is deciding what your logic needs to be rather than implementing it. Look at code examples sprinkled through the forums and the API and PW will start to shine before your eyes.

  • Like 1
Link to comment
Share on other sites

Very true, and these are the main reasons I became interested in PW to begin with.

This is not exclusively an issue of rendering though - inheritance rules, and how the content manager (person) experiences this, that's what I'm trying to figure out. Here's a quick illustration of a block-based UI we had in a CMS I used to work on:

https://docs.google....6mfI/edit?pli=1

One idea that just occurred to me is this: instead of just "fall down" (enable inheritance) on a block-instance, it could have two options: "fall down before" and "fall down after", so that parent pages can control whether inherited blocks appear before or after child-pages. Then the drag-and-drop sorting might work - you wouldn't need the priority number anymore...

(PS: smilies do not work well on this forum - why do I get a suprised-looking smiley every time I insert a happy-face?)

Link to comment
Share on other sites

If what you find in PW using page references and some simple logic of inheritance, maybe using checkboxes is not an option (also ui wise), there's no way to do this out of the box without getting your hands dirty. PW isn't designed to do this very easy. Using page reference won't give you all you want but at least some way. If your block inheritance concept demands functionality that is not there you'll have to code it. And I can imagine, depending what you exactly need, that it would require a lot of complex coding. But maybe I'm wrong :D

Personally I can't think of a way such a system would be easy to implement. Also it would have to be dead simple for editors to grasp it and don't lose control. My experience with such systems is like with inheritance of access control, which can get out of hand quickly. :)

Link to comment
Share on other sites

All of our clients loved it - it was one of the most celebrated features of our CMS.

And I like getting my hands dirty! I've already been trawling through the innards of PW to see what makes it tick. I'm never quite happy having to accept abstractions that "just work" - every abstraction has it's limitations, and it helps me use a tool more efficiently if I can understand what's going on underneath the skin.

And I'm happy to say, PW is a lot more transparent and easier to understand than most CMS I have examined!

Link to comment
Share on other sites

What about using repeaters, where one field is "fall down"? It doesn't sound too difficult concept to me. Then there might be other selection to put it "up" or "down" of other blocks there might be on deeper pages.

Our old cms supports similar feature, although the configuring part of which blocks are "falling down" is done by site builders.

Link to comment
Share on other sites

I think you can do it pretty easily with what's there. As already discussed. I don't think there's much performance issues with the approach you mentioned. You could even use markup cache if you got thousand and thousand of pages (PW is very performant). PW is designed to work very performant using page references and inheritly check upwards the page tree, this is where PW excels using the hirachy approach.

It would be easily possible with certain modules (ie fieldtypes) to list selected block from a page all up to the root and list them depending if they're falldown or not. There would be some trickery to it UI wise but I can imagine some simple setup.

Nonetheless we are here to help and give hints. It's always nice to see what other people come up with.

Link to comment
Share on other sites

The term "block" implies generated output or some understanding of what the final output is. PW is meant to be totally markup and output independent so there is no concept of anything relating to generated output. It may be web-based, but the content it's managing might not be. It's the opposite of something like Drupal. I'm not saying the other systems have the wrong approach, because there are benefits and drawbacks to different approaches. But I've been working on this blog profile for ProcessWire the last couple of days and my mind is entrenched in blocks at the moment. :)

I'm not sure if this is exactly what you are trying to achieve, but what you guys are describing sounds kind of similar to the "widgets" sidebar in the blog profile. There is a multi-page reference field called 'widgets' on the homepage. You select (asmSelect) from different widgets (pages) that you want to appear in the sidebar (i.e. Recent Comments, Recent Posts, Twitter Updates, etc.), and then drag them in the order you want them to appear. All the pages in the site inherent these widgets. When other pages in the site have their own 'widgets' field, it gets prepended to the list of widgets inherited from parent pages. Though I'm thinking about making it override rather than inherit, as I'm just trying to find the easiest to understand solution for new users. But regardless of where it ends up, it was pretty easy to setup:

// inherit and append widgets
$widgets = $page->widgets;
foreach($page->parents as $parent) {
if($parent->widgets) $widgets->add($parent->widgets);
}

// output widgets
foreach($widgets as $widget) {
echo $widget->render();
}

post-2-0-82940300-1339191373_thumb.png

post-2-0-96943100-1339191379_thumb.png

I'm guessing this is still different than what you guys are talking about, but figured it might at least add to the conversation since it sounded somewhat similar to what's already been mentioned.

  • Like 1
Link to comment
Share on other sites

That looks workable, probably fine for most sites. If I need something more complex, maybe I'll spend more time on this, but for the moment I don't feel like I'm missing anything... I had a chance to really dig in today, and I'm very, very impressed with what I've seen so far! :)

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...