spacer

Twisted WordPress: Non Unique URLs, Part 1

That's right my WordPress loving pals, you aren't being left out in the cold. Today I am starting a new tutorial series, affectionately called Twisted WordPress.

We are going to be focusing on doing twisted, insane, crazy things with and to WordPress. First up on my twisted list? Non Unique URLs.

Let's set the stage

Now friends, this isn't something that you will want to do often. Really, there are only one or two times when you would want to tackle this type of thing. Rare though it may be, when those moments come up, they can be incredibly important.

The only time I have seen a request for this come across my desk, that made sense, was when I was asked to modify WordPress to allow for non unique URLs on child categories. The site in question was a magazine/news type site and wanted to have a number of categories, that could contain any number of child cats, with the child cats having non-unique URLs.

For instance they wanted blue/websites and red/websites to both be possible. Seemed like a pretty sane request. This is how I did it.

First, we need a plugin

I'm a fan of writing your own stuff, but when someone else has done a bang up job of it, and the feature it provides is a small part of the overall picture, well it just makes good sense to not re-invent the wheel.

So if you haven't already, go download WP Category Meta from the WP Plugins site so we can get this show on the road!

WP Category Meta gives us a table to store some special data in, which is really the backbone of this little trick. Once you have installed and activated the plugin we need to create two records for our categories, choose the text type on both of them:

  1. non-unique-url — I am sure you are all a twitter, wondering what this is for :)
  2. parent — This might seem redundant, but it is easier to find the parent this way.

So, now we just need to create some parent and child cats! Go ahead and create two categories, with a child in each one, that has the same name. You will notice that when you create the second child, WP appends the parent categories slug to it, to ensure uniqueness. No worries, we won't be using that slug.

I'm going to create parent categories named Movies and Music, and in each of these will be a child category of iTunes.

Now, lets crack open the functions file for whatever theme you are using. We need to get busy writing some code in there. Let's look at our first method.

function is_subcat( $term ) {
   global $wpdb;
   $check = $wpdb->get_var( "SELECT terms_id FROM " . $wpdb->prefix . 
   "termsmeta WHERE meta_value = '" . $term . "' AND meta_key = 'non-unique-slug'" );
   if( $check == NULL ) {
      return false;
   } else {
      return true;
   }
}

add_action( 'pre_get_posts', 'enable_non_unique_subcats' );

Right. so lets break it down. First, lets take a look at is_subcat().

We pass in a string, in this case the slug of the category in question, and then check our termsmeta table for it. If we find a record that matches, the query returns the ID, if not it returns NULL. So we check for NULL in the next line, and if it is present we return false. Obviously if there is an ID found we return true.

Now that we have that out of the way, lets look at the method that makes all this magic work, enable_non_unique_subcats(). Trust me, it looks worse than it is.

function enable_non_unique_subcats( $query ) {	
   global $wpdb, $parent, $child;
   if( is_subcat($query->query_vars['attachment']) == true ) {
      $bits = explode('/', $_SERVER['REQUEST_URI'] );
      $c = array_pop( $bits );
      $p = array_pop( $bits );
      $parent = get_category_by_slug( $p );
      $ch = $wpdb->get_results( "SELECT terms_id FROM " . $wpdb->prefix . "termsmeta 
      WHERE meta_value = '" . $parent->slug . "' AND meta_key = 'parent'" );
      foreach( $ch as $chld ) {
            $candidates = $wpdb->get_results( "SELECT terms_id, meta_value FROM " . 
            $wpdb->prefix . "termsmeta WHERE terms_id = " . $chld->terms_id . " AND 
            meta_key = 'non-unique-slug'" );
            foreach( $candidates as $candies ) {
                  if( $candies->meta_value == $c ) {
                        $child = get_category($candies->terms_id);
                  }
            }
      }

      load_template( TEMPLATEPATH . '/subcat.php' );
   }
}

So, in this chunk of code, we are intercepting WordPresses query system, and overriding it if we find that the view we are calling is for on of our special subcategories. If we didn't do this, every time you tried to load a subcat with a non unique URL, it would 404.

First we call is_subcat() to check if we are indeed dealing with a special category. If true is returned we move onto handling our special case, if not we go on our merry way.

So, let's assume we have a special case category. Next we grab the URL from the server, and break it into its parts, splitting on the slash. Once we have a shiny new array of URL bits, we need to grab the last two members and process them. These two will be the child category and the parent category.

Call array_pop on the array, and bind it to $c for child, and the do our little dance again, this time binding it to $p for parent. Since you have done a little dance, feel free to make a little love. Maybe get down tonight. Your choice. Totally up to you.

Next we have to actually get the child and parent cats so we can you know, do stuff with them. Getting our parent is relatively simple. The bit we pulled out of the URL is the slug, so we just pass that to get_category_by_slug().

To get the child cat, that takes a little more work. Our URL contains the non unique slug after all, so we need to use that to find the ID of the category, and then use that to grab the category. And since a parent category could have any number of child cats, we need to grab all the children, and then loop over them to find the one that matches the non unique slug we began with.

Once we find our match, we pass the ID to get_category(), and voila! We have our child category. Since we global'ed parent and child at the opening of this method, all we need to do now is tell WordPress to load the subcat template file, and we are finished with this method.

Finally, we call add_action(); to tell WordPress that we want to run our new non_unique method anytime posts are queried.

Shoo, that was a lot of typing

While that was all awesome to build, without a way to display this majesty to the browser, we are kinda spinning our wheels. In part 2, we'll cover creating a new template file to house our subcats as well as look at some other methods we can add to more fully flesh out our new feature.

Should be fun! As always comments and questions are welcome.


Meta Info
  • d November, 16th 2012
  • v Chris J. Davis
  • t tutorials, wordpress and twisted
Gists
  • c Functions File
Prerequisites
  • s WordPress
  • s WP Category Meta
  • s A Sense of Adventure

This is not The greatest website in the world,
no, this is just a tribute. spacer

Get in Touch

Name

Email

Estimated Project Budget

Project Start Date

Project End Date

Message

Schedule Check

Through the magic of the internets we will check our schedule and let you know if we have availability for your project. Do we amaze you?

Take it away, Postman!

  • l
  • f
  • i
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.