﻿id,summary,reporter,owner,description,type,status,priority,milestone,component,version,severity,resolution,keywords,cc
12935,Evolve the URL routing system,mikeschinkel,ryan,"As WordPress grows into a proper CMS with MultiSite and Custom Post Types and Custom Taxonomies there are frequent opportunities for URL conflict that didn't occur as often with just Posts and Pages. 

Here's a simple example, let's say a company uses WordPress for their website and they offer development services as well as training on their website:

{{{
http://example.com/services/vmware/
http://example.com/training/vmware/
}}}

Currently it's not possible for an end user to get that result, the best they can do is this:

{{{
http://example.com/services/vmware/
http://example.com/training/vmware-2/
}}}

One key problem is WordPress considers both post_names and URLs as globally unique and the current system of using full path regexes makes it very hard to discover paths from the routes, it's only possible to test paths against the routes.

'''I'd like to propose''' we add a ''backward compatible layer'' that allows WordPress and its theme and plugin developers to transition to a system where post_names are no longer required to be unique and '''URL routing would be specified on a path segment basis'''. This would mean that WordPress would maintain an internal tree structure of URL routes and it would traverse the tree instead of scanning a global list of URL routes. 

The overhead for smaller sites should be trivial but for larger sites that need to scan many URL routes it could make it easier to scale in size and complexity. It would also make special cases much easier to implement robustly without as much fear of breaking something that already exists.  This proposed solution would make it possible to more easy to discover and test routes. It would also make it possible to display a URL sitemap and to enable plugins to easily let users edit the site map and thus define URL routings.  It would also open up lots of flexibility in areas or URL routing where before it was just too difficult to address.

I'm envisioning this URL routing to have a lower priority than existing URL routing and by nature the community would slowly transition to this new system. WordPress would first check the older URL routing and if no matches then the new URL routing would be used. Core could transition all it's routes to the new system sometime in 3.x and then plugins could start transitioning over as well until, over time, most plugins and themes support the new system.  It would also be nice to have an advanced option (maybe via a define()d constant) that would disable the older URL routing system for a given site so that users, themers and plugin developers could ensure their plugins are using the new system only.

This is potentially a big change so while I'm very willing to tackle this with community support I don't want to write code yet but I do want to start the discussion.  However, here is a psuedo-code that illustrates the structure conceptually. Note the example includes a custom post type and also a custom URL of the structure to illustrate flexibility:

 http://example.com/2010/top10/

{{{
/*
This code demonstrates ONE potential structure for visualization and NOT how most route code would be built.
*/
function set_routes() {
  global $wp_routes;

  $post_routes = array('%postname%'=> array('type'=>'post'));

  $year_routes = array(
    'top10'   => array('type'=>'query','query'=>'post_type=post&taxonomy=post_tag&term=top10'),
    '%month%' => array('type'=>'query','query'=>'post_type=post&year=%_parent%&month=%month%','match'=>'/[1-2][0-9]/','routes'=>$post_routes),
  );
  $category_routes = array(
    '%category%'=> array('type'=>'query','query'=>'post_type=post&taxonomy=category&term=%category%'),
  );
  $tag_routes = array(
    '%tag%'=> array('type'=>'query','query'=>'post_type=post&taxonomy=post_tag&term=%tag%'),
  );
  $wp_routes = array(
    'about' => array('type'=>'page'),
    '%year%'  => array('type'=>'query','query'=>'post_type=post&year=%year%','match'=>'/[0-9]{4}/','routes'=>$year_routes),
    'products' => array('type'=>'post_list','post_type'=>'product'),
    'category' => array('type'=>'tax_list','taxonomy'=>'category','routes'=>$category_routes),
    'tag' => array('type'=>'tax_list','taxonomy'=>'post_tag','routes'=>$tag_routes),
  );
}
}}}
And here is what it looks like when using print_r():
{{{
Array
(
  [about] => Array
    (
      [type] => page
    )

  [%year%] => Array
    (
      [type] => query
      [query] => post_type=post&year=%year%
      [routes] => Array
        (
          [top10] => Array
            (
              [type] => query
              [query] => post_type=post&taxonomy=post_tag&term=top10
            )

          [%month%] => Array
            (
              [type] => query
              [query] => post_type=post&year=%_parent%&month=%month%
              [routes] => Array
                (
                  [%postname%] => Array
                    (
                      [type] => post
                    )

                )

            )

        )

    )

  [products] => Array
    (
      [type] => post_list
      [post_type] => product
    )

  [category] => Array
    (
      [type] => tax_list
      [taxonomy] => category
      [routes] => Array
        (
          [%category%] => Array
            (
              [type] => query
              [query] => post_type=post&taxonomy=category&term=%category%
            )

        )

    )

  [tag] => Array
    (
      [type] => tax_list
      [taxonomy] => post_tag
      [routes] => Array
        (
          [%tag%] => Array
            (
              [type] => query
              [query] => post_type=post&taxonomy=post_tag&term=%tag%
            )

        )

    )

)
}}}

BTW, these tickets are probably somewhat related and I believe this approach would make it much easier to resolve these issues:

 * #12884 - Taxonomy Pages aren't properly redirected on main site when using Multi Site Subdirectories 
 * #12002 - WPMU should not lock the root blog into using a /blog prefix on permalinks
 * #11279 - Support for putting all ""blog"" content under /blog/ 

And these requests/issues:

 * http://wordpress.org/extend/ideas/topic/remove-category-base-from-permalinks
 * http://wordpress.org/support/topic/302621
 * http://wordpress.org/support/topic/346242
 * http://en.forums.wordpress.com/topic/remove-date-in-the-url
 * http://wordpress.org/support/topic/264688
 * And just: http://www.google.com/search?q=wordpress+remove+category+from+url
",enhancement,closed,normal,,Permalinks,3.0,normal,wontfix,,ryanpc@… 24-7@… aesqe@… jacobsantos sorich87@… mailings@… jamie.richard
