48

I have a very peculiar requirement, hopefully, I can explain it without being too confusing. I created a page template where I list some properties I get from an external XML file, so far no problems, let's say the URL is like this:

http://www.example.com/properties/

Each property has a link that should redirect the user to a "Single Property" page that displays more info about it. I was wondering if there's a way to make the link like this:

http://www.example.com/properties/123

Where 123 would be the id of the property. So if I have the URL like properties/some_id I want to be able to load a view file (like the single.php or page.php files) but specific to this URL condition.

Is this possible?

55

Add this to your theme's functions.php, or put it in a plugin.

add_action( 'init', 'wpse26388_rewrites_init' );
function wpse26388_rewrites_init(){
    add_rewrite_rule(
        'properties/([0-9]+)/?$',
        'index.php?pagename=properties&property_id=$matches[1]',
        'top' );
}

add_filter( 'query_vars', 'wpse26388_query_vars' );
function wpse26388_query_vars( $query_vars ){
    $query_vars[] = 'property_id';
    return $query_vars;
}

This adds a rewrite rule which directs requests to /properties/ with any combination of numbers following to pagename properties, with the query var property_id set. Just be sure to visit your permalinks settings page and save to flush rewrite rules, so this new rule will be included.

In your page-properties.php template, get_query_var('property_id') will return the property id if it was set, if it's not then show the default properties page.

  • 4
    This was CLOSE to working for me but I needed to add: add_filter('init','flushRules'); function flushRules(){ global $wp_rewrite; $wp_rewrite->flush_rules(); } – tooshel Nov 13 '12 at 17:52
  • 16
    @tooshel you definitely don't want to flush rules on every request, it is an expensive operation and will slow your site to a crawl. you only need to flush rules once, on plugin activation, or just by visiting the permalinks settings page. – Milo Nov 13 '12 at 20:17
  • Yeah, I get that . . . but when you are testing it's nice that it's in there! – tooshel Nov 14 '12 at 20:32
  • 3
    A smarter rewrite url regexp might be ^properties/([0-9]+)/?. Otherwise it would match something like example/properties/1 – Ryan Taylor Dec 12 '14 at 17:34
  • @RyanTaylor are you sure about that? it doesn't capture example/properties/1 when I test it. – Milo Dec 12 '14 at 18:14
9

Another way to do it:

add_action('init', function() {
    add_rewrite_rule( '^properties/([0-9]+)/?',
                      'index.php?pagename=properties&property_id=$matches[1]',
                      'top' );
}, 10, 0);

add_action('init', function() {
    add_rewrite_tag( '%property_id%', '([^&]+)' );
}, 10, 0);

Codex Rewrite API/add rewrite rule

Codex Rewrite API/add rewrite tag

  • 2
    The accepted answer works with 4.7 (and 4.8), not sure why you think it doesn't. Your code is essentially doing the same thing, add_rewrite_tag adds the query var to the same array as the query_vars filter. – Milo Jul 7 '17 at 17:45
  • @Milo it probably didn’t work for me, but I don’t have a 4.7 handy anymore so I can’t check. I will edit my answer. – Christian Lescuyer Jul 8 '17 at 7:28
  • @Milo Although I personally prefer rewrite tag, but still tested the accepted answer and it works. Just some personal tastes, though. – Jack Johansson Jul 8 '17 at 15:36
  • 1
    @JackJohansson rewrite tags are necessary when you're using it in a permastruct. It's just an extra bit of data that WordPress never uses in this case. – Milo Jul 8 '17 at 15:47
  • both rules can be added to the same method, ending up in a cleaner and more useful function to come back to and figure out if doing maintenance work – eballeste Jul 14 '18 at 15:51

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.