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.

This is a pretty strange problem. I'm creating a WordPress custom post type in my themes functions.php file using the following format:

add_action('init', 'product_register');

function product_register() {
$args = array(
    'label' => __('Products'),
    'singular_label' => __('Product'),
    'public' => true,
    'show_ui' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'rewrite' => true,
    'supports' => array('title', 'editor', 'thumbnail')
);

register_post_type( 'product' , $args );
}

This gives me the following url structure for my products: http://www.mywebsite.com/products/product-name.

However, if I switch to another theme (TwentyTen) and then switch back WordPress forgets the permalink, now when I browse to the URL above I get my 404 page.

The really strange thing I've noticed is that I can fix this issue by browsing to Settings -> Permalinks in admin. This temporarily fixes the problem until the next theme uninstall/ reinstall.

Anyone else had a similar issue?

share|improve this question
    
This is a non-issue. What you described is normal. And healthy. –  John P Bloch Oct 21 '10 at 13:23
    
Also, it was probably just a typo, but, given the code you've pasted, the url above should say /product/ not /products/. –  John P Bloch Oct 21 '10 at 13:24
    
Hey John, yes that is a typo. The example url should be mywebsite.com/product/product-name. –  jnthnclrk Oct 21 '10 at 13:26
    
I don't understand why WP forgets the permalink for the CPT. Surely, when I re-install my theme, functions.php should build the cpt and make the permalinks work as expected? –  jnthnclrk Oct 21 '10 at 13:27
    
I don't appreciate getting a negative vote for a typo. The issue is still a problem for me, and I love some help figuring out how to fix it. –  jnthnclrk Oct 21 '10 at 13:35

1 Answer 1

up vote 3 down vote accepted

The new permalink structure is only saved when WP_Rewrite::flush_rules() is called. Because this is an expensive operation (calculating the new rules and saving them to the database), you should not do it on every init call, but only when you change the structure. The custom post type however must be registered at every init call, since it is saved in a PHP array in memory, not in the database (which is why it forgot the custom post when you switched themes: the permalink structure still existed but referred to a custom post type that was not loaded, giving an error).

share|improve this answer
    
Thank you! That explains why browsing to Settings -> Permalinks fixes it as flush_rules() gets called. Can you tell me how I should configure my Theme and CPT so users can uninstall and reinstall without getting this problem? I guess putting WP_Rewrite::flush_rules() in functions.php is a bad idea? –  jnthnclrk Oct 21 '10 at 13:40
    
Or should I ask that as a separate question? –  jnthnclrk Oct 21 '10 at 13:44
    
@trnsfrmr: Most people put this kind of code in a plugin, and then hook into the activation of that plugin via register_activation_hook(). This will "survive" theme changes. If you really want it in your theme, you could try hooking into the switch_theme action. –  Jan Fabry Oct 21 '10 at 15:40
    
No need, I've fixed the problem by using the following line after my register_post_type call: flush_rewrite_rules( false ); –  jnthnclrk Oct 21 '10 at 15:48
    
@trnsfrmr: This works, but it is not recommended, because it takes some time to clear the database, re-calculate the rules and then save them again. Even if you don't do a "hard" flush (writing them to .htaccess), this requires database operations. So it really pays off to use the "proper" activation hooks. –  Jan Fabry Oct 21 '10 at 18:50

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.