Skip to content

Creating Your Own WordPress Permalink Structure For Custom Content

The latest feature I have added to WPVote is a page that shows you all pages submitted to the site for a specific domain. Below I will show how I created the custom permalink structure without creating custom pages.

The process took me a while to work out but it ended up being quite simple code. I wanted to have the urls in the format ‘’. I didn’t want to have to create custom pages, it was a feature that should ‘just work’ – so I created some custom WordPress rewrite rules.

You can check out this this page for Binary Moon to see what I ended up with.

The code required 3 PHP functions which I added to the themes functions.php file but the first thing I had to do was initialize a new WordPress query var which would be used later on. I added this to a function that is called on the init action, but it could just be added to the top of the functions.php file.

global $wp;

bm_parseQuery – Setup Query for The Loop

The first function hooks in when the WordPress query is being generated and, if the newly added variable is set, resets the page properties and adds a hook to load the template that will be used on the new path.

function bm_parseQuery() {
	global $wp_query;
	if (get_query_var('bmDomain') != '') {
		$wp_query->is_single = false;
		$wp_query->is_page = false;
		$wp_query->is_archive = false;
		$wp_query->is_search = false;
		$wp_query->is_home = false;
		add_action('template_redirect', 'bm_wpvoteTemplate');


bm_wpvoteTemplate – Execute the Template

The template function simply loads the relevant template file. I am using a custom template just for this page so that I can display just the posts for the specific website.

function bm_wpvoteTemplate() {
	global $template;
	if (get_query_var('bmDomain') != '') {
		$template = get_query_template('domain');
		include ($template);

bm_rewrite – The Rewrite Rules themselves

Adding the rewrite rules is relatively straight forward. It uses a simple regular expression to convert a url pattern into a website query string. My knowledge of regular expressions is quite limited but if I display all the existing rules (print_r($rules)) then it’s easy to work out what the new query should be.

In the case of my WPVote page, it converts the query from a pretty permalink to a traditional query string (which is exactly what happens to all the pages).

In the example I game above it would change this: domain/
into this: index.php?

I also added a second rule that would allow for domains with more than 1 page worth of post submissions.

One thing to note is that the new rules should be added to the start of the list. If you add the rule to the end then it won’t be reached as there are other rules that will catch it before you get there.

function bm_rewrite ($rules) {
	// add the rules
	$rules[]["domain/(.+?)/page/?([0-9]{1,})/?$"] = "index.php?bmDomain=\$matches[1]&paged=\$matches[2]";
	$rules[]["domain/(.+?)/?$"] = "index.php?bmDomain=\$matches[1]";
	return $rules;
add_filter( 'rewrite_rules_array', 'bm_rewrite' );

What Else?

The code above is quite specific to WPVote but I am sure there are areas that something like this could be used. It’s most useful for sites that do things that aren’t traditionally blog focused (since you could just use pages to do stuff like this).

I found this post quite hard to write in an understandable way so if you need further explanation please feel free to ask me to elaborate in the comments and I will try to be clearer

Ben View All

Ben is a lifelong Nintendo fan who also likes to build websites, and develop games. He also buys way too much Lego.

23 thoughts on “Creating Your Own WordPress Permalink Structure For Custom Content Leave a comment

  1. I have been looking for a better way to link to urls associated with a contact and I believe this would work great.

    Thanks for sharing!

    • Glad my post helped 🙂 Just checked out your application as well. Looks quite cool – I’ve been thinking about setting up some sort of crm theme as well!

      • Its definitely a challenging field as there are so many competitors but the tutorials that you and Justin Tadlock, among others, have written have saved me a year in programing time and thousands of dollars. The version I am preparing for WP3.0 will be hosted in an Edublog fashion so if you do decide to create a crm theme let me know, maybe we can work something out. 🙂

  2. Awesome post. I’ve bookmarked this post. By the way, the plugin WP-Download Manager has another way to create permalink structure. I think you are interested in this.

  3. Pingback: 2 weeks in and more new features for WPVote › WordPress Vote
  4. Pingback: Top Worthwhile Tutorials of the Week – #3 | AEXT.NET
  5. Very interesting Ben,

    I was faced with doing something similar recently and took a different approach:

    Instead of rewriting, I ran a filter on the_posts which parses the URL ($wp->request). If the trigger parameter isn’t present it just returns the $posts (ie whatever was in there before the filter was run). If it finds the trigger, it creates a virtual post and returns that.

    I roughly based the virtual post creation on this:

    Via the plugin, I can set the post content ($post->post_content), post title ($post->post_title) etc.

    Anyway, if I’d found your post first, I could have used that, but my approach works well enough for me.

    • Hey Stephen, thanks for the info. that’s an interesting approach as well – I hadn’t considered doing something like that. Thanks for the link too – it explains the concept well.

  6. Pingback: BlogBuzz February 27, 2010
  7. Pingback: Top Worthwhile Tutorials of the Week – #3 | Web Development News
  8. Pingback: What do you want me to write about?
  9. I ran a filter on the_posts which parses the URL ($wp->request). If the trigger parameter isn’t present it just returns

  10. I’m trying to use this for a plugin I’m writing, but I can’t figure out where I need to hook the bm_rewrite function into..

  11. so nice. Thanks for explaining so well, I have been looking for this information for quite some time because I really didn’t want to have to create pages manually and add shortcodes to the content to do what I wanted.

    Unfortunately, it took me so long to find this that I’m 90% through the plugin code that uses manually added pages! 🙁 .. never mind, it’s not a plugin I’m releasing.

    I’ll get to use this in a future plugin (or on the second version of this current one!)

    thanks again, great tutorial

    • Hey Andy – glad you found this useful. I have used the functionality on a couple of sites now and it’s worked surprisingly well. It really helps to turn WordPress into a fully fledged cms creating exactly what you need.

      • I think I’m gonna try and use it in this current project, I’ve found I need to show a popup that will need a custom template that can use wordpress functions. This might do the trick!

  12. I think something is wrong. Where will we call ‘bm_rewrite’ function?
    I tried add_filter(‘rewrite_rules_array’,’bm_rewrite’); but it gives error.
    I resaved my permalink settings but it didn’t work.

  13. Pingback: Extend Wordpress Permalinks to create Virtual Pages and Folders | DEEP in PHP
  14. Im fighting write now with permalink with wordpress.
    on my website I wrote simply plugin to just get last 4 post from my blog and now I need to create nice url like I had set in wordpress %category%post_name anyone knows how to create urls ?

Leave a Reply

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