I am testing out rewriting the permalink of a custom post type. The custom post type is for Events, one of the meta fields is the year of the event.

I'd like to have the event's year as part of the URL so if I have an event with the title 'Conference 1' and the year as '2011', the URL will be as follows: http://_____.com/events/2011/conference-1

I followed this tutorial to be able to rewrite the permalink of a custom post. Everything seems to be working but the page with the new URL always returns a page not found. I tried saving the Permanlinks settings a number of times and flushing the rewrite rules but nothing seems to be working.

Going to the page at http://_____.com/?event=conference-1 works but not the 'new' URL.

This is the code I have so far to rewrite the permalink:

function custom_post_event() {

    // ...

    $args = array(
        'labels' => $labels,
        'description' => 'Holds our Events and Event specific data',
        'public' => true,
        'menu_position' => 5,
        'supports' => array('title', 'editor', 'page-attributes', 'thumbnail'),
        'has_archive' => false,
        'publicly_queryable' => true,
        'query_var' => true,
        'rewrite' => false

    register_post_type('event', $args);

    // add to our plugin init function
    global $wp_rewrite;

    $event_structure = '/events/%event_year%/%event%';
    $wp_rewrite->add_rewrite_tag("%event%", '([^/]+)', "event=");
    $wp_rewrite->add_permastruct('event', $event_structure, false);
add_action('init', 'custom_post_event');

// Add filter to plugin init function
add_filter('post_type_link', 'event_permalink', 10, 3);   

function event_permalink($permalink, $post_id, $leavename) {
    $post = get_post($post_id);
    $rewritecode = array(
        $leavename? '' : '%postname%'

    if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
        $event_year = get_post_meta( $post->ID, 'event_post_year', true );

        $rewritereplace = array(

        $permalink = str_replace($rewritecode, $rewritereplace, $permalink);

    return $permalink;

1 Answer 1


If you are using this in a plugin, from the codex:

To get permalinks to work when you activate the plugin use the following example, paying attention to how my_cpt_init is called in the register_activation_hook callback:

add_action( 'init', 'my_cpt_init' );
function my_cpt_init() {
    register_post_type( ... );

function my_rewrite_flush() {
    // First, we "add" the custom post type via the above written function.
    // Note: "add" is written with quotes, as CPTs don't get added to the DB,
    // They are only referenced in the post_type column with a post entry, 
    // when you add a post of this CPT.

    // ATTENTION: This is *only* done during plugin activation hook in this example!
    // You should *NEVER EVER* do this on every page load!!
register_activation_hook( __FILE__, 'my_rewrite_flush' );

I would place

// add to our plugin init function
global $wp_rewrite;

$event_structure = '/events/%event_year%/%event%';
$wp_rewrite->add_rewrite_tag("%event%", '([^/]+)', "event=");
$wp_rewrite->add_permastruct('event', $event_structure, false);

In a separate action than the post registration, but before the flush.

Is the return $permalink output correct?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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