2

I'm trying to create a custom permalink structure that will allow me to accomplish the following.

  1. I have a custom post type called "products"
  2. I have a custom taxonomy called "catalogs" that is assigned to the CPT "products"

I want my permalink structure to look like this:

catalogs/product-name - without CPT slug or

%custom-taxonomy%/%post-name%/

Also need to work archives page(/products).

So far I have managed to achieve such a structure(/%post-name%):

function remove_cpt_slug( $post_link, $post ) {
    if ( 'products' === $post->post_type && 'publish' === $post->post_status ) {
        $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
    }

    return $post_link;
}
add_filter( 'post_type_link', 'remove_cpt_slug', 10, 2 );

function parse_request ( $query ) {
    if ( ! $query->is_main_query() )
        return;

    if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }

    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'page', 'products' ) );
    }
}
add_action( 'pre_get_posts', 'parse_request' );

Thanks

2

1 Answer 1

1

I managed to find a solution

$args   = array(
            'labels'             => $labels,
            'public'             => true,
            'publicly_queryable' => true,
            'show_ui'            => true,
            'show_in_menu'       => true,
            'query_var'          => true,
            'rewrite'            => array ( 'slug' => 'products/%catalogs%', 'with_front' => false),
            'capability_type'    => 'post',
            'has_archive'        => 'products',
            'hierarchical'       => false,
            'menu_position'      => 4,
            'menu_icon'          => 'dashicons-cart',
            'supports'           => array( 'title', 'thumbnail' ),
            'taxonomies'         => array( 'catalogs' ),
        );
    register_post_type( 'products', $args );

    register_taxonomy( 'catalogs', 'products', array(
            'hierarchical'      => true,
            'labels'            => $labels,
            'show_ui'           => true,
            'query_var'         => true,
            'show_admin_column' => true,
            'show_tagcloud'     => false,
            'rewrite'           => array( 'slug' => 'products', 'with_front' => false ),
        ) );

    /** 
Remove taxony slug, remove CPT slug and add new rewrite rule 
*/
function remove_tax_slug_link( $link, $term, $taxonomy ) {
    if ( $taxonomy !== 'catalogs' )
        return $link;

    return str_replace( 'products/', '', $link );
}
add_filter( 'term_link', 'remove_tax_slug_link', 10, 3 );

function custom_tax_rewrite_rule() {
    $cats = get_terms(
            'catalogs', array(
            'hide_empty' => false,
        )
    );
    if( sizeof( $cats ) )
        foreach($cats as $cat)
            add_rewrite_rule( $cat->slug.'/?$', 'index.php?catalogs='.$cat->slug, 'top' );
}
add_action('init', 'custom_tax_rewrite_rule');

function change_permalinks( $post_link, $post ) {
    if ( is_object( $post ) && $post->post_type == 'products' ){
        $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
        $terms = wp_get_object_terms( $post->ID, 'catalogs' );
        if( $terms ) {
            return str_replace( '%catalogs%' , $terms[0]->slug , $post_link );
        }
    }
    return $post_link;
}
add_filter( 'post_type_link', 'change_permalinks', 10, 2 );

function entry_rewrite_rules() {
    $custom_structure = '/%catalogs%/%products%';
    add_rewrite_tag( '%products%', '([^/]+)', 'products=' );
    add_permastruct( 'products', $custom_structure, array( 'walk_dirs' => false ) );

}
add_action( 'init', 'entry_rewrite_rules' );

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.