Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm developing a Custom Post Type plugin, which works fine in dev. Now that I've moved it to production, I'm getting a 404 when I try to display the template for the CPT.

So, two questions:

1- Is there some mechanism to determine the path WP took to get through the hierarchy?

2- Why wouldn't it just give me the single or index page?

I've dumped $wp_query and a stacktrace at the end of the 404. Here's part of what I found:

[query] => Array
    (
        [page] => 
        [pagename] => refletters/proximity
    )

[request] => SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND (wp_posts.ID = '0') AND wp_posts.post_type = 'page'  ORDER BY wp_posts.post_date DESC 
[posts] => Array
    (
    )

[queried_object] => 
[queried_object_id] => 0

And the stack trace:

2013-04-27 22:16:41 - 24.52.197.40 - TRACE - index.php - 404.php[39] - 
    wordpress/wp-content/themes/notoriousconsultant/404.php[39] - aaLog->logtrace
    wordpress/wp-includes/template-loader.php[50] - include
    wordpress/wp-blog-header.php[16] - require_once
    wordpress/index.php[17] - require

Thanks for your help.

share|improve this question

1 Answer 1

up vote 10 down vote accepted

Always flush the rewrite rules when you register a new public post type or taxonomy. Otherwise the internal rewrite rules will not take that into account when an URL is mapped to a query.

You can automate that process by hooking into registered_post_type and registered_taxonomy.

Below is the updated code, based on feedback from comments and other people.

Download as plugin T5 Silent Flush on GitHub.

add_action( 'registered_post_type', 't5_silent_flush_cpt', 10, 2 );
add_action( 'registered_taxonomy',  't5_silent_flush_tax', 10, 3 );

/**
 * Flush rules for custom post types.
 *
 * @wp-hook registered_post_type
 * @param   string $post_type
 * @param   stdClass $args
 * @return  void
 */
function t5_silent_flush_cpt( $post_type, $args )
{
    if ( $args->_builtin )
        return;

    if ( ! $args->public )
        return;

    if ( ! $args->publicly_queryable )
        return;

    if ( ! $args->rewrite )
        return;

    $slug = $post_type;

    if ( isset ( $args->rewrite['slug'] ) && is_string( $args->rewrite['slug'] ) )
        $slug = $args->rewrite['slug'];

    $rules = get_option( 'rewrite_rules' );

    if ( ! isset ( $rules[ $slug . '/?$'] ) )
        flush_rewrite_rules( FALSE );
}

/**
 * Flush rules for custom post taxonomies.
 *
 * @wp-hook registered_taxonomy
 * @param   string $taxonomy
 * @param   string $object_type
 * @param   array  $args
 * @return  void
 */
function t5_silent_flush_tax( $taxonomy, $object_type, $args )
{
    // No idea why we get an array here, but an object for post types.
    // Objects are easier to write, so ...
    $args = (object) $args;

    if ( $args->_builtin )
        return;

    if ( ! $args->public )
        return;

    if ( ! $args->rewrite )
        return;

    $slug = $taxonomy;

    if ( isset ( $args->rewrite['slug'] ) && is_string( $args->rewrite['slug'] ) )
        $slug = $args->rewrite['slug'];


    $rules = get_option( 'rewrite_rules' );

    if ( ! isset ( $rules[ $slug . '/(.+?)/?$'] ) )
        flush_rewrite_rules( FALSE );
}

This will flush the rules each time you create a new post type or taxonomy. No need to visit the permalink settings again.

share|improve this answer
    
I'm thinking of adding this to the CPT plugin itself. Doesn't seem to make sense to require a user to have another plugin for my plugin to work. –  NotoriousWebmaster Apr 28 '13 at 1:39
    
Yes, of course. I just wanted to provide a reusable example for other readers with the same problem. –  toscho Apr 28 '13 at 1:43
7  
Sounds like this should be in core –  Scott Kingsley Clark Apr 28 '13 at 2:08
    
Had a few questions on this: will this be as resource intensive as flushing the rewrite rules and does this run every time WP loads? –  Manny Fleurmond Apr 28 '13 at 4:33
2  
@kaiser There is a similar action for taxonomies called registered_taxonomy so it could also be done for those. I was thinking that if you did this for a plugin where the slug was changeable, all you had to do was unset the post type from the array and this would automatically get called again –  Manny Fleurmond Apr 28 '13 at 12:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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