70

I have a very peculiar requirement, but 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, and 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 information 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?

0

2 Answers 2

86

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.

10
  • 5
    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
    Commented Nov 13, 2012 at 17:52
  • 27
    @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
    Commented Nov 13, 2012 at 20:17
  • 1
    Yeah, I get that . . . but when you are testing it's nice that it's in there!
    – tooshel
    Commented Nov 14, 2012 at 20:32
  • 3
    A smarter rewrite url regexp might be ^properties/([0-9]+)/?. Otherwise it would match something like example/properties/1 Commented Dec 12, 2014 at 17:34
  • 1
    What is location of page-properties.php file? I put it inside plugin directory. Is that right? Commented Jun 30, 2016 at 6:09
11

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

5
  • 3
    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
    Commented Jul 7, 2017 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. Commented Jul 8, 2017 at 7:28
  • @Milo Although I personally prefer rewrite tag, but still tested the accepted answer and it works. Just some personal tastes, though.
    – Johansson
    Commented Jul 8, 2017 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
    Commented Jul 8, 2017 at 15:47
  • 1
    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
    Commented Jul 14, 2018 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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