I'm beginning to work on my first Craft CMS website. (I'm really excited!) I've read a ton of documentation and am getting my head around setting up a structure within the system.

The website will be fairly large, and the site structure a few levels deep.

For the IA, say I have:

/ (Home)
/about  (About Overview Page, contains information from all subpages)
/about/team (bios of team members)
/about/history (content page)
/about/contact (contact form)
/industries (overview of all industries, contains content from subpages)
/industries/medical (industry overview page, contains contact from about, featured documents, featured case study, etc)
/industries/medical/about (content)
/industries/medical/history (content)
/industries/medical/documents (content + documents)
/industries/medical/case-studies (content + case studies)

You get the point.

So, I believe that for the majority of the data (documents, case studies, portfolio items) I will set up channels to house that data. (Is that the way it should be done? Set up channels and then have a "Industry" select field where the admin can choose what industry the entry belongs to?)

How do I get this structure set up? Is it just a matter of adding templates into the corresponding /templates/ folders in the system?

I've gone into Admin > Sections and created an "Industries" section, and then I created entry types for: Content, Documents, Case Studies, Portfolio Items, Forms, etc. Will I basically use that index.html template in /templates/industries/index to route ALL of the requests across all subpages in that section? i.e. get the one part of the slug to determine the active industry, and then the second segment to determine what page and what template to show?

If so, then what role would the Entry Template have?

Am I going about this all wrong?

I think once I understand this piece of it, everything is going to click.

Thank you in advance for your help! Happy to clarify anything to help me get clarity ;)

UPDATE: Upon further reading, I think I'm getting it. The entries are really just containers for the data, the sections are a way of organizing that data. I just use routes to handle the site structure. Is that correct?


Lots of question so I'll describe how I would do it more or less. Ask if you want more info.

/ - single page type.

/about - single page type.

/industries - single page type.

/about/{slug} - structure page type (structure offers nested entries)

/industries/{slug} - structure page type

You cannot create /about entry within structure with slug like /about/{slug} - thats why /about is a seperate single page type page. Of course you can create single structure with {slug} as url - then /about and /industries could be created within structure section. Note: with many entries it is harder to handle in CP.

About structure would have following entry types:

  • bios

  • contentPage

  • contactForm

CP Section edit screen enter image description here

CP Entries: enter image description here about/_entry template would look like this:

{% extends "base_template" %}
{% block body %}
    {% switch entry.type %}
        {% case "bios" %}
            {% include "about/bios" %}
        {% case "contentPage" %}
            {% include "about/content_page" %}
        {% case "contactForm" %}
            {% include "about/contact_form" %}
    {% endswitch %}
{% endblock %}

or it could be (but I prefer first approach)

{% extends "base_template" %}
{% block body %}
    {% include "about/" ~ entry.type %} (filename == entry type)
{% endblock %}

Channel/structure sections can have multiple entry types. All of them use template defined by Entry Template - thats why we include other templates based on entry type.

/about, /industries single page template:

To fetch data from all subpages you can either hardcode it to fetch entries from section like this:

{%- set entries = craft.entries({
    section: 'aboutSection',
    order: 'postDate desc',
    limit: 20
}) -%}

{%- for entry in entries -%}
    <h1>{{ entry.title }}</h1>
    //use switch to display data specific to entry type
{%- endfor -%}

Or you can add entry field (lets call it subpages) to the page and display it like this:

{%- for entry in entry.subpages -%}
    <h1>{{ entry.title }}</h1>
    //use switch to display data specific to entry type
{%- endfor -%}

With field approach you can change content without changing the code.

Here is hybrid - use query when no entries assigned to entry field:

{%- set entries = entry.subpages %}

{% if entries.total() < 1 %}
    {%- set entries = craft.entries({
        section: 'aboutSection',
        order: 'postDate desc',
        limit: 20
    }) -%}
{% endif %}

{%- for entry in entries -%}
    <h1>{{ entry.title }}</h1>
    //use switch to display data specific to entry type
{%- endfor -%}

Similar industries section:

CP Section create page enter image description here

CP Entries: enter image description here


Industries Overview entry type template

Here you could query items like so:

{%- set entries = entry.chrildren -%}
{%- set entries = entry.chrildren.descendantDist(n) -%} n levels below entry
{%- set entries = entry.chrildren.type('content') -%} specific type of children
{%- set entries = entry.chrildren.type('content').with(['field', 'field']) -%} .with() helps reduce SQL queries

.children returns ElementCriteriaModel same as craft.entries so all methods here apply.

Or again you can add entry field and display specific children.


Q: In the case of the Medical > Portfolio being a single entry type WITHIN a structure, I'm assuming individual Portfolio Items would be housed within a Channel of their own?

Yes, that is one approach. To achieve this you would create a new section with URLs disabled (unless you want portfolio items to be accessible via URL - ex. separate page) like so:

enter image description here

Then you just query those items. Oh, I used Stucture instead of Channel - in addition to nested entries, Structure allows to reorder entries.

{% switch entry.type %}
    {% case "medicalPortfolio" %}
        {%- set entries = craft.entries.section('medicalPortfolioItemsSection') -%}
        {% include "industries/portfolio" with {"entries": entries} %}
{% endswitch %}

Important thing here is to create additional entry type per industry so you can query proper portfolio items. Also new section per industry. It is not good solution here because we duplicate things.

Another way is to use Matrix field to define portfolio item. This way you just use Portfolio entry type with Matrix field within Industries structure.

  • Wow, that’s a good and complete answer. I don’t really see a reason for an subpages Entries field, as a structure section already provides all the tools you need to reorder or show/hide individual entries (using the enable switch). – carlcs Jul 6 '17 at 10:11
  • @carlcs Thanks :) I agree enable switch can hide individual entries but you need to be aware that you disable both subpage and subpage content at the overview page. Entry field allows you to select subpages you want to display without disabling them. Since Steph Rose did not mention how she wants it to work I suggested more flexible approach. Other solution would be to modify overview template code to fetch flagged entries. Entry type would have Lightswitch field. It all depends on the project :) – Krzysztof Boduch Jul 6 '17 at 11:11
  • @KrzysztofBoduch This is an amazing answer. I know I was asking a lot. Structure was the hardest thing for me to wrap my head around, and it seems like there are quite a few way to use Craft. (I love that part of it.) So, to make sure I'm clear: in the case of the Medical > Portfolio being a single entry type WITHIN a structure, I'm assuming individual Portfolio Items would be housed within a Channel of their own? – Steph Rose Jul 6 '17 at 12:33
  • @StephRose please check UPDATE 2 – Krzysztof Boduch Jul 6 '17 at 15:16
  • @KrzysztofBoduch Are you saying that a new section per industry is bad design because it's duplicated, and that you'd create different entry types instead? Or that a separate section AND entry type is needed? I've started playing with the Matrix field. Pretty cool stuff and I know it's one of the big sellers of Craft. :) – Steph Rose Jul 7 '17 at 16:15

I would avoid setting up custom Routes whenever possible, since Craft already has a pretty sensible default routing behaviour: in my experience, just by using the standard folder/template structure you can do a lot of work. Problems arise when you need a custom template for a particular entry: in these cases you may have to add conditionals in your template or some system (maybe a 'customTemplate` field in your entry) to manage that.

  • Interesting. If you don't mind me asking, what has been a scenario where you've had to use a custom route -- you couldn't avoid it and you found it necessary? – Steph Rose Jul 6 '17 at 12:34
  • For example it can be used to rewrite a controller route - which can be quite messy - to a prettier URL. – gioppe Jul 6 '17 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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