Is there a standard way to do 404 pages with structure? Many thanks!
Ben
ExpressionEngine® Answers is a question and answer site for administrators, end users, developers and designers for ExpressionEngine® CMS. It only takes a minute to sign up.
Sign up to join this communityThere are several strategies for best utilizing 404s on a Structure site:
First, make sure that any Structure-assigned templates are either hidden, or inside a hidden template group (prepend the group or template name with "_" or "." - so "_blog" or ".blog"). This ensures that there is no duplicate EE URL in addition to the Structure URL.
For example, if I create a blog using Structure, and I have a template group like this:
When I publish a blog post, it will actually exist at 2 URLs: /blog/my-blog-post (Structure) and /blog/post/my-blog-post (native EE). By making your Structure templates hidden, you are eliminating the possiblility of the second, native EE URL, because if someone tries to navigate directly to a hidden template, they get a 404.
Go to the Structure tab on your homepage's publish page, and change "Structure Page URL" to "/". This will prevent your homepage from being displayed at the URL "/home".
Here are a couple of snippets you should use on every template:
At the Top of the Template:
{if segment_x == ''}
{redirect='404'}
{/if}
Where "x" is the segment after the last segment you would expect in the URL. So for a blog page (/blog/my-blog-post), you would use segment_3
, because you'd never expect anything after the second segment with the blog post (like /blog/my-blog-post/boo).
In your {exp:channel:entries}
tag, you should add the parameter require_entry='yes'
, and add an if no_results
conditional, like this:
{exp:channel:entries
channel='blog'
limit='1'
disable='pagination|categories|member_data'
require_entry='yes'
}
{if no_results}
{redirect='404'}
{/if}
{!-- Your Blog Content --}
{/exp:channel:entries}
This will ensure that a 404 will be returned if someone enters a non-existant URL title. Structure should do this automatically, but I like to do it anyway as an added insurance policy. Note that you should only do this on dynamic, single-entry pages. It won't work on listing pages with dyanmic='no'
.
I use an embedded template for the <head>
section of my document so I can pass it variables. That way, I can give pages that aren't managed by Structure (like the 404 page) unique titles without resorting to crazy conditional tomfoolery. For example, in my 404 page template, I'll put:
{embed='_global/document_head' page_title='404 Page Not Found'}
Then in the _global/document_head
template, I'll have:
{if embed:page_title}
<title>{embed:page_title} | Sam's Elephant Warehouse</title>
{/if}
{if embed:page_title == ''}
<title>{structure:page:title} | Sam's Elephant Warehouse</title>
{/if}
This technique also works great if you're using an SEO extension like SEO Lite or Better Meta and you want to pass meta data to pages that aren't managed by the extension.
Do that stuff, and be sure to read Ryan Battle's kickass Guide to 404 Pages, and you'll be good to go.
You can create a custom template for 404 pages and then select it using the "Global Template Preferences" control panel.
I use this approach and it works fine with the Structure add-on.
Also be sure to use the following inside your channel entries tagpair.
{if no_results}
{redirect="404"}
{/if}