Hierarchial Custom Post Types/Taxonomies

I’ve been learning WordPress for the last few weeks and I’m now creating my own theme.

I found this question which seems to be exactly what I want to do, but I can’t get it working and I suspect its me rather than a code issue.

Read More

URLs are to be like this:

domain-root/sports –> would show a list of all sport-types regardless of which type they are in

domain-root/sport/sport-type-parent –> would show parent and recurring child sport-types

domain-root/sport/sport-type-parent/sport-type-child –> shows sport-type child and children of it

domain-root/sport/sport-type-parent/sport-type-child/sport-page –> shows the page for the sport

I’m using these sport-types:

- Football (Parent Sport Type)
    - 6-a-side (Child Sport Type)
        - Powerleague (page)
    - 11-a-side

I want to end up with a URL like

domain-root/sport/football/6-a-side/powerleague

which is a page to view about that powerleague.

I’m currently working on the basis that I would never have more than 3 levels so changed the original source in the question above accordingly.

My Settings > Permalink option is set to default, but I don’t know what it should be.

Is this all correct? What needs changing to get this working?

Here is the functions from my functions.php file:

function custom_post_sport() {
    $labels = array(
        'name'               => _x( 'Sports', 'post type general name' ),
        'singular_name'      => _x( 'Sport', 'post type singular name' ),
        'add_new'            => _x( 'Add New', 'book' ),
        'add_new_item'       => __( 'Add New Sport' ),
        'edit_item'          => __( 'Edit Sport' ),
        'new_item'           => __( 'New Sport' ),
        'all_items'          => __( 'All Sports' ),
        'view_item'          => __( 'View Sport' ),
        'search_items'       => __( 'Search Sports' ),
        'not_found'          => __( 'No sports found' ),
        'not_found_in_trash' => __( 'No sports found in the Trash' ), 
        'parent_item_colon'  => '',
        'menu_name'          => 'Sports',
        'rewrite'            => array( 'slug' => 'sports/%taxonomy_name%' )
    );
    
    $args = array(
        'labels'        => $labels,
        'description'   => 'Holds our sports and sport specific data',
        'public'        => true,
        'menu_position' => 6,
        'supports'      => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
        'has_archive'   => true,
    );

    register_post_type( 'sport', $args );   
}

add_action( 'init', 'custom_post_sport' );

function taxonomies_sport() {
    $labels = array(
        'name'              => _x( 'Sport Types', 'taxonomy general name' ),
        'singular_name'     => _x( 'Sport Type', 'taxonomy singular name' ),
        'search_items'      => __( 'Search Sport Types' ),
        'all_items'         => __( 'All Sport Types' ),
        'parent_item'       => __( 'Parent Sport Type' ),
        'parent_item_colon' => __( 'Parent Sport Type:' ),
        'edit_item'         => __( 'Edit Sport Type' ), 
        'update_item'       => __( 'Update Sport Type' ),
        'add_new_item'      => __( 'Add New Sport Type' ),
        'new_item_name'     => __( 'New Sport Type' ),
        'menu_name'         => __( 'Sport Types' ),
        'rewrite'            => array( 'slug' => 'sports', 'with_front' => true, 'hierarchical' => true )
    );
    
    $args = array( 'labels' => $labels, 'hierarchical' => true, );
    
    register_taxonomy( 'sport-type', 'sport', $args );
}

add_action( 'init', 'taxonomies_sport', 0 );

add_filter('rewrite_rules_array', 'mmp_rewrite_rules');

function mmp_rewrite_rules($rules) {
    $newRules  = array();
    $newRules['basename/(.+)/(.+)/?$'] = 'index.php?custom_post_type=$matches[4]';     // my custom structure will always have the post name as the 5th uri segment
    $newRules['basename/(.+)/?$']                = 'index.php?taxonomy_name=$matches[1]'; 

    return array_merge($newRules, $rules);
}

function filter_post_type_link($link, $post) {
    if ($post->post_type != 'custom_post_type_name')
    return $link;

    if ($cats = get_the_terms($post->ID, 'taxonomy_name')) {
        $link = str_replace('%taxonomy_name%', get_taxonomy_parents(array_pop($cats)->term_id, 'taxonomy_name', false, '/', true), $link); // see custom function defined below
    }
    return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);

// my own function to do what get_category_parents does for other taxonomies
function get_taxonomy_parents($id, $taxonomy, $link = false, $separator = '/', $nicename = false, $visited = array()) {    
    $chain = '';   
    $parent = &get_term($id, $taxonomy);

    if (is_wp_error($parent)) {
        return $parent;
    }

    if ($nicename)    
        $name = $parent -> slug;        
    else    
        $name = $parent -> name;

    if ($parent -> parent && ($parent -> parent != $parent -> term_id) && !in_array($parent -> parent, $visited)) {    
        $visited[] = $parent -> parent;    
        $chain .= get_taxonomy_parents($parent -> parent, $taxonomy, $link, $separator, $nicename, $visited);
    }

    if ($link) {
        // nothing, can't get this working :(
    } else    
        $chain .= $name . $separator;    
        return $chain;    
}

Related posts

Leave a Reply