Wordpress - Wordpress 3.3 custom post type with /%postname%/ permastruct?
This isn't easily done in WP 3.3 unless you trick the rewrite rules to be in the correct spot and make wp_rewrite think verbose rules are being used in the front end. The class below works.
class Test_Post_Type {
const POST_TYPE = 'test';
public static function init() {
global $wp_rewrite;
$post_type_obj = register_post_type( self::POST_TYPE, array(
'labels' => array(
'name' => __( 'Tests' ),
'singular_name' => __( 'Test' ),
'add_new' => __( 'Add New' ),
'add_new_item' => __( 'Add New Test' ),
'edit_item' => __( 'Edit Test' ),
'new_item' => __( 'New Test' ),
'all_items' => __( 'All Tests' ),
'view_item' => __( 'View Test' ),
'search_items' => __( 'Search Tests' ),
'not_found' => __( 'No Tests found' ),
'not_found_in_trash' => __( 'No Tests found in Trash' ),
'menu_name' => __( 'Tests' )
),
'publicly_queryable' => true,
'exclude_from_search' => true,
'hierarchical' => false,
'public' => true,
'rewrite' => false,
'has_archive' => true,
'supports' => array( 'title', 'editor', 'thumbnail', 'test_source' ),
'taxonomies' => array( 'category', 'post_tag' ),
) );
$post_type_obj = get_post_type_object(self::POST_TYPE);
//register the rewrite tag for permalink building
$wp_rewrite->add_rewrite_tag( '%' . $post_type_obj->query_var . '%', '([^/]+)', $post_type_obj->query_var . '=' );
//we have to add the permastruct here in order to build the permalink, otherwise we'll need to filter the post_type link
add_permastruct(self::POST_TYPE, '%' . $post_type_obj->query_var . '%/', false );
//add a filter to remove the permastructs generated above
add_filter(self::POST_TYPE . '_rewrite_rules', array(__CLASS__, '_remove_default_rules'));
//now we add a filter to put the generated rewrite rules in the correct spot
add_action('generate_rewrite_rules', array(__CLASS__, '_filter_rewrite_rules'));
if(!is_admin()) {
//we need verbose_page_rules to be on on the front end in order for pages to be process properly
$wp_rewrite->use_verbose_page_rules = true;
}
}
/**
* Filter to remove the rules for this post type when they're automatically generated due to the permastruct registration
* @param type $rules
* @return type
*/
public static function _remove_default_rules($rules) {
return array();
}
/**
* Filters the rules at the end to add back the ones for this post type at the bottom
* @param WP_Rewrite $wp_rewrite
*/
public static function _filter_rewrite_rules($wp_rewrite) {
$post_type_obj = get_post_type_object(self::POST_TYPE);
$my_rules = $wp_rewrite->generate_rewrite_rules('%' . $post_type_obj->query_var . '%', EP_NONE);
$wp_rewrite->rules += $my_rules;
}
}
add_action( 'init', array( 'Test_Post_Type', 'init' ) );