Search code examples
phpconcrete5

Concrete 5 dynamically named areas


I have inherited a concrete 5 project and am debugging why certain 'areas' on the page do not show up the 'inline editing' feature.

The version is 5.5.1.

Essentially there is a page where it lists some items and each item has some div's to contain some information about each one, e.g name, description:

<div class = "description"></div>

The issue is that only one of the description elements is editable - I have worked out that this could be because the 'area' is name statically thus:

<div class = "description"> $a = new Area('Property Details'); $cont = Page::getByID($page->getCollectionID()); $regexMatchThis = $a->display($cont); </div>

So therefore there is only one area called 'Property Details' allowed to be editable. Am I ciorrect, and how can I name the area so that it reads the correct data but can be uniquely named so that it can be editable?

Help appreciated.


Solution

  • Pekka is correct, but I'm hesitant to litter the answer discussion with another (long) explanation.

    Areas are dynamic based on the name. Thus, "Property Details 1" is different than "Property Details 01".

    You could do something like:

    for ($i = 1; $i <= 10; $i++) {
       $a = new Area('Property Details ' + $i); 
       $a->display();
    }
    

    And you'd get 10 sequentially named "Property Details x" areas, from 1 - 10.

    Let's say you add content block to them. As long as they remain with the exact same names, then the blocks will work as expected. You could even change the first line to:

    for ($i = 10; $i >= 1; $i--) {
    

    In that case, you'd get the areas named sequentially downward (10, 9, 8...) and C5 would keep the content blocks in their original areas -- so they'd all be in reverse.

    But let's say you do:

    for ($i = 11; $i <= 20; $i++) {
    

    Now you get 10 areas (11, 12, 13...), and all are blank. The content blocks have basically disappeared. You can create new content blocks if you want. But then go ahead and put the original loop back in (1, 2, 3...). Your original content blocks are back -- just like before.

    This really long explanation just goes to show that C5 creates a block based on a name, and that name becomes the key. It can be anything. You can base it on the page name, or dynamically generate it, or whatever. You just can't change it once it's been created (if you don't want to "lose" the blocks).

    But... I'll agree with Pekka again here... you probably don't want to do this. Not knowing your goal, you're creating (or prolonging) a very brittle solution that's difficult to maintain. Pekka suggests creating subpages for each property, then you can use a page list block to "pull" the applicable attributes. Or, if you don't want to create separate pages, use Jordan's Designer Content block -- http://www.concrete5.org/marketplace/addons/designer-content/ . Have a single area ("Property Details"), and add a block for each property. Much easier to delete, reorder, etc.

    Edit to address Sphere's first two questions: Adding blocks to areas is really straightforward. As long as the areas don't have duplicate names, you click on it just like you've tried previously, and add a block. I'm not sure what block type your particular site needs -- that's specific to your site. It might just be a Content block, or maybe a Pagelist block with a particular template, where the previous developer set it up to "list" one page per block instance, per area (which would be REALLY weird, but you never know...). Or, maybe it's a block type created from the Designer Content block which I mentioned earlier. Poking around on the existing blocks should give you an idea. Also, I find that sometimes they write out some identifying ID in the HTML. So, the source is something like .

    As for your code sample: Yes, $cont is page. The code that Pekka and I provided ($a->display()) basically does:

    1. Initialize an area called 'Property Details' (or 1 or 2 or whatever). This is the key, as discussed.
    2. Display it, defaulting to displaying it "for" the current page. This is different than "on" the current page. It will always display on the current page... what you pass as an argument to ->display() is more like "the page that the area should be pulled from". So if you could theoretically pass $thePageObjectForPropertyOnMainStreet, and it would display that page's 'Property Details' area. Using $cont is unnecessary. As it creating it (it already exists). But... now that I think of it, that might be what he tried to do. $cont might have been a reference to individual property pages. Those pages might have an area called "Property Details", and this his loop serves to "pull the area" from those pages. But, $cont would have looked different. You can hardcode this by doing something like $cont = Page::getByID(x);, where x is the cID for a property page, which has an area called "Property Details". You can get the cID in the URL after you edit and save it.