If you run your Wordpress blog on the wonderful Genesis Framework (as I
do did), then you know that the 404 page is pretty nice out of the box. It gives the user a way back to the homepage, and lists of Pages and Posts and all kinds of ways to get people to find the content they wanted.
It lacks customization options though. In most of the sites I work on, there are a few pages that don’t get linked from the menus because they’re specialty pages. It could be a “thank you for purchasing” page, or a landing page for traffic from a specific site or campaign.
I’ve come up with a quick modification that lets you hide pages from the 404 listing by setting a field in the page’s metadata.
Changing the 404
Making any changes to the 404 page is going to require editing the PHP. But most Genesis child themes don’t include a customized 404; they just use the one provided by Genesis. We do not want to modify the file directly in Genesis. Instead we’ll copy the
404.php file into the directory for the child theme.
This will probably have to be done with your FTP program or through your web host’s file manager. Now, you can edit the
404.php file in the child theme directory. For this, you can use any editing method you like, including the one in the Wordpress back end:
Looking at the code in
404.php, find where the pages are listed:
In the documentation for the
wp_list_pages() function, you can see that there’s an exclude parameter. You can give it a list of page IDs and it will exclude those from the listing.
I wanted a method that didn’t require me to modify the 404 file for every site I worked on, and every single page I wanted hidden!
Metadata Custom Fields
Each post and page in Wordpress has the ability to add custom fields to its metadata, in the form of key/value pairs. This is perfect for what I wanted: a way to hide individual pages from the 404, and do it from the standard Wordpress back end.
To do that, I made the following modification to code you see above:
The outline of what I’m doing here goes like this:
Get an array of all the pages using
For each page, get the value of any custom fields with the name
Look for a value of
hideand if found, add the page ID to an array.
wp_list_pages()with a comma separated list of pages (generated from our exclude array) to exclude.
With these changes in place, the page is generic enough to be included in any Genesis child theme.
Excluding a Page
Now you need only set your metadata custom field with the name
404 and the value
Any value of other than
hide will be ignored, and the page will be shown in the 404 listing.
If you need to hide posts, you can apply the same logic to the section that shows posts, though I’ve never needed that functionality myself.
Since I’m getting a list of all the pages with the call to
get_pages(), I don’t need to call
wp_list_pages() again; I could generate the list items and the links myself. But I didn’t want to have to worry about generating the right tags with the right classes and all that. I feel like the 404 page should be such a small part of your site’s traffic that an extra database call in the 404 won’t be such a big deal.
I’ve also included a completed 404.php file which you can download here and use without changes. Just upload it to your child theme directory and you’re good to go (as long as there isn’t already one there).