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.

I have a custom post type called venues currently they display through the url format:

http://mywebsite.com/venue/{venue-name}

I would like to have the format:

http://mywebsite.com/venue/{venue-suburb}/{venue-name}

But the suburb doesn't actually have any relation to pulling the venue custom post type. Names are always unique.

What would need to happen is at the time of rewrite, it pulls the {venue-suburb} based on the {venue-name} or id and rewrites the url with that information in it.

Is this something that is possible and if so how might I go about starting it?

Update: Here's the code I've been able to put together after some research. The result: http://mywebsite.com/my-venues/{venue-suburb}/{venue-name}/{post_id}

add_action('init', 'myposttype_rewrite');
function myposttype_rewrite() {
    global $wp_rewrite;
    $queryarg = 'post_type=venue&p=';
    $wp_rewrite->add_rewrite_tag('%cpt_id%', '([^/]+)', $queryarg);
    $wp_rewrite->add_rewrite_tag('%suburb%', '([^/]+)', $queryarg);
    $wp_rewrite->add_rewrite_tag('%title%', '([^/]+)', $queryarg);
    $wp_rewrite->add_permastruct('venue', '/my-venues/%suburb%/%title%/%cpt_id%', false);
}

add_filter('post_type_link', 'venue_permalink', 1, 3);
function venue_permalink($post_link, $id = 0, $leavename) {
    global $wp_rewrite;
    global $wpdb;

    $post = &get_post($id);
    if ( is_wp_error( $post ) )
        return $post;

    $newlink = $wp_rewrite->get_extra_permastruct('venue');

    $sql = "
        SELECT meta_value 
        FROM " . $wpdb->postmeta . " 
        WHERE post_id = " . $post->ID . " AND meta_key = 'address'";
    $address = $wpdb->get_var( $sql );
    $address = unserialize( $address );
    $suburb = str_replace(" ", "-", strtolower($address['suburb']));
    $title = str_replace(" ", "-", strtolower(get_the_title( $post->ID )));

    $newlink = str_replace("%suburb%", $suburb, $newlink);
    $newlink = str_replace("%title%", $title, $newlink);
    $newlink = str_replace("%cpt_id%", $post->ID, $newlink);
    $newlink = home_url(user_trailingslashit($newlink));
    return $newlink;
}

Removing the section for %cpt_id% makes the page come up as a 404. Rewriting %cpt_id% to "" also makes the page come up as a 404. Anyone know how to remove the post_id?

share|improve this question
add comment

1 Answer

Probably one of the simpler ways to do this would be to make venue suburb a non-hierarchical custom taxonomy. When you create a venue post, add a term for the suburb and assign it to that post. The register post type rewrite parameter contains a reference to the %venue_suburb% tag, then you can filter post_type_link to substitute that tag for the selected venue suburb term:

add_action( 'init', 'wpa65770_venue_custom_types' );

function wpa65770_venue_custom_types() {

    // extra parameters for tax and post type trimmed to save space
    register_taxonomy( 'venue_suburb','venue',
        array(
            'hierarchical' => false,
            'show_ui' => true,
            'query_var' => true,
            'rewrite' => array( 'slug' => 'venue-suburb' ),
        )
    );

    register_post_type( 'venue',
        array(
            'public' => true,
            'query_var' => true,
            'rewrite' => array( 'slug' => 'venue/%venue_suburb%' ), // rewrite with %venue_suburb%
            'hierarchical' => false,
            'supports' => array('title', 'editor', 'thumbnail')
        )
    );

}

add_filter( 'post_type_link', 'wpa65770_venue_permalink', 10, 3 );

function wpa65770_venue_permalink( $permalink, $post, $leavename ) {
    if ( false !== strpos( $permalink, '%venue_suburb%' )
        && $venue_suburb = get_the_terms( $post->ID, 'venue_suburb' ) ) {
        $permalink = str_replace( '%venue_suburb%', array_pop( $venue_suburb )->slug, $permalink );
    }
    return $permalink;
}

When you create a post, you'll see the %venue_suburb% tag in the URL until you associate a term to the post. Be sure to visit your permalinks settings page in admin once you add the above code to flush the rewrite rules so this all takes effect.

EDIT- Another version based on your code. You'll have to modify it to extract suburb from your serialized meta, I just tested with a string val for address:

add_action('init', 'myposttype_rewrite');
function myposttype_rewrite() {
    global $wp_rewrite;
    $queryarg = 'post_type=venue&venue=';
    $wp_rewrite->add_rewrite_tag('%suburb%', '([^/]+)', $queryarg);
    $wp_rewrite->add_permastruct('venue', '/my-venues/%suburb%/%venue%/', false);
}

add_filter('post_type_link', 'venue_permalink', 1, 3);
function venue_permalink($post_link, $post_obj, $leavename) {

    $post = &get_post($post_obj);
    if ( is_wp_error( $post ) )
        return $post;

    $address = get_post_meta( $post_obj->ID, 'address', true );
    $newlink = str_replace( '%suburb%', $address, $post_link );
    return $newlink;
}
share|improve this answer
    
I actually got it to work after trying a few things. However, the ID still needs to be in the URL at the end and I can't figure out how to get rid of it. Can you take a look? (Above) –  Matt Sep 20 '12 at 17:35
1  
Is there a reason you don't want to just use the method I provided that works exactly the way you want without issue? –  Milo Sep 20 '12 at 17:50
    
Because I would have to rewrite the function that creates the venues to associate it to the new suburb taxonomy and the function that creates the venue custom post type is held within a plugin so the "register_post_type( 'venue'" is more difficult to modify. –  Matt Sep 20 '12 at 18:15
    
you should state the requirements more clearly in your question and add the the additional relevant code. registering a post type without a plugin is trivial. –  Milo Sep 20 '12 at 18:24
    
Sure, but the client isn't a programmer and needs to be able to manage it from WordPress. I appreciate your help, it really was a great answer, but the question did say "What would need to happen is at the time of rewrite, it pulls the {venue-suburb} based on the {venue-name} or id and rewrites the url with that information in it." –  Matt Sep 20 '12 at 18:36
show 3 more comments

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.