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 %}
<article>
{{ entry.title }}
...
</article>
{% 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 %}
<article>
{{ entry.title }}
...
</article>
{% 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.