Different wordpress 404 template for different post type [duplicate]

WordPress 4.7 introduces a new filter that allows us to easily modify the template hierarchy:

/**
 * Filters the list of template filenames that are searched for when retrieving 
 * a template to use.
 *
 * The last element in the array should always be the fallback 
 * template for this query type.
 *
 * Possible values for `$type` include: 'index', '404', 'archive', 'author', 'category', 
 * 'tag', 'taxonomy', 'date', 'embed', home', 'frontpage', 'page', 'paged', 'search', 
 * 'single', 'singular', and 'attachment'.
 *
 * @since 4.7.0
 *
 * @param array $templates A list of template candidates, in descending order of priority.
 */
$templates = apply_filters( "{$type}_template_hierarchy", $templates );

For the 404 type, we could check the current path, as suggested by @cjbj.

Here’s an example where we modify the 404 template hierarchy by supporting the 404-event.php template, if the current path matches the ^/event/ regex pattern (PHP 5.4+):

add_filter( '404_template_hierarchy', function( $templates ) 
{    
    // Check if current path matches ^/event/ 
    if( ! preg_match( '#^/event/#', add_query_arg( [] ) ) )
        return $templates;

    // Make sure we have an array           
    if( ! is_array( $templates ) )
        return $templates;

    // Add our custom 404 template to the top of the 404 template queue
    array_unshift( $templates, '404-event.php' );

    return $templates;
} );

If our custom 404-event.php doesn’t exists, then 404.php is the fallback.

We might also just adjust the 404.php template file to our needs, as suggested by @EliCohen

We could also use the old 404_template filter (since WordPress 1.5), that’s fired after the locate_template() is called.

Here’s an example (PHP 5.4+):

add_filter( '404_template', function( $template ) 
{
    // Check if current path matches ^/event/ 
    if( ! preg_match( '#^/event/#', add_query_arg( [] ) ) )
        return $template;

    // Try to locate our custom 404-event.php template    
    $new_404_template = locate_template( [ '404-event.php'] );

    // Override if it was found    
    if( $new_404_template )
        $template = $new_404_template;

    return $template;
} );

Hope you can test it further and adjust to your needs!

Leave a Comment