[wp-trac] [WordPress Trac] #13490: Permalinks Issues for Custom Post Types with Parents

WordPress Trac wp-trac at lists.automattic.com
Sun May 23 00:10:57 UTC 2010


#13490: Permalinks Issues for Custom Post Types with Parents
--------------------------+-------------------------------------------------
 Reporter:  mikeschinkel  |       Owner:                   
     Type:  defect (bug)  |      Status:  new              
 Priority:  normal        |   Milestone:  Unassigned       
Component:  Post Types    |     Version:  3.0              
 Severity:  normal        |    Keywords:  reporter-feedback
--------------------------+-------------------------------------------------

Comment(by mikeschinkel):

 Okay.  Ultimately to get it to work here's what I had to do (and I'm not
 100% sure all use-cases are tested.)  I had to 'preg_replace()' the html
 filtered by the '`get_sample_permalink_html`' hook (which is fragile and
 is likely to break with other plugin code that uses the term "menus" in
 URLs) and I had to do some serious surgery on the '`post_type_link`' hook:

 {{{
 <?php

 add_filter('get_sample_permalink_html','tyc_get_sample_permalink_html',10,4);
 function tyc_get_sample_permalink_html($return, $id, $new_title,
 $new_slug) {
         if (strpos($return,'</span>/menus/</span>')!==false) {
                 $return =
 str_replace('</span>/menus/</span>','</span>/</span>',$return);
                 $return =
 preg_replace('#http://([^/]+)/restaurants/([^/]+)/<span#','http://$1/restaurants/$2/menus/<span',$return);
                 $return =
 preg_replace('#http://([^/]+)/restaurants/([^/]+)/([^/]+)/menus/#','http://$1/restaurants/$2/menus/$3/\'',$return);
         }
         return $return;
 }
 add_filter('post_type_link','tyc_post_type_links',10,3);
 function tyc_post_type_links($post_link, $id, $leavename) {
         static $post_links;
         if (!isset($post_links[$post_link])) {
                 $parts = explode('/',$post_link);
                 if ($parts[4]=='%restaurant-dummy%') {
                         if ($parts[5]=='menus') {           // For Post
 Type: restaurant-menu
                                 $parts[4] = $parts[6];            // Move
 restaurant name to where the dummy is
                                 array_splice($parts,6,1);         //
 Remove the now second occurance of restaurant name
                         } else {                            // For Post
 Type: restaurant-location
                                 array_splice($parts,4,1);         //
 Remove the '%restaurant-dummy%' placeholder
                         }
                 }
                 $post_links[$post_link] = implode('/',$parts);
         }
         return $post_links[$post_link];
 }

 add_action('init', 'tyc_post_types');
 function tyc_post_types() {
         global $wp,$wp_rewrite;
         $wp->add_query_var('restaurant-dummy');
         $wp_rewrite->add_rewrite_tag('%restaurant-dummy%',
 '([^/]+)','restaurant-dummy=');

         register_post_type('restaurant-menu',
                 array(
                         'label'           => __('Menus'),
                         'singular_label'  => __('Menu'),
                         'public'          => true,
                         'show_ui'         => true,
                         'query_var'       => 'restaurant-menu',
                         'rewrite'         => array('slug' => 'restaurant-
 menus'),
                         'hierarchical'    => true,
                         'supports'        => array(
                                 'title',
                                 ),
                         )
         );

         $wp->add_query_var('restaurant-menu');
         $wp_rewrite->add_rewrite_tag('%restaurant-menu%',
 '([^/]+)','restaurant-menu=');
         $wp_rewrite->add_permastruct('restaurant-menu', 'restaurants
 /%restaurant-dummy%/menus/%restaurant-menu%');

         register_post_type('restaurant-location',
                 array(
                         'label'           => __('Locations'),
                         'singular_label'  => __('Location'),
                         'public'          => true,
                         'show_ui'         => true,
                         'query_var'       => 'restaurant-location',
                         'rewrite'         => array('slug' => 'restaurant-
 locations'),
                         'hierarchical'    => true,
                         'supports'        => array(
                                 'title',
                                 'editor',
                                 'excerpt',
                                 'custom-fields',
                                 ),
                         )
         );

         $wp->add_query_var('restaurant-location');
         $wp_rewrite->add_rewrite_tag('%restaurant-location%',
 '([^/]+)','restaurant-location=');
         $wp_rewrite->add_permastruct('restaurant-location', 'restaurants
 /%restaurant-dummy%/%restaurant-location%');

         register_post_type('restaurant',
                 array(
                         'label'           => __('Restaurants'),
                         'singular_label'  => __('Restaurant'),
                         'public'          => true,
                         'show_ui'         => true,
                         'query_var'       => 'restaurant',
                         'rewrite'         => array('slug' =>
 'restaurants'),
                         'hierarchical'    => true,
                         'supports'        => array(
                                 'title',
                                 'excerpts',
                                 'thumbnail',
                                 'custom-fields',
                                 'editor',
                                 ),
                         )
         );
         global $wp_rewrite;
         $wp_rewrite->flush_rules(false);
 }
 }}}

 Maybe I'm tackling it the wrong way, but if not don't you agree that this
 level of code is extreme for something as simple as URL patterns like
 this?

 {{{
 http://example.com/restaurants/mcdonalds/              ===> Restaurant
 http://example.com/restaurants/mcdonalds/downtown/     ===> Restaurant
 Location
 http://example.com/restaurants/mcdonalds/menus/lunch/  ===> Restaurant
 Menu
 }}}

 BTW, my solution still does not address the problem of unique slugs
 required, i.e.:

 {{{
 http://example.com/restaurants/mcdonalds/menus/lunch/
 http://example.com/restaurants/burger-king/menus/lunch-2/
 http://example.com/restaurants/wendys/menus/lunch-3/
 }}}

 Versus the more desirable (at least for my current two clients assuming my
 own preference is unimportant):
 {{{
 http://example.com/restaurants/mcdonalds/menus/lunch/
 http://example.com/restaurants/burger-king/menus/lunch/
 http://example.com/restaurants/wendys/menus/lunch/
 }}}

-- 
Ticket URL: <http://core.trac.wordpress.org/ticket/13490#comment:5>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software


More information about the wp-trac mailing list