Custom post type permalinks giving 404s

I’m having trouble setting up permalinks for a custom post type.
Below is the code from my init function:

register_post_type('topic',
  array(
   ...
   'hierarchical' => true,
   'query_var' => true,
   'rewrite' => false,
   ...
  ));

if(get_option('permalink_structure')!= ''):
  global $wp_rewrite;

  $wp_rewrite->add_rewrite_tag('%topic%', '(.+?)', 'topic=');
  $wp_rewrite->add_permastruct('topic', '%forum%/%topic%/', false, EP_PERMALINK);
endif;

Basically I’m trying to set up permalinks my own way because I want to append a custom taxonomy term before the post title.

Read More

Instead of: topic/whatever

use: general-forum/sub-forum/whatever

This is the function that changes the link, which seems to work ok:

add_filter('post_type_link', 'topic_link', 10, 4);
function topic_link($link, $post){
  if($post->post_type != 'topic') return $link;
  global $wp_post_types;
  $terms = get_the_terms($post->ID, 'forum');
  if(!is_wp_error($terms) && !empty($terms)):
    usort($terms, '_usort_terms_by_id');
    $forums = $terms[0]->slug;
    if(!empty($terms[0]->parent)):
      $parent_item = $terms[0]->parent;
      while(!empty($parent_item)):
        $parent = get_term($parent_item, 'forum');
        if(!is_wp_error($parent) && !empty($parent))
        $forums = $parent->slug.'/'.$forums;
        $parent_item = empty($parent->parent) ? false : $parent->parent;
      endwhile;
    endif;
  endif;
  return str_replace('%forum%', $forums, $link);
}

So the modified URL is displayed fine, the only problem is that I get a 404 error 🙂
What am I doing wrong in my init code?

LE: the ‘forum’ taxonomy:

register_taxonomy(
  'forum',
    array('topic', 'reply'),
    array(
      'public' => true,
      'name' => _a('Forums'),
      'singular_name' => _a('Forum'),
      'show_ui' => true,
      //'show_tagcloud' => true,
      'show_in_nav_menus' => true,
      'hierarchical' => true,

      'labels' => array(
        'name' => _a('Forums'),
        'singular_name' => _a('Forum'),
        'search_items' => _a('Search Forums'),
        'popular_items' => _a('Popular Forums'),
        'all_items' => _a('All Forums'),
        'parent_item' => _a('Parent Forum'),
        'parent_item_colon' => _a('Parent Forum:'),
        'edit_item' => _a('Edit Forum'),
        'update_item' => _a('Update Forum'),
        'add_new_item' => _a('Add New Forum'),
        'new_item_name' => _a('New Forum Name'),
      ),
      'query_var' => true,
      'rewrite' => array('slug' => 'forums', 'with_front' => false, 'hierarchical' => true),
      //'update_count_callback' => 'my_custom_count_callback',
  )
);

Related posts

Leave a Reply

1 comment

  1. My plugin Custom Post Permalinks does this sort of thing for you:

    http://wordpress.org/extend/plugins/custom-post-permalinks

    If you’d rather use your own solution, I’ll need a bit more information, such as the registration code for the forums taxonomy.

    Just guessing, I’m thinking the regex for a forum looks identical to the regex for a topic to the rewrite engine.

    EDIT

    Looking at your code, it looks like you’re using 3.1. The $args['rewrite']['hierarchical'] bit for taxonomies wasn’t in 3.0. Basically, what that argument does is changes the regular expression for the %forum% tag from ([^/]) to (.+?). This means that WordPress’ rewrite engine gets a match for this regular expression first:

     @/(.+?)/(.+?)/?$
    

    Which, for something like /generic-forum/specific-forum/specific-topic, will parse to this:

    index.php?forum=generic-forum&topic=specific-forum/specific-topic
    

    To test if this is really what’s causing the 404, change the taxonomy’s rewrite args so that ['rewrite']['hierarchical'] is either not set or set to false, flush the rewrite rules, and modify your topic link function not to add parents to the link; Then test to see if the new links work.

    If this is the cause of the problems, there are a couple of ways to fix this. The easiest would be to add a bit of plain text to the permastruct, like this: %forum%/topic/%topic%. That would give you links like this: /general-forum/sub-forum/topic/whatever. Another way would be to add another rewrite tag like this:

    $wp_rewrite->add_rewrite_tag( '%post_type_topic%', '(topic)', 'post_type=' );
    

    then change the permastruct to ‘%forum%/%post_type_topic%/%topic%’.