How To Change Your WordPress Category, Tag, or Post Format Permalink Structure

By | Tutorial | 3 Comments

There are five default WordPress taxonomies: category, post_tag, post_format, nav_menu, and link_category – but nav_menu and link_category are off in a world of their own so let’s pretend they don’t exist for now. All of the settings for these taxonomies are preset by the fine folks at WordPress, and hard-coded into WordPress core, so if you want to make any changes, you have to do a little work.

The category, post_tag, and post_format default slugs, or permalinks, are simple. Categories are preceded by the slug ‘category’, post tags are preceded by the slug ‘tag’, and post formats are preceded by the slug ‘type’. In other words…

But what if you wanted to change the slug to something else? Or get rid of it altogether?

Changing the Slug

Changing the category/tag slug is pretty simple. The base for the slugs are stored as options so all you have to do is hook into the ‘pre_option_{option name}’ filter that’s applied when options are retrieved, allowing you to change the value that’s returned. The category slug’s option name is ‘category_base’ and the tag slug’s option name is ‘tag_base’ so the filters are ‘pre_option_category_base’ and ‘pre_option_tag_base’.

Changing the post format slug is a little different. The base is not stored as a option but it does have a filter: ‘post_format_rewrite_base’.

The following code will, most likely, go in your functions.php file. Remember that filters must always return a value. Learn more about filters.

add_filter( 'pre_option_category_base', 'mysite_change_category_base' );
function mysite_change_category_base( $value ) {
   // let's change our category slug to rantings
   // this will change the permalink to http://wpdreamer.com/rantings/wordpress/
   return 'rantings';


add_filter( 'pre_option_tag_base', 'mysite_change_tag_base' );
function mysite_change_tag_base( $value ) {
   // let's change our tag slug to ravings
   // this will change the permalink to http://wpdreamer.com/ravings/custom-post-types/
   return 'ravings';

add_filter( 'post_format_rewrite_base', 'mysite_change_post_format_base' );
function mysite_change_post_format_base( $value ) {
   // let's change our tag slug to fanciness
   // this will change the permalink to http://wpdreamer.com/fanciness/video/
   return 'fanciness';


Removing The Slug

Removing the slug altogether requires a different workaround, but it’s still pretty simple.

When WordPress registers these default taxonomies, the register_taxonomy() function adds a permastruct for each taxonomy that registers its permalink structure. All you need to do is overwrite the permastruct with your own.

These taxonomies and permastructs are registered during the ‘init’ action on priority level 0 (highest priority) so we’ll add our own hook into the ‘init’ action, but give it a lower priority so it’s executed after WordPress does its thing.

The following code will, most likely, go in your functions.php file. Learn more about actions.

Heads up: I don’t recommend removing the slug from categories, tags AND post formats. In fact, I wouldn’t recommend removing the slug from more than one of these taxonomies because then WordPress would have a very difficult time figuring out your URLs. The code for removing all three is only shown together so you can pick which set you need.

If you still want to remove multiple slugs, or if you’re having issues with your changes, I recommend installing the Rewrite Rules Inspector plugin. It shows you all of your rewrites and allows you to filter out which rewrites match a specific URL.

// make sure our action's priority is lower than 0,
// which is the highest priority, so basically any
// number greater than 0 will do. let's go with 1.
add_action( 'init', 'mysite_change_taxonomy_permalinks', 1 );
function mysite_change_taxonomy_permalinks() {

   // changing the category permastruct
   $taxonomy = 'category';
   // change the settings at will but make sure 'slug' is set to NULL
   $category_rewrite = array(
      'hierarchical' => true, // categories are defaulty hierarchical
      'slug' => NULL, // we don't want no slug!
      'with_front' => false, // this is up to you
      'ep_mask' => EP_CATEGORIES // this is a constant set by WordPress we'll use
   // overwrites default category permastruct
   add_permastruct( $taxonomy, "%$taxonomy%", $category_rewrite );
   // ----------------------------------
   // changing the post_tag permastruct
   $taxonomy = 'post_tag';
   // change the settings at will but make sure 'slug' is set to NULL
   $post_tag_rewrite = array(
      'slug' => NULL, // we don't want no slug!
      'with_front' => false, // this is up to you
      'ep_mask' => EP_TAGS // this is a constant set by WordPress we'll use
   // overwrites default post_tag permastruct
   add_permastruct( $taxonomy, "%$taxonomy%", $post_tag_rewrite );
   // ----------------------------------
   // changing the post_format permastruct
   $taxonomy = 'post_format';
   // change the settings at will but make sure 'slug' is set to NULL
   $post_format_rewrite = array(
      'slug' => NULL, // we don't want no slug!
   // overwrites default post_format permastruct
   add_permastruct( $taxonomy, "%$taxonomy%", $post_format_rewrite );


Heads up: Sometimes messing with permalink settings requires you flush your system’s rewrite rules in order for the changes to take place. But they only need to be flushed once, each time you make a change, and not every time a page loads. To flush your rules, go to Settings -> Permalinks and click “Save Changes”.

CPT-onomies Update: Version 1.3 (MULTISITE!)

By | CPT-onomies, Plugins, Uncategorized, WordPress | 3 Comments
Download CPT-onomiesCPT-onomies Documentation

I’m pretty excited about this update and multisite compatibility is the reason why! As someone who manages a pretty vast multisite network, I think WordPress multisite is awesome and hope others find this new functionality useful as well.

But version 1.3 didn’t present itself solely bearing the fruits of multisite. Here’s the full list of improvements:

  • Added multisite custom post type manager.
  • Added setting to assign meta box format, i.e. autocomplete, checklist or dropdown.
  • Added “Show Admin Column” to the CPT-onomy settings.
    • This is a new register_taxonomy() setting as of WordPress 3.5.
    • Before, CPT-onomies added the column itself but will now hook into this new core taxonomy functionality.
    • I will retain backwards compatability for a little while.
  • Deprecated the ability to make the CPT-onomy admin columns sortable in order to align with new, core WP taxonomy admin column functionality.
    • The new core WordPress taxonomy admin columns are not sortable so, therefore, I’ve removed the column sort functionality from the plugin.
  • Deprecated the ‘custom_post_type_onomies_add_cpt_onomy_admin_sortable_column’ filter.
    • Before, you could use this filter to turn off the column sortability. Now, with sorting gone, there’s no need to have the filter.
  • Added support for the “Gravity Forms + Custom Post Types” plugin.
    • This particular feature was commissioned by a user and will allow you to create CPT-onomy relationships when you use a Gravity Forms form to create a custom post type post.
  • Added the ability to only include/assign specific terms by passing term IDs to a filter.
    • Like the previously added “exclude” filter, this filter allows you to designate that you only want specific CPT-onomy term(s) to be allowed to be assigned.
  • Added wp_set_post_terms() to the CPT-onomy class.

Hope you the enjoy the update. I already have ideas for the next round! And, as always, please let me know if you have any questions or find any bugs! Thanks!

CPT-onomies Update: Version 1.1

By | CPT-onomies, WordPress | 4 Comments
Download CPT-onomiesCPT-onomies Documentation

It took me long enough but the next version of CPT-onomies has finally shipped out! And, with it, some pretty cool new features:

  • Programmatically register your CPT-onomies
    • Much kudos and thanks to Travis Smith for the assist with this one!
  • When assigning CPT-onomy terms on the “edit post” page, choose from three different formats:
    • a checklist (same ole, same ole),
    • an autocomplete box (a pretty cool one, I might add),
    • and a select dropdown (for when you only want to select one term)
  • Customize the CPT-onomy archive page slug
    • Before, you were pretty much stuck with “{post type}/tax/{term slug}” (which is still the default) but now, via the settings panel, you can use your own keywords with a little help from the variables $post_type, $term_slug and $term_id. Don’t forget to flush/reset your rewrite rules once you’re finished!
  • Tell the CPT-onomy tag cloud widget whether you want the terms to link to their archive page or to their custom post type post page
  • When you’re using wp_get_object_terms() to request term information, you can now specify term ids to exclude from your results
  • The CPT-onomy class has a new function! Introducing get_term_ancestors(). I think it’s a little self-explanatory =)
  • CPT-onomies now supports Internationalization (can’t believe it took me so long!)
  • I also tweaked the UI and fixed a few bugs

I hope everyone enjoys the update as much as I do. Sorry it took me so long. My life has been a little crazy but I’m glad to be on the other side of the hiatus!

Please let me know if you have any questions or find any bugs! Thanks for being such awesome users!!

CPT-onomies Documentation is Up and Running

By | CPT-onomies, WordPress | No Comments
Download CPT-onomiesCPT-onomies Documentation

CPT-onomies is a WordPress plugin that allows you to create, and use, taxonomies powered by your custom post types, using the post titles as the taxonomy terms. The best part about CPT-onomies is that they work just like regular taxonomies and therefore use the same functions!

Unfortunately, not every taxonomy function works right now but don’t worry, I’ve created CPT-onomy functions to help bridge the gap between WordPress and the plugin. The CPT-onomy functions even mirror the WordPress functions, using the same parameters and return values.

Use the CPT-onomies Documentation to see which WordPress taxonomy functions work and when you’ll need to use a CPT-onomy function. The documentation also includes function parameters, return values, examples, and other helpful information.

If you notice a mistake, or have a function request, feel free to leave a comment or contact me.

CPT-onomies: Using Custom Post Types as Taxonomies

By | CPT-onomies, WordPress | No Comments

If you’ve ever used a WordPress custom post type or taxonomy, you know that they can be powerful tools for creating and organizing content. But what if I told you that you could take these features a step further and create relationships between your post types, using your post titles to assign taxonomy relationships?

Introducing “CPT-onomies: Using Custom Post Types as Taxonomies“:

Humble beginnings

When I was first building http://eng.ua.edu, I knew that custom post types would play a huge role (and basically take over my life). With numerous post types, I wanted to establish a dynamic “People” directory that would connect each person to the “Departments” they worked for, the “Buildings” they worked in, the “Capstone Engineers” they were featured in (our research magazine), and any other content available.

In came custom taxonomies. I created taxonomies that “mirrored” each custom post type (using the post title as terms) and, voila, a dynamic and easily filtered people directory was born! But while managing the “Buildings” taxonomy was easy (buildings don’t exactly come and go on a daily basis), imagine managing a list of 200+ people and having to make sure the “People” taxonomy always matched the “People” custom post type. It’s more than just managing the titles, you have to make sure the slugs match too! Let’s just say that system didn’t last long.

From Idea to Plugin

While the premise of being able to use custom post types as taxonomies, and not having to duplicate information, was always the root of the project, “CPT-onomies” has taken several forms. At first, it wasn’t even a plugin, it was in my theme. When it progressed to a plugin, it was just for personal use and was very rough around the edges, using all kinds of WordPress hacks in a devil-may-care manner. To give me some credit, I had only been using WordPress for a few months and was on a strict redesign schedule. “Behind the scenes” was not a high priority.

But the website launched, my WordPress skills grew, and before I knew it I was saying things like “I bet I’m not the only one who could use this setup” and “This system of using custom post types as taxonomies would make a great plugin”. Little did I know how much fun I would have over the next few weeks.

Developing CPT-onomies

It wasn’t until I started development that I came up with the idea to hook into WordPress core and register the custom post type taxonomies as actual taxonomies. Once this decision was made, the project grew tenfold but, boy, was it worth it. Not only did it make the plugin stronger but it kept the user from having to learn or implement new code. That, in itself, was worth every minute of development. Tack on an extensive custom post type manager, so the user can manage their custom post types within the admin, and you’ve got yourself a pretty powerful plugin. Is CPT-onomy an official WordPress term? No. It’s just a fun word I made up. =)

Using CPT-onomies

One of the best features of the CPT-onomies plugin is that you don’t have to create CPT-onomies to put the plugin to good use. Featuring a full-fledged interface, CPT-onomies allows you to create custom post types, and manage them, without touching one line of code! If you’re already using a plugin, or theme, that creates custom post types, don’t worry, CPT-onomies is all-inclusive. Any registered custom post type can be used as a CPT-onomy.

Learn more about CPT-onomies or download CPT-onomies. Refer to the plugin’s support forums or my CPT-onomies section if you ever need any help. If you can’t find what you need, or come across any bugs, please let me know.

I hope you enjoy using CPT-onomies as much as I enjoyed bringing it to life.