Some of my clients need to add what I would call "ad-hoc" pages to their sites. As many have pointed out, this is (a) somewhat contrary to the spirit/concept of EE channels and (b) when necessary, arguably best handled by the Structure module.

On a new project I'm considering skipping Structure and incorporating two channels: one called Pages and another called Sub-Pages. Both channels would have generic {main_content} and {sidebar_content} fields, but Sub Pages would have a {page_assignment} relationship field to subordinate the page to an existing Page.

How would you output a dynamic navigation of titles/links with unordered lists, adding active classes as appropriate? To save space, Sub Pages belonging to a Page should only be listed when that Page or sibling Sub Pages are active. In other words, you have to "click into" a Page to see its Sub Pages.

So if I'm on the Products landing page or the Products 1 sub page, the nav should look like:

    Product 1
    Product 2
    Product 3

About the Company


But if I'm on the About the Company landing page or the Our History sub page, it should look like:


About the Company
    About Our Team
    Our History

  • Can you not use the standard Pages module? That is designed for those ad-hoc static pages which don't fit into channel entries.
    – Ian Young
    May 9, 2013 at 20:18
  • The requirement for the client to edit the url slug seems like a deal breaker to me. I played with it for half a day and couldn't understand it. May 9, 2013 at 20:26

3 Answers 3


@James Right, I really do understand that argument, but at the same time the "streams of content" philosophy requires knowing quite a lot about content before it is ever created.

Yep, you're absolutely right there. Most EE sites I've made usually end up with a generic 'Pages' channel, but I always try to drill home that it needs to be for exceptional one-off circumstances. (I'm running Structure on one site and it's a complete mess because the client is defining their own IA. They probably like the power they have, but the site suffers).

For setting up a Pages channel I usually use the native Pages module and explain that by default their 'page' will be available at site.com/pages/[url_title] but that they can override/clean up this url to be whatever they like by completing the Page URI field. (There's an add-on somewhere that automatically fills in the Pages URI field with the url_title on save, but I can't find it at the moment)...

I create a generic Pages template (template group in fact), and point the Pages module's default settings for the pages channel to use that template, then I always hide the template selector in the publish screen (using Publish Layouts) so the client can't choose which template gets used.

Then 6 months later I come back and find 100s of 'pages' that should have been 'events' or 'conferences' or 'products' or anything else and I'm a little bit sick in my mouth.

  • Very helpful -- this matches my experience pretty well. It's part of the reason I had high hopes for Mojomotor (and now the latest slew of wiki-like, "no control panel" CMSs): in some cases it might make sense to completely embrace non-standardization and let the client create chaos as they see fit. It makes for an interesting design problem. But back here in the real world I guess we'll continue to create awkward hybrids of structured and ad-hoc channels. May 10, 2013 at 18:58

This seems to be a great role for NavEE. As you can see in my post (thanks for the link, BTW) I'm a fan of NavEE because it accomplishes much of the good stuff about Structure (easy nav menus) without abandoning the EE philosophy.

You could have a NavEE fieldtype associated with those two channels whereby the client could create nav links, and NavEE's template tags allow for the dynamic collapsing sub-menus you're looking for.


Ok, this is the closest I've gotten. It's pretty gross. The main bug so far is that when viewing the home page ({site_url}), the first top-level Page is "expanded," showing its sub-page links, even though you would think {segment_3} doesn't exist and therefore $active_parent should be empty.

Keep in mind my concept of parents/children is the opposite of the EE terminology for some reason.

        {!-- if we're on a sub_page, retreive and store its parent top-level page  --}
        <?php $active_parent = ""; ?>
        {exp:channel:entries channel="sub_pages" url_title="{segment_3}" limit="1" dynamic="no"}
        <?php $active_parent = '{page_assignment}{page_assignment:url_title}{/page_assignment}';?>

        {!-- begin loop of top-level pages --}
        {exp:channel:entries channel="pages" limit="99" dynamic="no"}

            {!-- store this entry's url_title --}
            <?php $this_title = "{url_title}";?>
            {!-- get its child sub_pages --}
            <?php unset($this_child_array); ?>
            {parents field="page_assignment"}<?php $this_child_array[] = "{parents:url_title}"; ?>{/parents}

        {!-- show top-level pages --}
        <li <?php if ( ("{segment_3}" == "{url_title}") || (in_array("{segment_3}", $this_child_array)) ) { ?> class="primary-active"<?php } ?>>
            <a href="{comment_url_title_auto_path}">{title}</a>

            {!-- show any sub-pages under each top-level page if (a) that top-level page is active or (b) one of its sub-pages is active  --}
            <?php  if ( ("{segment_3}" == "{url_title}") || ($active_parent == "{url_title}") )  {  ?>
            {parents field="page_assignment"}
                {if '{parents:count}' == '1'}<ul>{/if}
                    <li{if "{segment_3}" == "{parents:url_title}"} class="sub-active"{/if}><a href="{parents:comment_url_title_auto_path}">{parents:title}</a></li>
                {if '{parents:count}' == '1'}</ul>{/if}

                <?php } ?>




  • My first thought is that Structure is a much better fit here. In comparison it keeps PHP out of your templates, keeps them cleaner and easy to manage and is better suited to the specific task at hand. It's only against the nature of EE when you're dealing with dynamic content (content which isn't a one-to-one relationship with a page). In the case of a single page for a single URL it is static and exactly what Structure aims to cater for. Your client would also have a nicely presented tree view for easy drag and drop arrangement.
    – Ian Young
    May 9, 2013 at 20:40
  • I'm beginning to think you're right. The major problem with this two-channel idea is that the standard list of entries completely obscures which Sub Pages belong to which Pages. May 9, 2013 at 20:42
  • Holy Moses...! Foregoing the Structure module is a noble goal in my opinion (as you can see from my comments in the blog post you linked to). However, all you're doing here is recreating Structure's functionality with some convoluted template code. Instead you should take the opportunity to rethink the IA. Start by forgetting that you're creating a website and instead define your content types in a more granular way. In my opinion even the largest organisations have no excuse for a dedicated 'our history' page. Your content items are not 'pages' and definitely not 'sub-pages'. May 9, 2013 at 20:44
  • You should be able to do it with relationships but you'd be relying on your client to set that relationship (correctly) with each page entry and also to ensure the URL structure is correct. You could also use something like Freebie to try and help out in the URL structure but overall it's far more complicated than Structure in comparison.
    – Ian Young
    May 9, 2013 at 20:46
  • @James Right, I really do understand that argument, but at the same time the "streams of content" philosophy requires knowing quite a lot about content before it is ever created. I don't think it's crazy for a client to want ad-hoc page/section. FWIW, this site is for an academic society; channels will include blog, articles, and newsletter, but what I'm trying accommodate are pages for infrequent conferences: it seems a difficult battle to shoehorn information like "travel details," "schedule," "registration," and "accommodation," into rigid pre-defined EE fields. May 9, 2013 at 20:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.