How does routing on wordpress work?

In WordPress, URLs don’t map to routes. They map to database queries.

When using WordPress in the “default” permalinks mode, you have a set of variables in the main URL query, like ?p=1 or ?page=234 and so forth. There’s also ?s=search and many others.

If you use the “pretty” permalinks, then a big set of rules called the “rewrite rules” is created which directly maps various URL patterns onto this same set of URL parameters. So a URL like /2014/04/12/example would map to ?year=2014&month=04&day=12&postname=example or similar. So the following applies to these as well, after this mapping is done.

These variables are essentially controlling the main instance of the WP_Query class. The WP_Query class holds all the information that builds the database query to get the “posts” from the database. The various parameters passed into it control what kind of query it builds and what data it gets.

See, everything that can be displayed by WordPress is essentially a “post”. A blog is a series of posts in reverse time-based order. A “page” is a static post with a defined name. A “custom post type” is exactly what it sounds like, a “post” with a custom type that you define. All main queries to display anything in WordPress are getting some subset of posts from the wp_posts table.

The WP_Query is what does that. And the parameters from the URL are sent directly into that main query and used there.

The theme then determines what template to use based on what the query comes back with. If you requested /category/example, then that becomes ?category_name=example which means that the main $wp_query->query_vars array will get that information, and the WP_Query will pull out the last X posts for the “example” category, and it will set its is_category flag to true.

The template-loader will run after this, see that is_category() returns true, and decide to pick the category template, so it will look for category-example.php and fall back to category.php and so on, according to the Template Hierarchy.

So, the question if you want to change how URLs work is simple: Do you want to change the URLs, or what they are mapped to? Because URLs are not mapped to functions, they’re mapped to parameters that control the query. If you want have the URL adjust that main query, then it’s a slightly different process than if you want a special URL to run some totally other special code.

And to answer your specific question in the comments: “isn’t there cases where you don’t actually want to display posts?” No, there is not. Everything is a post. All content is stored in posts. If you want to store content elsewhere and be different, then you can do that, but it’s more difficult because, honestly, it’s not usually necessary. If you have special content, make a custom post type, store your content as a post with that type, map a URL pattern to it. Easy.

Leave a Comment