32

I've spent a few days trying to learn how to best add rewrite rules. So far my understanding is that a suitable way to add simple rules is to use add_rewrite_rules(), with large thanks to Jan Fabry on this exchange who's elaborations have been of great use.

Although he mentions add_rewrite_tags() I haven't seen a guide on it explaining when it's beneficial to use it, as opposed to other ways to add rewrite rules, or any good examples on its usage. It seems to be a more powerful tool, but that's about all I can fathom. I find the examples in the Codex to be too cryptic or incomplete. Could someone elaborate on it or point to some resource? I found nothing useful on Google.

edit: Its Codex page talks about 'generally' using it in conjunction with add_rewrite_rules(), but doesn't elaborate. Similarly the Codex page for add_rewrite_rules() refers to add_rewrite_tags() but it too is very sparse on information. When and how would such a combination be used? The only example I found is this answer by Rob Vermeer which I don't understand.

1 Answer 1

26

The fundamental difference is:

  • The add_rewrite_rule() adds a particular rule which is interpreted
  • The add_rewrite_tag() adds a placeholder to use in url structures. This placeholder is then used to generate multiple rules.

For instance - suppose you're a travel agent advertising hotels in various countries. You may want a hotel's url to be like

  www.example.com/hotels/UK/Balmoral

Where the country (UK in this example) is a custom taxomony term and Balmoral is a hotel (post type). We could add rewrite rules for this, but then we would have to generate a rule for:

  • the hotel itself
  • the hotel's attachments
  • A rule for hotels (posts) where it spills over several pages etc.

Generating these rules can become complicated. Furthermore we'll probably be competing with WordPress's own rules for that post type - generated from the permastructure we set when registering the post type. (In any case, let WordPress do the work).

This 'permastructure' - similar to what you set for posts in the permalink settings - determines the rewrite rules WordPress generates. But since we want a structure which contains some unknown (the country) - which we want interpreted - we need to provide a placeholder of the form %country%. (It's almost identical to %category% for posts).

For example:

add_action_init('init','wpse71305_register_types');

function wpse71305_register_types(){

     //You'll need to register the country taxonomy here too.

     //Add 'country' tag.
     add_rewrite_tag('%country%', '([^&/]+)'));

     //Register hotel post type with %country$ tag
    $args = array(  
        ...
        'has_archive'=>true,  
        'rewrite' => array(  
            'slug'=>'hotels/%country%',  
            'with_front'=> false,  
            'feed'=> true,  
            'pages'=> true  
        )  
        ...
    );  
    register_post_type('hotel',$args);  
}

Note: WordPress doesn't know how to generate the url from the %country% tag - you need to tell it do that. (I cover this in an article I've linked to below).

Finally WordPress will also store the matched value so you can retrieve it via get_query_var() (something you don't with a standard rewrite rule).

You can also create tags to be used in the permastructure of posts (set it in the Permalink settings page).

By adding a tag, we can use it in permastructures. WordPress then knows

  • What to expect
  • How to interpret the url (check it matches)
  • How to interpret the value (i.e. 'UK')

(As reference see this article I wrote: http://wp.tutsplus.com/tutorials/creative-coding/the-rewrite-api-the-basics/).

Edit

As noted in the comments the above example is a poor as register_taxonomy() in fact calls add_rewrite_tag().

Regarding the Codex documentation about using them 'in combination': this is perhaps misleading as they can both be used independently. As noted above, however, add_rewrite_tag() adds the tag name to the WordPress-understand 'query variables'. In practice this allows you to retrieve the value with get_query_var(). Thus, when add_rewrite_rule() is used with add_rewrite_tag(), the variable will be stored by WordPress. But there are other ways of doing this (see this answer - note also Rob Vermeer's comment).

Also related: How to retrieve $_GET variables from rewritten URLs?

4
  • Thanks for this. One thing that I understand from your answer is that add_rewrite_tag() can be used for making placeholders to be used in Settings->Permalinks. About using a taxonomy, is it a requirement for using add_rewrite_tag()? My impression from the Codex page is that it's not, but it seems commonly used. I expanded my question with regard to using add_rewrite_tag() in conjunction with add_rewrite_rule() as suggested in the Codex page.
    – ivvi
    Commented Nov 4, 2012 at 9:53
  • You're absolutely right about taxonomies (a bad example on my part). See this part of register_taxonomy(). A better example would be when you want to use something like %country% but when country is just a common a query variable and not a taxonomy. These cases are rare - I've never had to use add_rewrite_tag(). Commented Nov 4, 2012 at 18:28
  • 1
    @StephenHarris when should one choose add-rewrite_tag() to add placeholders compared to the query_vars filter hook? Commented Jul 31, 2020 at 5:51
  • What is add_action_init? Shouldn't that be add_action? Commented May 2 at 16:15

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.