Pippins Plugins
  • Email
  • Facebook
  • Feedburner
  • Github
  • Google
  • Twitter
  • Vimeo
  • Youtube
  • Rss
  • About
  • News
  • Join the Site
    • Member Benefits
    • Member Plugins
    • Email Notifications
  • Plugin Store
    • Affiliate Area
    • Checkout
  • Plugins
    • Plugin Portfolio
      • Plugin Portfolio – List View
    • Free
    • Premium
    • Member Plugins
    • Coding Standards
    • Get Plugin Support
  • Tutorials
    • Series
      • Plugin Development 101
      • Creating a User Follow System Plugin
      • Customizing Restrict Content Pro
      • Displaying Content with Easy Content Types
      • Writing Your First WordPress Plugins, Basic to Advanced
      • Working with Widgets
      • User Submitted Image Galleries
      • Plugin Thoughts
      • Integrating Stripe.com with WordPress
      • WordPress Rewrite API
    • Member Exclusive
      • Free Members
      • Subscriber Only
    • Difficulty
      • Beginner
      • Intermediate
      • Advanced
    • Action and Filter Hooks
    • Ajax
    • Custom Post Types
    • External APIs
    • Short Codes
    • Taxonomies
    • Video Tutorials
    • Widget Tutorials
    • WordPress Admin / Dashboard
    • Working with jQuery
    • WordPress Database
    • Writing Plugins
    • Tag Index
  • Reviews
  • Support Forum
  • Contact
    • Support the Site
    • Request Code Review
    • Plugin Support

WordPress Rewrite API – Part 1

Posted on February 29, 2012 by Abid Omar in Advanced, Tutorials 13 Comments
Home» Tutorials » Advanced » WordPress Rewrite API – Part 1
Tweet
Love It - 0
This entry is part 1 of 3 in the WordPress Rewrite API Series
WordPress Rewrite API – Part 2 →
  • WordPress Rewrite API – Part 1
  • WordPress Rewrite API – Part 2
  • WordPress Rewrite API – Part 3

The Rewrite API for WordPress is one of the most overlooked features, yet it provides some unparalleled functionality that drastically improves user experience. This tutorial aims to help you understand how the WordPress URL Rewrite engine works and the different uses of this API.

Why use the Rewrite API? An Introduction to Smart Permalinks

That should be the first question. If you have installed previously and worked with WordPress on an Apache server, you have probably used the Rewrite API even though you didn’t have to deal with it directly.

By default, when WordPress is installed, all blog posts and pages URLs are written in this format

  • http://example.com/index.php?p=1
  • http://example.com/index.php?p=5&category=7&product=15

This is the URL for the first blog post on your freshly installed blog. This is the default way WordPress handles URLs and it works pretty much without any problems. There are a few issues with this format, though.

  1. It’s barely readable. For the average Internet user, it looks cryptographic.
  2. It’s not SEO-friendly.
  3. Hardly memorable, and sometimes the URL is quite long for sharing.

Enough reasons to improve our URL format. Here is the right way of doing it:

  • http://example.com/first-blog-post
  • http://example.com/computers/laptops/hp

This format is a lot better. It’s more readable, SEO friendly, and short. If you don’t know about URL rewriting, it’s fair to ask how this can work. The path for the computers/laptops/hp does not actually exist on the server. This is why we call it URL rewriting; when the URL doesn’t exist as a physical path, we redirect it to another location but without changing the URL in the address bar. But how the URL is being rewritten in WordPress?

The .htaccess file

If you have setup WordPress on an Apache server with the mod_rewrite module, it’ll work out of the box for you. Check the .htaccess file on the WordPress install root directory and open it. You should find this.

< IfModule mod_rewrite.c >
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
< /IfModule >

Looks terrible, right? It’s not actually hard to understand. The file will apply a simple rule. It’ll redirect any URL request to index.php, but only if two conditions are valid: When the requested file name is either invalid or doesn’t exist. The conditions will prevent the redirection of valid URL, like an image URL.

For example, http://example.com/my-blog-post will be redirected to http://example.com/index.php; whereas http://example.com/image.png will still give the actual image file. It’s worth mentioning again that this is not a true redirect. The address bar will still display the the smart link. Wikipedia page has a concise article about URL rewriting.

WordPress permalinks settings

Enabling URL rewriting for WordPress is pretty straightforward, assuming you’d setup the redirection correctly (it’s done for you on Apache, just make sure you have the mod_rewrite module installed).

The Settings > Permalinks page is where you change the settings for URLs. I’m using a custom structure which renders URLs as http://example.com/post_name

This is good so far, but pretty limited. What if you want to shorten a blog post URL to make it even easier for sharing? The real blog post URL is http://example.com/2012_free_wordpress_plugins and you want to make it http://example.com/freemium to make sharing and remembering the URL easier.

The settings panel is limited, but WordPress is not. The rewrite API is open, and you can play with it and customize it. First, I’ll explain how the rewrite API actually works, and then I’ll show off an example. Don’t jump the rewrite API basics; it’s necessary to expand your knowledge beyond the trivial example.

How the Rewrite API works?

If you have tried messing up with the rewrite API before this tutorial, you might think it’s a complicated and sophisticated mechanism that WordPress runs. It’s not. It’s actually pretty simple.

  1. You request a URL. (like http://example.com/blog-post)
  2. If the resource exists (like an image or a font), the resource is returned.
  3. If the resource doesn’t exist, the request is redirected to index.php.
  4. WordPress displays the page accordingly.

It’s that simple. Now you might think that if WordPress displayed the page correctly, it has some schema that defines every URL and the end point or the results to display. It certainly doesn’t guess which page it will be.

Where WordPress hides this schema?

You are certainly curious to see how this schema looks. Okay, I have put down this bit of code. It’s a small WordPress plug-in that will print the schema object (from now on, we’ll be calling it $wp_rewrite). Create a new file, put this bit of code in it, save it in your plugins directory and load your WordPress blog (any page)

1
2
3
4
5
6
7
8
9
10
11
12
<?php
/*
  Plugin Name: URL Rewrite
  Description: Testing the WordPress Rewrite API
  Author: Abid Omar
 */
add_action('template_redirect', 'ao_dump_rewrite');
function ao_dump_rewrite() {
  global $wp_rewrite;
  var_dump($wp_rewrite);
}
?>

The $wp_rewrite object

Depending on your WordPress blog configuration (and what plug-ins, custom taxonomies and other things you setup there), your $wp_rewrite object will vary in size. But if you look carefully (and you have x_debug which will beautify this bunch of text), the object structure is the following:

WP_Rewrite Object (
	public 'permalink_structure' => string '/%postname%/' (length=12)
	public 'use_trailing_slashes' => boolean true
	public 'author_base' => string 'author' (length=6)...
	[rules] = > Array (
		[category/(.+?)/?$] = > index.php?category_name=$matches[1]
		[tag/([^/]+)/page/?([0-9]{1,})/?$] = > index.php?tag=$matches[1] & paged=$matches[2]
		[tag/([^/]+)/?$] = > index.php?tag=$matches[1]
		[(.+?)/trackback/?$] = > index.php?pagename=$matches[1] & tb=1
		...
	)
	[rewritecode] = > Array ()
	...
	)

That was, certainly, a small part of my $wp_rewrite object. I wanted to emphasize on this snippet the rules array. This is actually the real schema. It’s like a map. It links every URL structure to, well, another URL structure. Do you remember what our URLs looked like before changing them from the permalinks panel?

  • http://example.com/index.php?p=1

That’s actually how WordPress loads every page: by reading the URL parameters. Now that we changed our URL structure to something smarter like:

  • http://example.com/blog_post

It looks like the old format was removed and WordPress is using a new one. It’s actually not true. WordPress is always using the same old-fashioned structure, but now it has a map between the smart URLs and the old URLs. It uses the map to link between them.

So for http://example.com/blog_post WordPress will actually call http://example.com/index.php?p=1 and will use the $wp_rewrite object to figure out the destination URL. Let’s take a look at how one rewrite rule looks.

'page/?([0-9]{1,})/?$' => string 'index.php?&paged=$matches[1]' (length=28)

The array key is our smart URL or how it should look like. It is obvious here that it’s a regular expression. The matched pattern is ‘page/{{some_digit}}’, and the end point is ‘index.php?&paged={{some_digit}}’.

This means that WordPress will match any http://example.com/page/2 (or any other number instead of 2) and redirects it to http://example.com/index.php?&paged=2

Shortening a blog post URL

Now we are going to put this knowledge into some real life stuff. The application is pretty simple and straightforward. We are going to shorten a long blog post URL to a tiny one. One may wonders why go this route since we can simply do it in the WordPress edit blog post page. Well, there are a couple of reasons for that.

First, this is aimed to teach how to work with the Rewrite API and to start with something simple. Second, this can be applied to pretty much any URL in WordPress, not just a blog post URL.

So let’s start. First, create a blog post with the name “2012 Free WordPress Plugins“. If you have the permalink structure set to %postname%, your URL will look something like this: http://example.com/2012-free-wordpress-plugins/

Not bad, but you are looking to share this on viral networking sites like Twitter. You don’t want your URL to be too long because these sites put restrictions on how much characters you can use. You want it to be http://example.com/freemium

Do you still remember the rules array in the $wp_rewrite object? That one magical map that WordPress uses to relay between smart URLs and classic URLs. If we hack this schema, we can probably get WordPress to redirect our http://example.com/freemium to the desired blog post. Fine. How to start then?

  1. Define your target. The target is the array key. It’s the Smart URL format. We said earlier that it’s a regular expression format. Regex are easy to use but don’t worry we are not going to use them since our pattern is easy. Our pattern is ‘freemium’. That’s what we want to match.
  2. Define your destination. Your destination is the blog post. But that destination should be written in the old classic URL format. That is ‘index.php?p=post_number’. To find the post number, click the “Get Shortlink” button when editing your post. If you don’t find that button, revert to the old permalink style and you’ll find the post number.

That’s it. Now, let’s edit the $wp_rewrite object. Remember our old plug-in? Well, replace the PHP code with the following

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
/*
  Plugin Name: URL Rewrite
  Description: Testing the WordPress Rewrite API
  Author: Abid Omar
 */
 
add_action( 'init', 'ao_add_rewrite_rule');
function ao_add_rewrite_rule() {
  add_rewrite_rule( 'freemium', 'index.php?&p=15', 'top');
  flush_rewrite_rules();
}
?>

Who said it is hard? You may wonder about a couple things

  1. The add_rewrite_rule() function will add a new rule to the $wp_rewrite object.
  2. The flush_rewrite_rules() function will order WordPress to rebuild the $wp_rewrite object. This is required since we changed our object. It’s a bad practice, however, to call this function everytime the page is loaded since it’s an unnecessary overhead. Place this function on the activation and deactivation actions of your plug-in to make it execute only once. I have used the init hook only for demonstrative purposes.

You can use the first snippet of code to print your $wp_rewrite object. You’ will find your newly added rule in the rules array.

Moving forward

This was an introduction to the rewrite API. In this tutorial, I wanted to show the ABC of URL rewriting in WordPress. It’s worth mentioning that this is just a small bit of it. It helps you grasp the basics of fundamentals. In the next tutorial, we are going to delve deeper on how WordPress actually does the URL redirect and make more practical examples with it.

Abid Omar

Abid Omar is an independent consultant specializing in HTML5 , JavaScript and WordPress. He is located in Sunny Tunisia.
Tweet Follow @pippinsplugins
Abid Omar, htaccess, permalink, rewrite

13 comments on “WordPress Rewrite API – Part 1”

  1. Ryan Duff says:
    February 29, 2012 at 8:02 pm

    While you can pass anon functions… it’s not exactly best practice. In saving what some call defining an “unnecessary” function, you take away the ability for someone else to remove that action.

    See this for clarification: http://codex.wordpress.org/Function_Reference/add_action#Take_Arguments

    I hope you consider changing the code examples before others read and unknowingly pickup this bad practice without understanding the consequences.

    Reply
    • Pippin says:
      March 1, 2012 at 7:35 pm

      Yep, you’re completely right, Ryan. I’ve updated Abid’s code with non-anonymous functions.

    • Abid Omar says:
      March 2, 2012 at 5:49 am

      Good catch. I wasn’t aware of it, however, it’s giving me a clue on how to hook functions that can’t get removed thereafter.

    • Pippin says:
      March 2, 2012 at 10:13 am

      Why would you want a function that can’t get removed afterwards?

    • Abid Omar says:
      March 2, 2012 at 2:33 pm

      No, I was thinking about hooking a function that can’t get removed by someone else. However, probably the remove_action hook will remove all hooks even if it’s anonymous.

  2. Paul says:
    March 2, 2012 at 12:07 pm

    is it possible to remove the custom taxonomy base using rewrite rules or will it break WP?
    for example:
    http://example.com/food-types/healthy/ to http://example.com/healthy/

    Reply
    • Pippin says:
      March 2, 2012 at 12:09 pm

      Yes, that is possible. See this Stack Exchange thread: http://wordpress.stackexchange.com/questions/6342/remove-custom-taxonomy-base

  3. takemura says:
    March 4, 2012 at 4:19 am

    Thank you for sharing this insight…

    I’m wondering if it is possible to use this API technique to automatically shorten URLs based on a shortened version of our website?

    For example, let’s say we have the following post:

    http://www.wesellcandles.com/2012/03/04/my-really-long-post-title-is-too-long/

    But we also registered a short version of our domain, something like: candl.es

    We don’t want the short domain to be a public URL shortening service, we only need it to create shorter versions of our own main domain.

    So, in this scenario we will simply append the post ID of our main site. In the case of above let’s say the post ID is 15, then the short version will simply be candl.es/15

    Is it possible to use the API to do something like this?

    Reply
    • Pippin says:
      March 4, 2012 at 11:26 am

      That is definitely possible! Abid’s simple example is almost everything you need, in fact. You could, of course, expand it to include a “Get Short Link” option in the post editor (similar to the default one) so that you have an easy way to get the exact URL.

    • Abid Omar says:
      March 5, 2012 at 4:53 am

      though it’s possible, I don’t think it’s the best thing to do. Loading the whole WordPress base and making a database query is very expensive for a URL redirect. I’d suggest that you go with a pure PHP solution. It’ll be faster and cheaper.

  4. takemura says:
    March 5, 2012 at 5:08 am

    Thanks guys. I agree, it does seem to be possibly but probably not the best solution. We have a Bit.ly Pro account which is set up to use our own short domain.

    I see there are a few plugins which can create a shortened URL for each post, including one by the esteemed Yoast. The added benefit of this approach is we can get access to Bit.ly’s stats.

    Reply
  5. Abdullah says:
    June 20, 2012 at 5:07 am

    Hi,

    Its posibble?

    mydomain.com/greeat-long-url

    to rewrite

    mydomain.com/global/greeat-long-url

    and also

    mydomain.com/parentpage/subpage

    to rewrite

    mydomain.com/global/subpage

    Means i want to short large url string to “global” and after that the acutual post permalink show.

    I am using wordpress :)

    Need help.

    Reply
    • Pippin says:
      June 20, 2012 at 11:55 am

      When someone goes to the URL mydomain.com/global/subpage or mydomain.com/global/greeat-long-url, do you want them redirected to the actual URL (so they see the new URL in their browser bar), or do you want them to still see the URL with /global/ in it?

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

  • Login

Lost your password?

Please enter your username or e-mail address. You will receive a new password via e-mail.

  • Facebook Become a Fan Like

  • Twitter Subscribe on Twitter Follow

  • YouTube Follow my Videos Subscribe

  • RSS Feed Subscribe with RSS Subscribe

Easy Digital Downloads

Most Loved

  • Love It Pro for WordPress
  • Write a “Love It” Plugin with Ajax to Let Users Love Their Favorite Posts / Pages
  • Simple Notices Pro Plugin for WordPress
  • User Bookmarks for WordPress
  • Front End Registration and Login Forms Plugin

Similar Plugins and Posts

  • WordPress Rewrite API – Part 3
  • WordPress Rewrite API – Part 2

Latest Premium Content

  • Plugin Development 101 – Introduction to Adding Dashboard Menus
  • Plugin Development 101 – Intro to Loading Scripts and Styles
  • User Follow System – Part 5
  • Plugin Development 101 – Intro to Short Codes
  • Plugin Development 101 – Registering a Custom Post Type
  • Plugin Development 101 – Intro to Actions

Latest Tutorials

  • Submitting Your First Pull Request to a WordPress Plugin on Github (2)

    Github is an extremely popular tool for managing WordPress plugins, and one...

  • Plugin Development 101 – Introduction to Adding Dashboard Menus (1)

    Adding new menus, both top level and sub level, to the WordPress Dashboard is a really common task for plugins...

  • Plugin Development 101 – Intro to Loading Scripts and Styles (16)

    In this part of Plugin...

Enter your email to receive automated updates when new posts are published

Latest Tweets

  • @jaredatch @kimparsell :D
    May 23, 2013
  • @jaredatch there is, as long as there is at least one ticket
    May 23, 2013
  • RT @Astoundify: We are hiring p/t tech support rep for our support forum if your interested email contact [at] http://t.co/bcXNhcwZx5
    May 23, 2013

Topics

featured Sugar Event Calendar register_setting add_shortcode campaign monitor meta box Rémi Corson Tom McFarlin the_content wp_enqueue_script add_options_page shortcodes contextual help forms do_action short codes mail chimp login authors attachment Related posts image plugin comments apply_filters post types bbpress recent posts short code taxonomies custom post type Ajax images gallery Stripe taxonomy jquery widgets users add_filter easy content types add_action widget restrict content pro easy digital downloads

Weekly Newsletter

Useful Links

  • Join the Site
  • Plugin Store
  • Affiliate Area
  • Tag Index
  • Support the Site
  • Suggest a Tutorial
  • Random Post
  • Contact

Monthly Archives

(c) 2011 Pippin's Plugins