0

Is wordpress capable of having hierarchical taxonomy and hierarchical custom post types in one permalink ?

I would like to do the following:

tax-1/tax-2/cpt-1/cpt-1-post/cpt-2/cpt-2-post/

in other words:

continent/country/travelog/travelog-post/videos/video-post/

or in a real case where "a-day-at-the-beach" is the travelog post and "sand-in-my-trunks" is the video post:

europe/spain/travelog/a-day-at-the-beach/videos/sand-in-my-trunks/

I have 4 custom post types that would always be at the level of cpt-1 and 3 custom post types (videos, photos, sketches) that would always appear at the sub level of cpt-2.

When complete the site will have roughly 4000 posts in total.

I'm hoping there is a plugin or set of plugins to help achieve this, but so far I've not found that magic combination. If not, can this permalink structure be custom coded with url re-writes and REGEX ?

8
  • Looks like you're trying to make parent/child relationship in 2 different post types. While it's not technically impossible, wordpress admin panel will ignore it. You'll need to create a custom admin screen for it. Have you successfully implemented this? Dec 17, 2012 at 19:02
  • @MridulAggarwal I'm confused by your comment. Are you saying that the permalink I desire is not technically possible ? I have neither implemented the permalink structure nor created a custom admin screen.
    – timoto
    Dec 17, 2012 at 19:14
  • I'm trying to understand what you have already done & what you want to do. If you haven't implemented a custom screen, how can you make a post from 1 CPT a parent of another CPT? Technically it is possible but i'm trying to understand what you've achieved so far. Dec 17, 2012 at 19:26
  • @MridulAggarwal I am able to create custom hierarchical taxonomy and custom post types, but not hierarchical custom post types. So I don't know how to make the proposed permalink that has both hierarchical taxonomy and hierarchical custom post types. At best I have been able to create tax-1/tax-2/cpt-1/cpt-1-post/ but with varying results depending on the use of plugins. Have you seen a working example such as this: tax-1/tax-2/cpt-1/cpt-1-post/cpt-2/cpt-2-post/ ?
    – timoto
    Dec 17, 2012 at 23:35
  • I haven't. Wordpress lacks simple ways when it comes to permalink structures. For this case, you'll need more than just permalink. First you'll need to provide a way to link cpt-1-post & cpt-2-post(you need a custom admin screen for it). Then you'll use add_rewrite_rule to add rules. In this function you have to make sure you don't rewrite it to both cpt-1-post & cpt-2-post. Dec 18, 2012 at 3:53

1 Answer 1

1

To cut a long story short the answer to the question is Yes.

In the end I was able to create: tax-1/tax-2/cpt-1/cpt-1-post/cpt-2/cpt-2-post/

and another structure: tax-1/tax-2/cpt-1/cpt-1-post/cpt-2/custom-field/cpt-2-post/

I used Types from http://wp-types.com/ to create the hierarchical custom taxonomy, the custom post types, custom fields, but most importantly the parent/child relationship between custom post types. That plugin saved a lot of time.

The next step was to do the URL re-writes using regular expressions.

    <?php


    // Add custom rewrite rules

    add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );

    // Add custom variable for WP_QUERY

    add_filter( 'query_vars','my_insert_query_vars' );

    // This hook is fired once WP, all plugins, and the theme are fully loaded and instantiated.

    add_action( 'wp_loaded','my_flush_rules' );

    // Flush rules for include custom rewrite rules

    function my_flush_rules(){
        $rules = get_option( 'rewrite_rules' );
        global $wp_rewrite;
        $wp_rewrite->flush_rules();
    }

    // Add custom rewrite rules

    function my_insert_rewrite_rules( $rules ){
        $newrules = array();  

        $location_list = get_terms("location",array("parent" => 0, "hide_empty" => 0));
        foreach($location_list as $location){
            $base_url = sprintf('index.php?taxonomy=%s&term=%s&child_term=$matches[1]&type=$matches[2]&type_title=$matches[3]&media_type=$matches[4]&media_maintitle=$matches[5]&media_title=$matches[6]','location',$location->slug);
            $newrules[$location->slug.'/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?'] = $base_url;
            $base_url = sprintf('index.php?taxonomy=%s&term=%s&child_term=$matches[1]&type=$matches[2]&type_title=$matches[3]&media_type=$matches[4]&media_title=$matches[5]','location',$location->slug);        
            $newrules[$location->slug.'/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?'] = $base_url;
            $base_url = sprintf('index.php?taxonomy=%s&term=%s&child_term=$matches[1]&type=$matches[2]&type_title=$matches[3]&media_type=$matches[4]','location',$location->slug);        
            $newrules[$location->slug.'/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?'] = $base_url;
            $base_url = sprintf('index.php?taxonomy=%s&term=%s&child_term=$matches[1]&type=$matches[2]&type_title=$matches[3]','location',$location->slug);        
            $newrules[$location->slug.'/([^/]+)/([^/]+)/([^/]+)/?'] = $base_url;
            $base_url = sprintf('index.php?taxonomy=%s&term=%s&child_term=$matches[1]&type=$matches[2]','location',$location->slug);        
            $newrules[$location->slug.'/([^/]+)/([^/]+)/?'] = $base_url;
            $base_url = sprintf('index.php?taxonomy=%s&term=%s&child_term=$matches[1]','location',$location->slug);        
            $newrules[$location->slug.'/([^/]+)/?'] = $base_url;
        }

        return $newrules + $rules;
    }

    // Add custom variable for WP_QUERY

    function my_insert_query_vars( $vars ){                                                                                               
        array_push($vars, 'taxonomy');          
        array_push($vars, 'child_term');                   
        array_push($vars, 'type');                       
        array_push($vars, 'type_title');                           
        array_push($vars, 'media_type');                                
        array_push($vars, 'media_maintitle');                    
        array_push($vars, 'media_title'); 
        return $vars;
    }

    ?>

I'm not sure if the optimum REGEX rules have been created here, but I found I had to do this much to make sure re-directs were in place ensuring no potential for multiple URLs displaying the same content.

There is more to the answer than I've posted here, but I think there is a limit to the number of lines I can post.

1
  • You can post up to 30.000 characters. So there is still room for detailed explanations. :)
    – fuxia
    Jan 15, 2013 at 20:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.