$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>custom post types - Pretty Permalinks with CTP and TaxonomiesHierarchical|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

custom post types - Pretty Permalinks with CTP and TaxonomiesHierarchical

matteradmin8PV0评论

My Site has 2 Custom Post Types with a 2 Taxonomies. One taxonomy is “Location” which is 2 level / hierarchical (Country, City). My goal is to get our Post Types & Taxonomies in a SEO Pretty Permalink structure. I have completed most of the Permalink structure but I am still getting 404’s errors on the Post / Slug Landing pages. I am halfway there and I have ran out of patience, I have tried dozens of solutions and they all seem to break one thing or another.

Post Types: Excursion, Stay-Dive

Taxonomies: Location, Excursion-Category

Taxonomy Pages:

Working - /location/%LocationCountry%/

Working - /location/%LocationCountry%/%LocationCity%/

Post Type Pages:

Working - /stay-dive/%LocationCountry%/

Working - /stay-dive/%LocationCountry%/%LocationCity%/

Not Working /stay-dive/%LocationCountry%/%LocationCity%/Slug - Not Working

Working - /excursion/%LocationCountry%/

Not Working - /excursion/%LocationCountry%/%LocationCity%/

Not Working - /excursion/%LocationCountry%/%LocationCity%/Slug

Working - /excursion/%excursion-category%/

Not Working - /excursion/%excursion-category%/%LocationCountry%/

Not Working - /excursion/%excursion-category%/%LocationCountry%/%LocationCity%/

Taxonomy Code:

    // excursion category
register_taxonomy('pdm_excursion_category', array('pdm_excursion'), array(
    'labels' => array(
        'name'                       => _x('Categories', 'taxonomy general name', 'pdm'),
        'singular_name'              => _x('Category', 'taxonomy singular name', 'pdm'),
        'menu_name'                  => __('Categories', 'pdm'),
        'all_items'                  => __('All Categories', 'pdm'),
        'edit_item'                  => __('Edit Category', 'pdm'),
        'view_item'                  => __('View Category', 'pdm'),
        'update_item'                => __('Update Category', 'pdm'),
        'add_new_item'               => __('Add New Category', 'pdm'),
        'new_item_name'              => __('New Category Name', 'pdm'),
        'parent_item'                => __('Parent Category', 'pdm'),
        'parent_item_colon'          => __('Parent Category:', 'pdm'),
        'search_items'               => __('Search Categories', 'pdm'),
        'popular_items'              => __('Popular Categories', 'pdm'),
        'separate_items_with_commas' => __('Separate categories with commas', 'pdm'),
        'add_or_remove_items'        => __('Add or remove categories', 'pdm'),
        'choose_from_most_used'      => __('Choose from the most used categories', 'pdm'),
        'not_found'                  => __('No categories found.', 'pdm'),
    ),
    'show_ui'           => true,
    'show_admin_column' => true,
    'hierarchical'      => true,
    'query_var'         => true,
    'rewrite'           => array('slug' => 'excursions', 'with_front' => true, 'hierarchical' => false),
));

// location
register_taxonomy('pdm_location', array('pdm_hotel', 'pdm_excursion', 'pdm_dive_site'), array(
    'labels' => array(
        'name'                       => _x('Locations', 'taxonomy general name', 'pdm'),
        'singular_name'              => _x('Location', 'taxonomy singular name', 'pdm'),
        'menu_name'                  => __('Locations', 'pdm'),
        'all_items'                  => __('All Locations', 'pdm'),
        'edit_item'                  => __('Edit Location', 'pdm'),
        'view_item'                  => __('View Location', 'pdm'),
        'update_item'                => __('Update Location', 'pdm'),
        'add_new_item'               => __('Add New Location', 'pdm'),
        'new_item_name'              => __('New Location Name', 'pdm'),
        'parent_item'                => __('Parent Location', 'pdm'),
        'parent_item_colon'          => __('Parent Location:', 'pdm'),
        'search_items'               => __('Search Locations', 'pdm'),
        'popular_items'              => __('Popular Locations', 'pdm'),
        'separate_items_with_commas' => __('Separate locations with commas', 'pdm'),
        'add_or_remove_items'        => __('Add or remove locations', 'pdm'),
        'choose_from_most_used'      => __('Choose from the most used locations', 'pdm'),
        'not_found'                  => __('No locations found.', 'pdm'),
    ),
    'show_ui'       => true,
    'show_admin_column' => true,
    'hierarchical'      => true,
    'query_var'         => true,
    'rewrite'           => array('slug' => 'location', 'with_front' => false, 'hierarchical' => true),
));

Post Type Code:

// hotel
register_post_type('pdm_hotel' , array(
    'labels' => array(
        'name'               => _x('Stay & Dive Hotels', 'post type general name', 'pdm'),
        'singular_name'      => _x('Stay & Dive', 'post type singular name', 'pdm'),
        'menu_name'          => _x('Stay & Dive Hotels', 'admin menu', 'pdm'),
        'name_admin_bar'     => _x('Stay & Dive Hotel', 'add new on admin bar', 'pdm'),
        'add_new'            => _x('Add New', 'book', 'pdm'),
        'add_new_item'       => __('Add New Hotel', 'pdm'),
        'new_item'           => __('New Stay & Dive Hotel', 'pdm'),
        'edit_item'          => __('Edit Stay & Dive Hotel', 'pdm'),
        'view_item'          => __('View Stay & Dive Hotel', 'pdm'),
        'all_items'          => __('All Stay & Dive Hotels', 'pdm'),
        'search_items'       => __('Search Stay & Dive Hotels', 'pdm'),
        'parent_item_colon'  => __('Parent Stay & Dive Hotel:', 'pdm'),
        'not_found'          => __('No hotels found.', 'pdm'),
        'not_found_in_trash' => __('No hotels found in Trash.', 'pdm'),
    ),
    'public'             => true,
    'publicly_queryable' => true,
    'show_ui'            => true,
    'show_in_menu'       => true,
    'query_var'          => true,
    'rewrite'        => array('slug' => 'stay-dive/%pdm_location%/%pdm_location2%', 'with_front' => true),
    'capability_type'    => 'post',
    'has_archive'        => true,
    'hierarchical'       => false,
    'menu_position'      => 101,
    'menu_icon'          => 'dashicons-admin-home',
    'supports'           => array('title','editor','thumbnail'),
    'taxonomies'         => array('pdm_location'),
));

// excursions
register_post_type('pdm_excursion' , array(
    'labels' => array(
        'name'               => _x('Excursions', 'post type general name', 'pdm'),
        'singular_name'      => _x('Excursion', 'post type singular name', 'pdm'),
        'menu_name'          => _x('Excursions', 'admin menu', 'pdm'),
        'name_admin_bar'     => _x('Excursion', 'add new on admin bar', 'pdm'),
        'add_new'            => _x('Add New', 'book', 'pdm'),
        'add_new_item'       => __('Add New Excursion', 'pdm'),
        'new_item'           => __('New Excursion', 'pdm'),
        'edit_item'          => __('Edit Excursion', 'pdm'),
        'view_item'          => __('View Excursion', 'pdm'),
        'all_items'          => __('All Excursions', 'pdm'),
        'search_items'       => __('Search Excursions', 'pdm'),
        'parent_item_colon'  => __('Parent Excursion:', 'pdm'),
        'not_found'          => __('No excursions found.', 'pdm'),
        'not_found_in_trash' => __('No excursions found in Trash.', 'pdm'),
    ),
    'public'             => true,
    'publicly_queryable' => true,
    'show_ui'            => true,
    'show_in_menu'       => true,
    'query_var'          => true,
    'rewrite'        => array('slug' => 'excursion  /%pdm_excursion_category%/%pdm_location%/%pdm_location2%','with_front' => true),
    'capability_type'    => 'post',
    'has_archive'        => true,
    'hierarchical'       => false,
    'menu_position'      => 102,
    'menu_icon'          => 'dashicons-location',
    'supports'           => array('title','editor','thumbnail'),
    'taxonomies'         => array('pdm_location','pdm_excursion_category'),
));

My Site has 2 Custom Post Types with a 2 Taxonomies. One taxonomy is “Location” which is 2 level / hierarchical (Country, City). My goal is to get our Post Types & Taxonomies in a SEO Pretty Permalink structure. I have completed most of the Permalink structure but I am still getting 404’s errors on the Post / Slug Landing pages. I am halfway there and I have ran out of patience, I have tried dozens of solutions and they all seem to break one thing or another.

Post Types: Excursion, Stay-Dive

Taxonomies: Location, Excursion-Category

Taxonomy Pages:

Working - /location/%LocationCountry%/

Working - /location/%LocationCountry%/%LocationCity%/

Post Type Pages:

Working - /stay-dive/%LocationCountry%/

Working - /stay-dive/%LocationCountry%/%LocationCity%/

Not Working /stay-dive/%LocationCountry%/%LocationCity%/Slug - Not Working

Working - /excursion/%LocationCountry%/

Not Working - /excursion/%LocationCountry%/%LocationCity%/

Not Working - /excursion/%LocationCountry%/%LocationCity%/Slug

Working - /excursion/%excursion-category%/

Not Working - /excursion/%excursion-category%/%LocationCountry%/

Not Working - /excursion/%excursion-category%/%LocationCountry%/%LocationCity%/

Taxonomy Code:

    // excursion category
register_taxonomy('pdm_excursion_category', array('pdm_excursion'), array(
    'labels' => array(
        'name'                       => _x('Categories', 'taxonomy general name', 'pdm'),
        'singular_name'              => _x('Category', 'taxonomy singular name', 'pdm'),
        'menu_name'                  => __('Categories', 'pdm'),
        'all_items'                  => __('All Categories', 'pdm'),
        'edit_item'                  => __('Edit Category', 'pdm'),
        'view_item'                  => __('View Category', 'pdm'),
        'update_item'                => __('Update Category', 'pdm'),
        'add_new_item'               => __('Add New Category', 'pdm'),
        'new_item_name'              => __('New Category Name', 'pdm'),
        'parent_item'                => __('Parent Category', 'pdm'),
        'parent_item_colon'          => __('Parent Category:', 'pdm'),
        'search_items'               => __('Search Categories', 'pdm'),
        'popular_items'              => __('Popular Categories', 'pdm'),
        'separate_items_with_commas' => __('Separate categories with commas', 'pdm'),
        'add_or_remove_items'        => __('Add or remove categories', 'pdm'),
        'choose_from_most_used'      => __('Choose from the most used categories', 'pdm'),
        'not_found'                  => __('No categories found.', 'pdm'),
    ),
    'show_ui'           => true,
    'show_admin_column' => true,
    'hierarchical'      => true,
    'query_var'         => true,
    'rewrite'           => array('slug' => 'excursions', 'with_front' => true, 'hierarchical' => false),
));

// location
register_taxonomy('pdm_location', array('pdm_hotel', 'pdm_excursion', 'pdm_dive_site'), array(
    'labels' => array(
        'name'                       => _x('Locations', 'taxonomy general name', 'pdm'),
        'singular_name'              => _x('Location', 'taxonomy singular name', 'pdm'),
        'menu_name'                  => __('Locations', 'pdm'),
        'all_items'                  => __('All Locations', 'pdm'),
        'edit_item'                  => __('Edit Location', 'pdm'),
        'view_item'                  => __('View Location', 'pdm'),
        'update_item'                => __('Update Location', 'pdm'),
        'add_new_item'               => __('Add New Location', 'pdm'),
        'new_item_name'              => __('New Location Name', 'pdm'),
        'parent_item'                => __('Parent Location', 'pdm'),
        'parent_item_colon'          => __('Parent Location:', 'pdm'),
        'search_items'               => __('Search Locations', 'pdm'),
        'popular_items'              => __('Popular Locations', 'pdm'),
        'separate_items_with_commas' => __('Separate locations with commas', 'pdm'),
        'add_or_remove_items'        => __('Add or remove locations', 'pdm'),
        'choose_from_most_used'      => __('Choose from the most used locations', 'pdm'),
        'not_found'                  => __('No locations found.', 'pdm'),
    ),
    'show_ui'       => true,
    'show_admin_column' => true,
    'hierarchical'      => true,
    'query_var'         => true,
    'rewrite'           => array('slug' => 'location', 'with_front' => false, 'hierarchical' => true),
));

Post Type Code:

// hotel
register_post_type('pdm_hotel' , array(
    'labels' => array(
        'name'               => _x('Stay & Dive Hotels', 'post type general name', 'pdm'),
        'singular_name'      => _x('Stay & Dive', 'post type singular name', 'pdm'),
        'menu_name'          => _x('Stay & Dive Hotels', 'admin menu', 'pdm'),
        'name_admin_bar'     => _x('Stay & Dive Hotel', 'add new on admin bar', 'pdm'),
        'add_new'            => _x('Add New', 'book', 'pdm'),
        'add_new_item'       => __('Add New Hotel', 'pdm'),
        'new_item'           => __('New Stay & Dive Hotel', 'pdm'),
        'edit_item'          => __('Edit Stay & Dive Hotel', 'pdm'),
        'view_item'          => __('View Stay & Dive Hotel', 'pdm'),
        'all_items'          => __('All Stay & Dive Hotels', 'pdm'),
        'search_items'       => __('Search Stay & Dive Hotels', 'pdm'),
        'parent_item_colon'  => __('Parent Stay & Dive Hotel:', 'pdm'),
        'not_found'          => __('No hotels found.', 'pdm'),
        'not_found_in_trash' => __('No hotels found in Trash.', 'pdm'),
    ),
    'public'             => true,
    'publicly_queryable' => true,
    'show_ui'            => true,
    'show_in_menu'       => true,
    'query_var'          => true,
    'rewrite'        => array('slug' => 'stay-dive/%pdm_location%/%pdm_location2%', 'with_front' => true),
    'capability_type'    => 'post',
    'has_archive'        => true,
    'hierarchical'       => false,
    'menu_position'      => 101,
    'menu_icon'          => 'dashicons-admin-home',
    'supports'           => array('title','editor','thumbnail'),
    'taxonomies'         => array('pdm_location'),
));

// excursions
register_post_type('pdm_excursion' , array(
    'labels' => array(
        'name'               => _x('Excursions', 'post type general name', 'pdm'),
        'singular_name'      => _x('Excursion', 'post type singular name', 'pdm'),
        'menu_name'          => _x('Excursions', 'admin menu', 'pdm'),
        'name_admin_bar'     => _x('Excursion', 'add new on admin bar', 'pdm'),
        'add_new'            => _x('Add New', 'book', 'pdm'),
        'add_new_item'       => __('Add New Excursion', 'pdm'),
        'new_item'           => __('New Excursion', 'pdm'),
        'edit_item'          => __('Edit Excursion', 'pdm'),
        'view_item'          => __('View Excursion', 'pdm'),
        'all_items'          => __('All Excursions', 'pdm'),
        'search_items'       => __('Search Excursions', 'pdm'),
        'parent_item_colon'  => __('Parent Excursion:', 'pdm'),
        'not_found'          => __('No excursions found.', 'pdm'),
        'not_found_in_trash' => __('No excursions found in Trash.', 'pdm'),
    ),
    'public'             => true,
    'publicly_queryable' => true,
    'show_ui'            => true,
    'show_in_menu'       => true,
    'query_var'          => true,
    'rewrite'        => array('slug' => 'excursion  /%pdm_excursion_category%/%pdm_location%/%pdm_location2%','with_front' => true),
    'capability_type'    => 'post',
    'has_archive'        => true,
    'hierarchical'       => false,
    'menu_position'      => 102,
    'menu_icon'          => 'dashicons-location',
    'supports'           => array('title','editor','thumbnail'),
    'taxonomies'         => array('pdm_location','pdm_excursion_category'),
));
Share Improve this question edited Dec 11, 2018 at 21:59 Enkode asked Dec 11, 2018 at 20:42 EnkodeEnkode 515 bronze badges 2
  • 1 It’s never going to work with just rewrites alone, as you have identical patterns that could be either a term or a post. You’ll need to hook into query parsing and do some manual disambiguation. – Milo Commented Dec 11, 2018 at 23:24
  • I determined I will use "excursions" for the taxonomy and "excursion" for the CPT will that work? – Enkode Commented Dec 12, 2018 at 0:48
Add a comment  | 

1 Answer 1

Reset to default 0

Found a git repo that had the solution: https://github/hemal21/WordPress-CPT-Hierarchical-Taxonomy-Permalinks/blob/master/cpt-hierarchical-tax-permalinks.php

I needed do a rewrite, Here is an example of working pretty permalink code:

    <?php
/**
 * WordPress Custom Post Type and Hierarchical Taxonomy Permalinks
 *
 * Ever wanted to have custom taxonomy permalinks that reflect parent/child relation?
 * Then this is for you. Still in development though.
 *
 * @version 1.0b
 * @author Kenth Hagström
 * @link http://www.facebook/keha76
 * @license GNU General Public License v2
 *
 * Last updated 19 sep 2013, 15:30(GMT+1)
 *
 * KNOWN BUGS:
 * - When a 'photo' is published without any taxonomy, the URL url.tld/photos/john does not work.
 * - The full URL url.tld/photos/family/kids/john/ has an unwanted trailing slash.
 *
 * These URL structures work:
 * url.tld/photos/ loads archive-photo.php
 * url.tld/photos/family/ loads taxonomy-album.php
 * url.tld/photos/family/kids/ loads taxonomy-album.php
 * url.tld/photos/family/kids/john loads single-photo.php
 * url.tld/photos/page/2 loads page 2 with archive-photo.php
 *
 * If you try this code, remember to flush your permalinks. Go to 'settings->permalinks' and it's done.
 *
**/
function keha_register_photo_tax_album() {

        $labels = array(
                'name'              => _x( 'Albums', 'taxonomy general name', 'blank' ),
                'singular_name'     => _x( 'Album', 'taxonomy singular name', 'blank' ),
                'search_items'      => __( 'Search Albums', 'blank' ),
                'all_items'         => __( 'All Albums', 'blank' ),
                'parent_item'       => __( 'Parent Album', 'blank' ),
                'parent_item_colon' => __( 'Parent Album:', 'blank' ),
                'edit_item'         => __( 'Edit Album', 'blank' ),
                'update_item'       => __( 'Update Album', 'blank' ),
                'add_new_item'      => __( 'Add New Album', 'blank' ),
                'new_item_name'     => __( 'New Album Name', 'blank' ),
                'menu_name'         => __( 'Albums', 'blank' ),
        );      

        $rewrite = array(
                'slug' => 'album',
                'with_front' => false,
                'hierarchical' => true
        );

        $args = array(
                'hierarchical' => true,
                'labels'       => $labels,
                'show_ui'      => true,
                'query_var'    => true,
                'rewrite'      => $rewrite
        );
        register_taxonomy( 'album', array( 'photo' ), $args );
}
add_action( 'init', 'keha_register_photo_tax_album' );

function keha_register_cpt_photo() {

        $labels = array(
                'name'               => __( 'Photos', 'blank' ),
                'singular_name'      => _x( 'Photo', 'Photo post type singular', 'blank' ),
                'add_new'            => __( 'Add New', 'blank' ),
                'add_new_item'       => __( 'Add New Photo', 'blank' ),
                'edit_item'          => __( 'Edit Photo', 'blank' ),
                'new_item'           => __( 'New Photo', 'blank' ),
                'all_items'          => __( 'All Photos', 'blank' ),
                'view_item'          => __( 'View Photo', 'blank' ),
                'search_items'       => __( 'Search Photos', 'blank' ),
                'not_found'          => __( 'No photos found', 'blank' ),
                'not_found_in_trash' => __( 'No photos found in Trash', 'blank' ),
                'parent_item_colon'  => '',
                'menu_name'          => __( 'Photos', 'blank' )
        );

        $rewrite = array(
                'slug' => 'photos',
                'hierarchical' => true,
                'with_front' => true
        );

        $args = array(
                'labels'               => $labels,
                'exclude_from_search'  => false,
                'publicly_queryable'   => true,
                'show_ui'              => true,
                'show_in_nav_menus'    => true,
                'show_in_menu'         => true,
                'show_in_admin_bar'    => true,
                'menu_position'        => 20,
                'menu_icon'            => null, // Handled from CSS
                'capability_type'      => 'post',
                'hierarchical'         => false,
                'public'               => true,
                'supports'             => array( 'title', 'editor', 'thumbnail' ),
                'taxonomies'           => array( 'album' ),
                'rewrite'              => $rewrite,
                'has_archive'          => true,
                'query_var'            => true,
                'can_export'           => true
        );

        register_post_type( 'photo', $args );
}
add_action( 'init', 'keha_register_cpt_photo' );

function keha_add_rewrite_rules() {
        add_rewrite_rule( '^photos/(.+?)/(.+?)/(.+?)$', 'index.php?album=$matches[1]&album=$matches[2]&photo=$matches[3]', 'top' );
        add_rewrite_rule( '^photos/(.+?)/(.+?)/$', 'index.php?photo=$matches[2]', 'top' );
        add_rewrite_rule( '^photos/(.+?)/(.+?)/(.+?)$', 'index.php?photo=$matches[3]', 'top' );
        add_rewrite_rule( '^photos/(.+?)/(.+?)/?$', 'index.php?album=$matches[2]', 'top' );
        add_rewrite_rule( '^photos/(.+?)$', 'index.php?album=$matches[1]', 'top' );
}
add_action('init', 'keha_add_rewrite_rules');

function keha_post_type_link( $post_link, $post, $leavename ) {

        global $wp_rewrite;

        $draft_or_pending = isset( $post->post_status ) && in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) );
        if ( $draft_or_pending and !$leavename ) {
                return $post_link;
        }

        if ( $post->post_type == 'photo' ) {

                $post_type_object = get_post_type_object( $post->post_type );
                $post_link = home_url() . '/' . $post_type_object->rewrite['slug'] . '/';
                $parent_dirs = '';
                if ( $terms = get_the_terms( $post->ID, 'album' ) ) {
                        foreach ( $terms as $term ) {
                                if ( $term->parent != 0 ) {
                                        $dirs = keha_get_taxonomy_parents( $term->term_id, 'album', false, '/', true );
                                } else {
                                        $dirs = $term->slug.'/';
                                }
                        }
                }
                $post_link = $post_link . $dirs . $post->post_name;
        }

        return $post_link;
}
add_filter( 'post_type_link', 'keha_post_type_link', 10, 3 );

/**
 * Custom function based on WordPress own get_category_parents()
 * @link http://core.trac.wordpress/browser/tags/3.6.1/wp-includes/category-template.php#L0
 *
 * @param integer $id
 * @param string $taxonomy
 * @param string $link
 * @param string $separator
 * @param string $nicename
 * @param array $visited
 * @return string
 */
function keha_get_taxonomy_parents( $id, $taxonomy = 'category', $link = false, $separator = '/', $nicename = false, $visited = array() ) {
        $chain = '';
        $parent = get_term( $id, $taxonomy, OBJECT, 'raw');
        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 .= keha_get_taxonomy_parents( $parent->parent, $taxonomy, $link, $separator, $nicename, $visited );
        }

        if ( $link ) {
                $chain .= '<a href="' . get_term_link( $parent->term_id, $taxonomy ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $parent->name ) ) . '">'.$name.'</a>' . $separator;
        }else {
                $chain .= $name.$separator;
        }
        return $chain;
}
Post a comment

comment list (0)

  1. No comments so far