Change positioning of aliased blocks

Permalink
It took me a while to figure out how to alias the same block on multiple pages, but now that I know how this feature works I use it all the time.

I do have a question, though... if I change the positioning of an aliased block on one page, how do I get it to change on all other pages where that block appears?

An example: I have a site with a right sidebar. On the page type, I inserted a couple of content blocks into the sidebar, and made them appear on all pages in the site by doing 'Set up on child pages...'. Now I want to add another block to the right sidebar, but not at the bottom - say, in the middle somewhere. I can edit the page type, add my new block, move it to the position I want, and do 'Set up on child pages...', but on child pages the new block always appears at the bottom. Any way around this? (other than repositioning the block manually on every page...)

Thanks in advance for any responses.

tomreitz
 
jordanlev replied on at Permalink Best Answer Reply
jordanlev
Unfortunately you can't. To me, this is the one glaring hole in Concrete5's otherwise perfect array of tools for setting up site content. Hopefully it will be fixed one day (but I wouldn't hold you breath -- I've mentioned this to the core team a couple of times and they don't seem to think it's an important issue --I guess it's just not something they've come across often).

:(
tomreitz replied on at Permalink Reply
tomreitz
Well that's unfortunate. My site has only 40 or so pages, so I guess I can do it manually. Imagine if a site had thousands of pages though... ugh.

Looking in the database, it seems that the assortment of blocks on a particular page is called a Collection (stored in the Collections table). To handle versioning of pages, there's a CollectionVersion table, which stores metadata about the when that version was created and by whom. The only place block position info is stored is in the CollectionVersionBlocks table, which ties block instances to a Collection version. (There's a cbDisplayOrder fields that seems to correspond to the ordering of my blocks...)

Maybe one of the devs wants to chime in, but I'm guessing that the problem is this: you have a sidebar with blocks A, B, and C, in that order [A B C]. This sidebar is the same on all pages (via the 'Set up on child pages..' feature). Now you add a block X between blocks A and B on just one page (maybe the home page) [A X B C]. Next you go to the page type and move block C between blocks A and B, and 'Set up on child pages'. On most pages, there's no problem [A C B]. But on the home page, is it [A X C B] or [A C X B]?

Anyway, thanks for the fast response Jordan.
jordanlev replied on at Permalink Reply
jordanlev
I know it totally sucks -- even with "just 40 pages" (it sucks even for 5 pages!)

The situation you bring up is one of the challenges that Franz (one of the core devs) mentioned.

I started writing out my thoughts on this, which follow -- I apologize if this is way too much info for you, but you really have me thinking about this again. If you can make it through the end and understand what I'm talking about, I'd really appreciate your feedback and thoughts on it...

So I have a few ideas for how to address this problem:

1) Use sensible defaults to deduce where things go. For example if you move a block to the top or bottom of its area, it always gets move to the top or bottom of its area on child pages (even if there are different blocks in it). If you move it in between other blocks, then on child pages where there are additional blocks between those, just slip it in under the top block of the one you put it between in page defaults. For situations where the child page's block order has been totally changed from page defaults, you either tell the user that they can't apply the change to that child, or that the change will overwrite the current position.

2) Consider all of the blocks in the page defaults to be "at the top" of their area. If you change the order in page defaults, all children pages have all of those blocks that are aliases of the page defaults moved to the top of their respective areas. So in a sense you have segmented each area into 2 halves: the top half is all of the blocks that are children of page defaults, and the bottom half is all of the blocks that are unique to that page and not in page defaults (or page default blocks that have been edited**).

3) Simply prevent any position changes in page defaults to be set up on children pages that have had their blocks moved or edited in any way from the defaults.

Either way, the re-ordering would be presented to the user similarly to the current "Setup on Child Pages" dialog -- a list of child pages is shown, and the user can check boxes next to each one they want to apply the positioning to. If the situation on the child page is such that it has been modified too much, then it will be greyed out or not available in the list.

Another challenge is figuring out what to do when a block is moved from one area to another (!!)

**It is important to note is that if a user edits a block on a child page, that block immediately becomes "orphaned" from the page defaults and is no longer considered a child of it (meaning that changing it on page defaults no longer effects the block on that specific page, and hence if this block positioning were ever added, it wouldn't apply either).
tomreitz replied on at Permalink Reply
tomreitz
Of the solutions you mention, #1 seems best to me (although the logic to implement it would be a beast!). I think #2 is bad because it would limit functionality. #3 might work... maybe when clicking "save positioning", the user could choose between #1 and #3...

Regarding what to do when a block is moved from one area to another, if there was a way to mark that block as edited, then your ** comment would apply (changing positioning of the block on the page default wouldn't do anything).

I'm just getting into developing for Concrete5 (working on a few packages), so I don't really feel comfortable diving into modifying the core code myself to implement something like this. Maybe in a few months...
DominicWhiteStudio replied on at Permalink Reply
DominicWhiteStudio
I just ran into this problem and got around it by making different content areas to the sidebar DIV of my theme template in the order I want them to appear.

My side bar now has three block areas: "sidebar" for the page-specific info, and two others named for what I want them for that I then populated with blocks from my page defaults.... (with an hr tag between them for separation)

[code]
<div id="leftsidebar">
<?php
$as = new Area('Sidebar');
$as->display($c);
?>
<hr />
<?php
$as = new Area('Sidebar Email');
$as->display($c);
?>
<hr />
<?php
$as = new Area('Sidebar Weather');
$as->display($c);
?>
</div>
[code]

The advantage of this is I was able to do it all just by changing my template page and reloading the blocks on my page defaults. I didn't have to change every single page. (Pasting the blocks from the concrete5 scrapbook didn't work, but I just copied the existing block html code into a txt file then pasted it back into new blocks that I place directly into the page default.)

I'm not a programmer, so if this method is going to cause problems, I'd appreciate it if someone more knowledgeable that me would let me know!
jordanlev replied on at Permalink Reply
jordanlev
This is a great solution, as long as you're okay with those areas you've set up. I actually don't have problems with the sidebar for sites where I really know what is supposed to be on each page (for example, many marketing sites for companies will have the contents of the sidebar spelled out in the design itself). Where I've run into problems is when the client has complete control over the content of the site and doesn't even really know what they want until they start playing around with it.

Anywho, there's also another solution that came out recently that works fairly well for most situations (not for every kind of block though, but still worth trying out):
http://www.concrete5.org/marketplace/addons/global-areas...
DominicWhiteStudio replied on at Permalink Reply
DominicWhiteStudio
I completely understand with not wanting to have clients control the side bar content at all... however I'm still new to Concrete5 and I just haven't got around to learning out how to hard code blocks in my theme yet!
jordanlev replied on at Permalink Reply
jordanlev
Are you designing a site for someone else or is this your own site that you'll be managing?

I think the way you did it is great -- no need to change that unless you run into problems in the future.
herrin replied on at Permalink Reply
herrin
They have to be dicks to think this is not an issue. Tell me what is the point of having a database driven system if not to make this type of thing possible? I am liking the C5 platform apart from a few rather large glaring oversights by the core developers.

Would the idea of global blocks containing a prearranged group of scrapbook blocks be so hard to implement?
jordanlev replied on at Permalink Reply
jordanlev
Hi Herrin,
You probably didn't mean for your comment to come across this way, but calling people nasty names doesn't really help anything. If you've built large/complex systems in the past surely you understand that sometimes you make decisions early on that make sense for one phase of a job but slowly become inappropriate as the environment changes (i.e. it gets used a lot more than you originally planned) and now those decisions don't fit the state of affairs so well. Or maybe your use cases aren't the same as someone else's. Voicing an opinion about potential changes to the system is very useful but if they are delivered in an inflammatory message then they will not be heard in the right way.

All that being said, there are a couple of solutions to this problem now. Both are free addons in the marketplace:
http://www.concrete5.org/marketplace/addons/scrapbook-display-basic...
http://www.concrete5.org/marketplace/addons/global-areas...
(the first one displays blocks from a global scrapbook, the second one displays blocks from an area on another page -- different UI's but the same end result).

There are some blocks that won't work well with these solutions, but most will. The big ones that have problems are the autonav block and the form block. If you use the free Ajax Form addon:
http://www.concrete5.org/marketplace/addons/ajax-form...
...this will solve the problem with forms. And there's a relatively easy modification you can make to the autonav block to fix that one -- edit this file:
YOURSITE/concrete/blocks/autonav/controller.php

Find this chunk of code:
function __construct($obj = null) {
   if (is_object($obj)) {
      switch(strtolower(get_class($obj))) {
         case "blocktype":
            // instantiating autonav on a particular collection page, instead of adding
            // it through the block interface
            $this->bID = null;
            $c = Page::getCurrentPage();
            if (is_object($c)) {
               $this->cID = $c->getCollectionID();
               $this->cParentID = $c->getCollectionParentID();
            }
            break;
         case "block": // block
            // standard block object

...and replace it with this code:
function __construct($obj = null) {
   if (is_object($obj)) {
      switch(strtolower(get_class($obj))) {
         case "blocktype":
           // instantiating autonav on a particular collection page, instead of adding
           // it through the block interface
           $this->bID = null;
           break;
         case "block": // block
           // standard block object
           $this->bID = $obj->bID;
           break;
      }
      $c = Page::getCurrentPage();
      if (is_object($c)) {

(if you use this fix be sure to click the little "View entire code block" links at the bottom-right of each code area to see the full chunk of code).

Hope that helps!

-Jordan
herrin replied on at Permalink Reply
herrin
Thank you for your detailed guidance on this issue. I am looking at the global blocks add-on now too.

Don't get me wrong. C5 is great. I am part of a web development company and they all love the platform.

Our current workaround is to go to the default pages for a particular set of page types and remove all the blocks from child pages and then to re-add them in the order that we want. Works but seems a little clunky considering this is a database driven system.

I apologise for my inflammatory remark (not aimed at anyone in particular). I do think this is a somewhat basic feature though and if solved in the core programming I think it could elevate C5 into realm of some of the more popular players in the cms field.

The thing is to get clear about the different audiences a platform has to appeal to and in this regard I can see your dilemma. However I don't think you would be alienating anyone by making things more user friendly and faster for both the developer and user.

Thanks again for the links and will follow up on these to see how they work.
Veronikan replied on at Permalink Reply
Veronikan
Thank you for the work-around! That's much better than editing 40 pages which in future will be in the hundreds.

I also think this should be a priority feature request for future releases.
magicyoda replied on at Permalink Reply
Hello,

What is the status in 2016 of this problematic? I'm also facing this same issue and will try the last workaround (remove all blocks and place them again).

Both proposed extensions are not supported anymore.

Is there a better solution to synchronise the position of aliased blocks on all childs based on the page type defaults?

Thanks!