A painting of me

Building a 404 Error Page in Textpattern

   29 July 2004, evening time

Update: This information works with Textpattern 1.19 (gamma). Textpattern 4.0.1 provides some basic -- albeit lame -- support 404 pages.

This is a concise outline of what I did to get a custom 404 page working with Textpattern. You can read my earlier post on such pages for background.

Begin by creating a new section in Textpattern. (I called my section “404”). You should create a custom page template for your new section. At the top of this template, you should place the following snippet of PHP code. This will tell the web browser that you are sending back a 404 error.

<?php header("HTTP/1.0 404 Not Found"); ?>

Once done, create a new article that will be the contents of your 404 page. Assign the article to your new error section. Note down the id number of the article. You will need to the id number and the section name later.

Open up your .htaccess file, and add an ErrorPage directive to the file that will redirect 404 errors to the new article you created above. You will need to add something like this, replacing ‘999’ with the id number of the article you created:

ErrorDocument 404 /index.php?id=999

Now to get around some of the bugs in Textpattern, you will need to edit the publish.php file, in particular the pretext function. We will add some checks that verify ids, sections and categories exist before they are used.

After line 105, before the $out['id'] variable gets set, place the following code that will look up the id, and verify it exists in the database.

// verify the id exists, if not set it to your 404 article
if (!empty($id) && !fetch('ID','textpattern','ID',$id)) {
    $id = 999; // your 404 article id

Replace lines 108-112, where the $out['s'] variable is set. This variable stores the section we are in. If a section is supplied in a URL, we want to verify it exists in the database. So, this block of code should be replaced with the following:

// what section are we in?
if ($s) {
    $out['s'] = $s;
    // verify the section exists, if not, return the 404 page
    if (!fetch('name','txp_section','name',$s)) {
        $id = 999;// your 404 article id
        $out['s'] = 'XXX';// your 404 article section
} elseif ($id) { 
    $out['s'] = fetch('Section','textpattern','ID',$id); 
} else {
    $out['s'] = "default";

Line 124 is where the $out['c'] variable is set. The variable is where the category supplied in a URL get saved. Before we proceed, we want to verify that this category exists. We will want to do this check before the query to get section information (line 116), since if we do not find the category, we will be in the 404 section. So, we will remove line 124:

$out['c']              = gps('c');     // category?

and insert the following block of code right after the code we added above.

$out['c']              = gps('c');     // category?
// if a category has been set, then verify it exists
// otherwise redirect the user to a 404 page
if ( !empty($out['c']) && !fetch("name","txp_category","name",$out['c']) ){
    $id = 999;             // your 404 article id
    $out['s'] = '404';    // your 404 section
    $out['c'] = '';

That should be all you need to do to have all bad requests to your Textpattern install redirect to your 404 article.



  1. Please let me know if there are any problems with what I’ve presented above.

  2. Hi ramanan,

    Good idea. :)
    Little Addition: You may also want to add the right HTTP-Response-Code:

    header(“HTTP/1.0 404 Not Found”);

    (This has to be done, before anything is sent to the browser).

  3. Great! Thanks for that information.

    So you would in fact need to make a new page template for your 404 section, and would need to place this code at the top of that template:

    ... rest of code …

    I’ll update the article now.

  4. If you don’t like to hack your install, check out the zem_redirect plugin. I think this hack is more comprehensive, as I’m not sure the plugin captures all the cases. However, I think it is worth a look.

  5. Would zem_redirect and your hack complement each other well, do you think?

  6. I don’t think you’d need to run either with the newest version of TXP; there is built in support for 404 pages now. Finding documentation on it is much harder than it should be. Briefly, you should make a page template with the name of the numeric error code you want it to be displayed for. (So, you can make a page template called “404”, and it will be displayed when Textpattern detects a 404 error.) There are still a couple cases where I think Textpattern should send a 404 error and it doesn’t, though I can’t remember what those are off the top of my head. Also, I know a couple of the developers read this site, so you might get an even better answer from them (though posting this sort of stuff in the forums might be fruitful).

Don't be shy, you can comment too!

Some things to keep in mind: You can style comments using Textile. In particular, *text* will get turned into text and _text_ will get turned into text. You can post a link using the command "linktext":link, so something like "google":http://www.google.com will get turned in to google. I may erase off-topic comments, or edit poorly formatted comments; I do this very rarely.