23

I am using a structure for all of my site's pages (single pages and channel index pages). The structure settings are as follows:

URL for Top-Level Entries:
{slug}

URL for Nested Entries:
{parent.uri}/{slug}

Entry Template:
_pages/_entry.html

Additionally I set up multiple entry types for the structure to relate the pages with individual templates (basically as described in the FAQs). This is my _entry.html:

{% include '_pages/_types/' ~ entry.type %}

This all works great for me [*], but now I'd like to further improve the template setup by adding my site's home page to the structure, too. With a single section I can simply trigger the option "this is the home page" in the section's settings, but how can I tell an entry of my pages structure to be my home page?

[*]: I can generate my site's main navigation from this structure (nice!) and all channels' index pages have entry slugs now, which is incredibly helpful in a multi-lingual Craft setup, if you want to translate your slugs.

  • 1
    I think this is a great question, and I'm slightly bummed that it hasn't been answered yet. If it's not possible, perhaps it's worthy of an official feature request. If a single can be set "as the home page", why not a structure page? – Lindsey D Jul 30 '14 at 2:57
31

This isn't documented, so it's subject to change:

When you set a Single to be the homepage, its slug is automatically set to __home__.

If you want your homepage to be part of a Structure, rather than a separate Single, you can set the slug of a Structure entry to __home__, which makes it act as the site's homepage and gives it that little Home icon in place of its slug in the structure view.

  • Yep just remember to untick the box on the default single that says "This is for the homepage" – John Macpherson May 28 '15 at 14:26
  • Coming across this and checking, the slug for the homepage appears to be homepage currently. – Marty Aug 11 '15 at 5:26
  • 3
    Technically, the actual slug can be whatever you want. The URI must be __home__. But, unless you want to open up the db and edit those values separately, you would probably be editing both together via the slug input. – Michael Rog Aug 11 '15 at 13:20
  • 2
    This tip is absolutely brilliant. I just stumbled across it, and it works like a charm! – Lindsey D Feb 2 '16 at 5:46
  • 1
    @JCharette In my setup, the homepage is a sibling of the other first-level pages on the site, so it doesn't need to have any children. I recommend this approach. – Michael Rog Apr 12 '17 at 8:01
14

The "this is for the homepage" button available on single sections does two things for you, when you navigate to the home page's URL:

  • it populates the entry variable with the single's entry model
  • it loads the template spezified in the single's CP settings

.

Actually nothing you can't do manually with your home page's index.html:

{# Replace the default `entry` variable with the home page's entry model #}
{% set entry = craft.entries.section('pages').id('1').first() %}

{# Load the home page's template from the "pages" structure #}
{% include "_pages/_entry" %}

_pages/_entry.html further includes the template partial designed for the entry type I assigned my home page to:

{# Load the designed template for this entry's entry type #}
{% include '_pages/' ~ entry.type %}

This is all you need to replicate the "this is for the homepage" button behaviour for a structure entry. Additionally you might want to exclude the home page from your navigation menu for example. Again use the id or slug parameter on the ElementCriteriaModel:

{# Get top-level entries in pages structure (exclude home page)  #}
{% set pages = craft.entries.section('pages').id('not 1').level(1) %}

.

Thanks again to Marion, her answer pointed me in the right direction. I added this answer, because her configuration is a bit spezific and rather complicated.

  • 1
    This is a great answer, but wouldn't '/homepage/{slug}' now be part of the uri for all subpages? I would think you would also need to add a custom route that re-maps uris to remove the 'homepage' segment. – Douglas McDonald Feb 22 '15 at 19:42
  • Nope @Douglas, "Home" could go anywhere in my structure, as it is excluded from the nav loop. So pages like "About" and "Contact" are still first level entries in my "Pages" structure, peacfully located besides "Home" (one could say this is not consistent, but I think it's good enough having it at the top). – carlcs Feb 22 '15 at 20:35
  • Got you. I was thinking you were suggesting placing everything under 'home' in the heirarchy (i.e. level 2). That makes more sense. Thanks for clarifying. ;) – Douglas McDonald Feb 22 '15 at 20:43
  • If you don't want to use and "id" or "slug", but the first element in the structure, it's very easy too. On the index page: {% set entry = craft.entries.section('pages').first() %}. For the navigation: {% set pages = craft.entries.section('pages').offset(1).level(1) %}. Works like a charm. – outline4 Jun 11 '15 at 6:36
3

I kludged this to work by creating a global whose value was the entry I wanted to use as the home page (everyPage.homePage), and then on _pages/_entry.html using twig to sort things out based on the entry:

  • if no entry: 404 (this should never happen)
  • if entry is everyPage.homePage: 404
  • if entry is the Craft home page single: set entry to everyPage.homePage

Then proceed as normal.

{% if entry is not defined %}
  {% exit 404 %}
{% elseif entry.id == everyPage.homePage.first.id %}
  {% exit 404 %}
{% elseif entry.id == craft.entries.section('homePage').first().id %}
  {% set entry = everyPage.homePage.first %}
{% endif %}

This was using a channel (not a structure) for the pages, and the URL is simply {slug}

  • Whooohoo, Marion! Kinda hacky but really great solution, if this really works. Off for the test... – carlcs Jul 31 '14 at 17:50
  • To be true, I don't really understand it. Let's try: I'd still need a single (the only entry I could route / to), the global is basically not necessary, right? (just for convenience) and then you'd just "import" the content from the select channel- or structure-entry by getting it's entry model... good that's a plan! – carlcs Jul 31 '14 at 18:05
  • Actually... why not simply get the desired entry model (with id or slug) from my public/index.html template!? If that's all I needed, I totally don't know why I didn't come up with that myself. That's all the more reason to thank you, Marion! :D – carlcs Jul 31 '14 at 18:13
3

From an IA and content-modelling perspective, putting all your site's "pages" in a Structure is fraught with problems, and, in my opinion, does a terrible disservice to the future-friendly approach with which you should be building sites. I wrote about this at length recently: https://cld.agency/blog/content-utopia

To more directly answer the question:

  1. stop mixing all your content types together in a single Structure (see article);
  2. divorce your navigation from the content;
  3. use a dedicated Channel or Structure for home page entries (note the plural - allows for A/B tests and seasonal variations, permanent storing of draft home pages etc), then load the most recent or first-structure-ordered entry manually in your home page template.
  • I totally agree, and when I wrote that “I am using a structure for all of my site's pages”, I meant entries where you usually use Singles for. The reason to go with a structure instead, was that there’s no way to list Singles in the CP in manual sort order. In this project we had so many Singles that it was getting hard to find the right one in the list. – carlcs Nov 30 '18 at 20:35

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.