Different wordpress 404 template for different post type [duplicate]
IT Nursery
May 7, 2022
0
I want to have different 404 template for each custom post type.
eg. I have post type name event and the link will be domain.com/event/my-event-name
but if it link to page that not have post domain.com/event/xxxxxxx
then it will show 404 page, but I want it different from 404.php template, I try get post type in 404.php but it can’t because it not have a post to get from.
3 Answers 3
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!