The WordPress rewrite system is an area many people struggle with when starting out. People not familiar with rewrite systems don’t necessarily understand what role they play and often developers who are used to using rewrite systems find WordPress’s implementation somewhat clunky.
When working on relatively complex WordPress projects, which have multiple custom taxonomies and combinations of post types, custom rewrite rules are likely to be needed.
So, what are rewrite rules? In WordPress, a rewrite rule is essentially a map of a URL pattern (using regex) to the WP_Query arguments. When the URL regex pattern is matched, the global $wp_query is populated with the arguments of the rule. For example, a year archive “page” would have a rewrite rule like:
^([d*4])/?$ => year=$matches
Now, to add your own custom rewrite rules, you have hook into potentially several places. Firstly you must hook into flush_rewrite to add your regex => wp_query arguments:
add_rewrite_rule( '#some regex#', 'post_type=offer&posts_per_page=5');
Some things to note:
- If you want to do any more advanced wp_query args that you can not pass in the string args style, or dynamically set arguments, you will need to hook into parse_request.
- If you have used any non-standard public query vars in your wp_query arguments you will need to hook into public_query_vars and add them to the array.
- Then you will need to hook into template_redirect to load a custom template for that URL pattern (if you so wish).
As a large amount of the work that I do is with quite complex relationships of post types and taxonomies, I have wrapped all the rewrite and associated functionality into a simple API, called hm_add_rewrite_rule.
The function takes an array of arguments about the specific rewrite rule, though the interface is all via one function call, it is backed by a pretty modular object orientated approach. A brief rundown of the argument
That’s about all the most useful arguments, but there are more. An example of a user profile rewrite rule:
Another rewrite with more callback options:
Or, if you are writing a nice RESTful API, and you want to do it using WordPress rewrite rules (for the cool kids), you can define the type of method request (GET|POST|PUT|DELETE) etc, capture the post_id from the url and handle the request in the request_callback.
HM Rewrite is currently part of the HM Core plugin, though the hm-rewrite file is self-contained, so if you want to try
hm_add_rewrite_rule() out, can can just use this file: https://github.com/humanmade/hm-core/blob/master/hm-core.rewrite.php.
Remember: Whenever you add a new rewrite rule via
hm_add_rewrite_rule() or update the regex/query of an existing rule, you have to flush your permalinks (just visit the permalinks options page).