Rewriting URLs in WordPress: Tips and Plugins

Recent updates to WordPress make it easier than ever for developers to personalize their websites. You can effortlessly modify your theme, switch out sidebar widgets, and even create your own custom PHP functions. One popular feature is the ability to customize URL permalinks to make them more user-friendly.

In this guide, we’ll explore different ways to modify WordPress’s default URL rewriting system. While some knowledge of PHP is helpful, the process is straightforward enough that you can simply copy and paste the code into your own template.

Understanding WP_Rewrite

If you’ve worked with mod_rewrite on Apache servers, you’ll find WordPress’s rewrite system quite similar. WordPress also uses an .htaccess file, but the rules are written in PHP. This gives you more flexibility in customizing your URLs.

For a deep dive, check out the $wp_rewrite class documentation. It’s filled with useful information and examples. You can add most of the code directly to your theme’s functions.php file. Let’s first explore the default rewrite rules that come with WordPress.

Content of $wp_rewrite->rules

By making the $wp_rewrite class global, you can access its internal data. Your custom rules will be stored in an array named $wp_rewrite->rules. Keep this variable in mind, as you’ll likely refer to it multiple times during development.

<div><code>
 <?php
 global $wp_rewrite;
 print_r($wp_rewrite->rules);
 ?>
</code></div>

I included this code snippet in my theme’s page.php file. It displays a large array that might seem confusing at first. However, if you View Source on your webpage, you’ll find it easier to understand how each rewrite rule corresponds to a specific filename. For instance, let’s examine the rules for category rewrites:

[category/(.+?)/?$] => index.php?category_name=$matches[1]

The part inside the brackets on the left is the Apache RewriteRule to look for. It starts with /category/ followed by any string of characters. When this pattern is matched, the server knows to use index.php?category_name= and replace the variable at the end.

How to Set Up Custom Permalinks

WordPress has a class called $wp_rewrite that offers various options for URL structures. You can access properties like $wp_rewrite->category_base or $wp_rewrite->author_base to get the default URL settings. You can also create your own custom URL rules.

Changing the Author URL Structure

When you visit the Permalinks settings in WordPress, you can change the URL structures for categories and tags. However, strangely, there’s no option to change the author URL structure.

You can use the add_rewrite_rule() function from WordPress to add new URL settings. For example, I’ve changed the default /author/ to /writer/. You can choose any base you like. Below is a code snippet that you can add to your theme’s functions.php file to make these changes.

add_action('init', 'add_author_rules');

function add_author_rules() {
  add_rewrite_rule(
    "writer/([^/]+)/?",
    "index.php?author_name=$matches[1]",
    "top"
  );

  add_rewrite_rule(
    "writer/([^/]+)/page/?([0-9]{1,})/?",
    "index.php?author_name=$matches[1]&paged=$matches[2]",
    "top"
  );

  add_rewrite_rule(
    "writer/([^/]+)/(feed|rdf|rss|rss2|atom)/?",
    "index.php?author_name=$matches[1]&feed=$matches[2]",
    "top"
  );

  add_rewrite_rule(
    "writer/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?",
    "index.php?author_name=$matches[1]&feed=$matches[2]",
    "top"
  );
}

You can use this function without needing the $wp_rewrite variable. Some developers prefer this approach because it’s easier than using class properties. However, be aware that this method may not work consistently for all WordPress setups. You can also add these rules after updating your .htaccess file (explained later).

How to Set Up Author URLs Using generate_rewrite_rules

To use this method, you’ll need to access the global $wp_rewrite class. Then, create a new variable called $new_rules that holds an array of data. The example code below sets up URL rewriting for basic author pages.

function generate_author_rewrite_rules() {
  global $wp_rewrite;
  $new_rules = array(
    "writer/([^/]+)/?" => "index.php?author_name=" . $wp_rewrite->preg_index(1)
  );
  $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}

If you want to include multiple pages and RSS feeds, you can expand the array. You can either create a PHP function to add more data to the array or separate the data blocks with commas. Here’s an updated version of the code:

function generate_author_rewrite_rules() {
  global $wp_rewrite;
  $new_rules = array(
    "writer/([^/]+)/?" => "index.php?author_name=" . $wp_rewrite->preg_index(1),
    "writer/([^/]+)/page/?([0-9]{1,})/?" => "index.php?author_name=" . $wp_rewrite->preg_index(1) . "&paged=" . $wp_rewrite->preg_index(2),
    "writer/([^/]+)/(feed|rdf|rss|rss2|atom)/?" => "index.php?author_name=" . $wp_rewrite->preg_index(1) . "&feed=" . $wp_rewrite->preg_index(2),
    "writer/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?" => "index.php?author_name=" . $wp_rewrite->preg_index(1) . "&feed=" . $wp_rewrite->preg_index(2)
  );
  $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}

Remember, these changes won’t take effect until you’ve updated the original URL rewrite rules. You’ll need to do this every time you modify these functions. After that, your new rules will stay in place.

How to Update URL Rewrite Rules

Changes to the URL rewrite code don’t happen instantly. You need to update the .htaccess file for the new code to work. Doing this every time a page loads is inefficient because it writes to the database and refreshes the .htaccess file.

A better way is to go to your permalinks page in the WordPress admin panel and save the changes again. This triggers a flush_rewrite_rules, so you don’t have to worry about loading issues for users. You only need to save the page once to update all the rules.

How to Use Non-WordPress Rules

In the $wp_rewrite class, you can find many options. One important option is $wp_rewrite->non_wp_rules. This is an array that stores redirects that don’t go through the index.php file.

This feature is commonly used in WordPress plugin development. For example, you can redirect a custom URL like /calendar/june-2012/ to a specific file in your website’s backend, like /wp-content/plugins/calendarplug/myscript.php. Below, you’ll find a detailed example that explains how to use this array for custom rewrite rules.

How to Hide Your Theme Files

Many WordPress users recommend hiding the actual paths to theme files. For instance, you might want to access files in the /wp-content/themes/mytheme/ folder using a cleaner URL. To do this, you’ll need to set up some special WordPress rewrite rules.

Normally, WordPress routes all content through a single file, usually index.php. But if you want to hide the paths to your theme files, you’ll need to set up rules for multiple files.

add_action('generate_rewrite_rules', 'themes_dir_add_rewrites');

function themes_dir_add_rewrites() {
  $theme_name = next(explode('/themes/', get_stylesheet_directory()));
  
  global $wp_rewrite;
  $new_non_wp_rules = array(
    'css/(.*)' => 'wp-content/themes/' . $theme_name . '/css/$1',
    'js/(.*)' => 'wp-content/themes/' . $theme_name . '/js/$1',
    'images/wordpress-urls-rewrite/(.*)' => 'wp-content/themes/' . $theme_name . '/images/wordpress-urls-rewrite/$1',
  );
  $wp_rewrite->non_wp_rules += $new_non_wp_rules;
}

I’ve created a new function called themes_dir_add_rewrites(). This function takes the long URLs and redirects them to shorter, cleaner ones. It uses the non_wp_rules option in the $wp_rewrite class, which allows for server-side handling instead of routing through WordPress’s index.php.

The advantage of using these non-WordPress rules is flexibility. You can still use the old URL format if you want. For example:

/wp-content/themes/mytheme/images/wordpress-urls-rewrite/logo.jpg

But it’s much cleaner to use:

/images/wordpress-urls-rewrite/logo.jpg instead.

Useful Tools and Plugins for URL Rewriting

If you’re new to coding custom URLs, don’t worry—it can be challenging at first. But practice makes perfect! To help you get started, here are some useful tools and plugins. You might not need all of them, but they’re great resources for anyone working with WordPress URL rewrites.

Monkeyman Rewrite Analyzer

This plugin is essential for beginners in URL rewriting. It doesn’t modify your website’s existing rules; it simply lets you test your code to see how URLs will redirect. It’s also useful for testing custom query variables for any custom post types.

Monkeyman Rewrite Analyzer interface
AskApache RewriteRules Viewer

This plugin is similar to Monkeyman Rewrite Analyzer, but it doesn’t allow you to test your own rules. Instead, it displays all the default WordPress rules and their corresponding redirects. It shows key properties of $wp_rewrite, like permalink settings and bases for pages, categories, and tags.

AskApache RewriteRules Viewer interface
WP htaccess Control

This plugin offers a different approach to creating new page redirects. It comes with an admin panel where you can edit various settings, including your author and page bases. You can also add your own custom .htaccess rules directly.

WP htaccess Control admin panel
Rewrite Rule Tester

This isn’t a WordPress plugin, but it’s a useful tool for testing rewrite rules. You can copy and test your rules without modifying your .htaccess file, making it easier to debug your code before going live.

Rewrite Rule Tester web application
DW ReWrite

DW ReWrite is a straightforward plugin that automatically creates three clean URLs for admin, login, and registration pages. It replaces the default, more complicated WordPress registration URL with simpler versions like /admin, /login, and /register.

Conclusion

I hope this guide helps you understand the basics of WordPress URL rewriting. WordPress is a popular CMS with constant updates and new features. Customizing your URLs can significantly enhance your website’s user experience and branding.

If you run into issues with your rewrite rules, don’t panic. You can easily revert the changes by deleting the function code and refreshing your .htaccess file. Feel free to explore more articles on this topic, and if you have any questions or comments, share them in the post discussion area.

WebsiteFacebookTwitterInstagramPinterestLinkedInGoogle+YoutubeRedditDribbbleBehanceGithubCodePenWhatsappEmail