I've created a custom post type, with an easy permalink structure. Now I want to enhance this permalink structure with some extra information.
public function custom_post_mission() {
$labels = array(
...
);
$args = array(
'labels' => $labels,
'description' => __( 'Holds our missions and specific data', TEXT_DOMAIN ),
'public' => true,
'menu_position' => 5,
'supports' => array( 'title', 'author', 'editor' ),
'has_archive' => true,
'menu_icon' => plugin_dir_url( __FILE__ ).'img/mission.png',
'register_meta_box_cb' => array( $this, 'add_custom_box' )
);
register_post_type( 'mission', $args );
}
With the above coding I got the following permalink structure: http://localhost/wordpress/mission/<post-title>/
This structure I would like to improve to the following one:
http://localhost/wordpress/mission/<year>/<month>/<post-title>/
How can I do this? It would be nice if there is a way to transfer the old permalink structure to the new one, but it's not necessary.
BR & Thanks,
mybecks
/E: enhanced my code with code example provided by ravi
public function custom_post_mission() {
global $wp_rewrite;
$labels = array(
...
);
$args = array(
'labels' => $labels,
'description' => __( 'Holds our missions and specific data', TEXT_DOMAIN ),
'public' => true,
'menu_position' => 5,
'supports' => array( 'title', 'author', 'editor' ),
'has_archive' => true,
'menu_icon' => plugin_dir_url( __FILE__ ).'img/mission.png',
'register_meta_box_cb' => array( $this, 'add_custom_box' )
);
register_post_type( 'mission', $args );
$wp_rewrite->add_permastruct('mission', 'mission/%year%/%monthnum%/%mission%/', true, 1);
add_rewrite_rule('mission/([0-9]{4})/(.+)/?$', 'index.php?mission=$matches[2]', 'top');
$wp_rewrite->flush_rules(); // !!!
}
This creates the following permalink structure:
http://localhost/wordpress/mission/%year%/%monthnum%/<mission-title>/
But the %year%
and %monthnum%
placeholder couldn't be replaced with the corresponding values.
/E2: I finally get it to work. I needed a filter which resolves the placeholders:
add_filter('post_type_link', 'mission_permalink', 10, 3);
function mission_permalink( $permalink, $post_id, $leavename ) {
$post = get_post($post_id);
$rewritecode = array(
'%year%',
'%monthnum%',
'%day%',
'%hour%',
'%minute%',
'%second%',
$leavename? '' : '%postname%',
'%post_id%',
'%category%',
'%author%',
$leavename? '' : '%pagename%',
);
if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
$unixtime = strtotime($post->post_date);
$category = '';
if ( strpos($permalink, '%category%') !== false ) {
$cats = get_the_category($post->ID);
if ( $cats ) {
usort($cats, '_usort_terms_by_ID'); // order by ID
$category = $cats[0]->slug;
if ( $parent = $cats[0]->parent )
$category = get_category_parents($parent, false, '/', true) . $category;
}
// show default category in permalinks, without
// having to assign it explicitly
if ( empty($category) ) {
$default_category = get_category( get_option( 'default_category' ) );
$category = is_wp_error( $default_category ) ? '' : $default_category->slug;
}
}
$author = '';
if ( strpos($permalink, '%author%') !== false ) {
$authordata = get_userdata($post->post_author);
$author = $authordata->user_nicename;
}
$date = explode(" ",date('Y m d H i s', $unixtime));
$rewritereplace =
array(
$date[0],
$date[1],
$date[2],
$date[3],
$date[4],
$date[5],
$post->post_name,
$post->ID,
$category,
$author,
$post->post_name,
);
$permalink = str_replace($rewritecode, $rewritereplace, $permalink);
// wp_die($permalink );
} else { // if they're not using the fancy permalink option
}
return $permalink;
}
and I there was a small error in the add_rewrite_rule regexp.
The correct one: add_rewrite_rule('mission/([0-9]{4})/([0-9]{2})/(.+)/?$', 'index.php?mission=$matches[3]', 'top');
rewrite
argument when you register your post type and WordPress does this for you. Also do not flush rules on every request as your code does now. – Milo Jan 3 '14 at 15:12