I am using a custom post structure, which ads a slug /travel-advice/before the post name. E.g. http://example.com/travel-advice/article-one/

I would like Wordpress to use archive.php whenever I use the following url `http://example.com/travel-advice/

For custom post types it is possible to specify an archive page slug using 'has_archive' but what to do in case I want this for the default posts?

So far it gives me 404 error. The only solution I found so far is creating a page which uses a custom template and shows all default posts. Is there a way to do it differently through functions.php, for instance?

  • 1
    For reference, archive.php is a template loaded on a page. This implies your understanding of the way templates and pages in WP works is quite literally upside down. The query determines the template, not the other way around. If you create an archive at a particular URL, it will automatically use that template. pre_get_posts and rewrite rules are your friends here
    – Tom J Nowell
    Apr 5, 2017 at 15:54

1 Answer 1


Have a look at the following ..

function my_parse_request allows for the template to override.

function my_query_vars adds your custom argument to the WordPress white listed args

function my_init registers the rewrite.

function find_custom_template finds your template in either a parent or child theme.

remember you will need to flush() your permalinks for the rewrite. Just do this either from the Admin>settings>permalink>save or flush through code on plugin activation (not on the init hook !)

// redirect to the signup template file
add_action( 'parse_request', 'my_parse_request' ); 

function my_parse_request( &$wp ) {
    if ( array_key_exists( 'custom-travel-advice', $wp->query_vars ) ) {  
        /* Allow themes to override the signup template with the file 'page-signup.php'
        * in either the parent or child theme.
        if ( $template_found = find_custom_template( 'page-signup.php' ) ) {               
                include( $template_found );

add_action( 'query_vars', 'my_query_vars' );        

 * whitelist plugin defined query variable within WordPress
 * @access public    
 * @param $query_vars
 * @return $query_vars
function my_query_vars( $query_vars ) {
        $query_vars[] = 'custom-travel-advice';
        return $query_vars;

add_action( 'init', 'my_init' );

 * Registers all required code
 * @access public    
 * @return void
function my_init() {
        // add rewrite on the frontend and amdmin side for any furture flush of the rewrites
        // the query variable 'custom-travel-advice' is used
        add_rewrite_rule( 'travel-advice/?$', 'index.php?custom-travel-advice=true', 'top' );


 * Finds a custom template is available, if present allows the child or 
 * parent theme to override the plugin templates.
 * @return   False if not found otherwise the template file location given within the site
function find_custom_template( $template_wanted = '' ) {

        $plugin_template_file = false;                       
        if ( locate_template( $template_wanted ) != '' ) {

                // locate_template() returns path to file
                // if either the child theme or the parent theme have overridden the template
                $plugin_template_file = locate_template( $template_wanted );

        return $plugin_template_file;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.