I am trying to add a url rewrite rule that finds any posts that are connected to the current post (using Posts 2 Posts by scribu). It's tied into the WP Query object, so all I have to do is pass another variable "connected" => $post_id and it works. This is my rule that I am working with, but I don't have the post_id as a part of my url, so I can't get that via regex.

add_rewrite_rule("cleats/([^/]+)/news", "index.php?tag=\$matches[1]", 'top');

What really needs to happen if this is going to work is that I need to get the id based on the post slug via get_posts, but that seems like overkill to happen on every single init. Am I going down the right path, or is this not worth it?

What I want to happen is show only related news articles. For instance, I have a Manchester United page (custom post type of club) at /clubs/manchester-united. I want /clubs/manchester-united/news to show a listing of blog articles that are connected to that post. The way I am storing that information is with Posts 2 Posts, linking posts directly to that custom post. That keeps me from having to doubly maintain a list of tags that exactly match the custom post types that I have.

Where the query string for returning tags is as simple as ?tag=manchester-united, it works a little differently in my case. What I need is ?connected=45, where 45 is the post->ID of manchester-united. The regex in the rewrite rule above returns the slug "manchester-united", but that isn't enough information for my query. What I need to do is get the post->ID based on the "manchester-united" slug.

Is that hopefully a little clearer?

  • I'm struggling to follow your question. Can you give examples of the URLs you want and a description of what you expect each to do for you? – MikeSchinkel Feb 3 '11 at 10:28
  • I changed the description above to include more detail. – Derek Perkins Feb 3 '11 at 17:41

This is not really a WP_Rewrite question, unless you want to include the post ID in the URL. I think the best way to solve this is, as you suggest, do a get_posts() query with your slug, and change the variables from there.

Of course you don't have to do this on every init, only do it when you are at a clubs/[club_slug]/news/ page. So first create a rewrite rule that will set a special variable that you can check:

add_action( 'init', 'wpse8421_init' );
function wpse8421_init()
    // Assuming `wpse8421_club` is the name of your custom post type
    add_rewrite_rule( 'clubs/([^/]+)/news/?$', 'index.php?wpse8421_club=$matches[1]&wpse8421_related_news=true', 'top' );

Add this query var to the public query vars so you can check for it:

add_filter( 'query_vars', 'wpse8421_query_vars' );
function wpse8421_query_vars( $query_vars )
    $query_vars[] = 'wpse8421_related_news';
    return $query_vars;

Then check for this extra variable, and if it is set, modify the query.

add_filter( 'request', 'wspe8421_request' );
function wpse8421_request( $query_vars )
    if ( array_key_exists( 'wpse8421_related_news', $query_vars ) ) {
        $club_posts = get_posts( array(
            'post_type' => 'wpse8421_club',
            'name' => $query_vars['wpse8421_club'],
        ) );
        if ( $club_posts ) {
            $query_vars['connected'] = $club_posts[0]->ID;
            unset( $query_vars['wpse8421_club'] );
    return $query_vars;

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.