For a project I'm working on I have set up several channels that are related to each other. What the setup comes down to is the following:


|- News relations (news is a channel and news entries can be related to a project entry)
|- Gallery relations (gallery is a channel and galleries can be related to a project entry)
|- ... and more related content ...

Now I can visit the projects overview on the /projects path and a project entry on the /projects/{slug} path. The project entry page shows a short overview of the related content (i.e. 2 or 3 of the related items for the various channels), but will also contain a link to the full listing of all news items/galleries/etc of the requested projected.

Preferably I would have a url for these subpages to the project on a path like /projects/{slug}/news and /projects/{slug}/gallery.

How would I set this up? I've been looking around, but can't find any solution to this.

1 Answer 1


Two ways that this can be done is A) use a structure, or B) use custom routes.

Using a Structure with different entry types defined for the various sub-page types would probably be the most straightforward and flexible. The base of the structure would be projects (but could just as easily start above projects, if you also wanted to use it to generate your site nav). Your structure might look something like this:

/project1 (entry type: project)
   /news (entry type: projectNews)
   /gallery (entry type: projectGallery)
/project 2

In your projectNews template, you can access the 'project' entry through entry.parent and can retrieve the news related to the project using relatedTo():

{% set project = entry.parent %}
{% set projectNews = craft.entries.section('news').relatedTo(project) %}
{% for entry in projectNews %}
        {{ entry.title }}
{% endfor %}

The advantage of the structure is that: you can selectively add these pages to projects on a case by case basis; you can add additional content to the news or gallery pages as needed, in addition to the related content; and that it automatically generates the uri that your looking for.

The other option would be to create custom routes, using the project slug as one of the uri segments (i.e. projects/{slug}/news). The variable slug will be accessible in the templates and can be used to fetch the project using an Element Criteria Model, and the related content via relatedTo():

{% set project = craft.entries.section('projects').slug(slug) %}
{% set projectNews = craft.entries.section('news').relatedTo(entry) %}
{% for entry in projectNews %}
        {{ entry.title }}
{% endfor %}

The advantage here is that you don't need to generate those additional entries, if 'news' and 'gallery' will always be defined. And if you did need some customizable content for those pages, you could easily place that in the projects main entry.

For another example see this question regarding site structure.

  • Thank you for your answer. I'll check out these two options, at this point I'm tempted towards using option B.
    – Martijn B.
    Nov 13, 2014 at 8:16
  • It is worth noting that custom route templates can throw 404 errors for content where the route is inappropriate using {% exit 404 %}. So whilst the route always exists, if it isn't valid for certain content, then it can behave properly when somebody modifies the address bar in the browser.
    – Lea Hayes
    Nov 23, 2014 at 3:51

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.