The fundamental difference is:
add_rewrite_rule() adds a particular rule which is interpreted
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
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).
//You'll need to register the country taxonomy here too.
//Add 'country' tag.
//Register hotel post type with %country$ tag
$args = array(
'rewrite' => array(
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/).
As noted in the comments the above example is a poor as
register_taxonomy() in fact calls
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?