2

This is the code i have until now to add a CPT articles and taxonomy articles-category.

The code works, sort off. The pages are displaing correct (when i access them directly):

articles/

articles/categ-slug/

articles/categ-slug/post-slug/

The problem appears when the permalink are generated automatically (eg: yoast breadcrumbs)

<span typeof="v:Breadcrumb">
<a href="example.com" rel="v:url" property="v:title">Example</a> /
<span rel="v:child" typeof="v:Breadcrumb"><a href="example.com/articles/%articles-category%/" rel="v:url" property="v:title">Articles</a> /
<span rel="v:child" typeof="v:Breadcrumb"><a href="example.com/articles/categ-slug/" rel="v:url" property="v:title">Category name</a> /
<span class="breadcrumb_last">Post Name</span></span></span></span>

Notice example.com/articles/%articles-category%/ where it should be just example.com/articles/

What is wrong in the code and how can i make it work?

function custom_post_articles() {

    $labels = array(
        // labels
    );

    $args = array(
        'labels'        => $labels,
        'public'        => true,
        'menu_position' => 5,
        'supports'      => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
        'has_archive'   => true,
        'hierarchical'  => true,
        'rewrite'       => array('slug' => 'articles/%articles-category%','with_front' => false),
        'query_var'     => true,
        //'rewrite'     => true,
        //'publicly_queryable' => false,
    );
    register_post_type( 'articles', $args );
}
add_action( 'init', 'custom_post_articles' );


function my_taxonomies_product() {
    $labels = array(
        //labels
    );
    $args = array(
        'labels' => $labels,
        'hierarchical'  => true,
        'public'        => true,
        'query_var'     => 'articles-category',

        'rewrite'       =>  array('slug' => 'articles' ),
        '_builtin'      => false,
    );
    register_taxonomy( 'articles-category', 'articles', $args );
}
add_action( 'init', 'my_taxonomies_product', 0 );

add_filter('post_link', 'articles_category_permalink', 1, 3);
add_filter('post_type_link', 'articles_category_permalink', 1, 3);

function articles_category_permalink($permalink, $post_id, $leavename) {

    if (strpos($permalink, '%articles-category%') === FALSE) return $permalink;
        // Get post
        $post = get_post($post_id);
        if (!$post) return $permalink;

        // Get taxonomy terms
        $terms = wp_get_object_terms($post->ID, 'articles-category');
        if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0]))
            $taxonomy_slug = $terms[0]->slug;
        else $taxonomy_slug = 'no-category';

    return str_replace('%articles-category%', $taxonomy_slug, $permalink);
}
0

1 Answer 1

0

I solved this way:

Register Custom Post Type:

function custom_post_articles() {

    $labels = array(
        'name'                  => _x( 'Articles', 'post type general name', 'textdomain' ),
        'singular_name'         => _x( 'Article', 'post type singular name', 'textdomain' ),
        // etc...
    );

    $args = array(
        'labels'              => $labels,
        'public'              => true,
        'menu_position'       => 5,                      // Below Posts.
        'menu_icon'           => 'dashicons-megaphone',  // https://developer.wordpress.org/resource/dashicons/
        'capability_type'     => 'post',
        'hierarchical'        => false,                  // False like post, True like page.
        'has_archive'         => true,                   // False like page, True like post.
        'rewrite'             => array(
                                     'slug'       => 'articles/%articles_tax%',
                                     'with_front' => false
                                 ),
        'supports'            => array(
                                     'title',
                                     'editor',
                                     'author',
                                     'thumbnail'
                                )
    );

    register_post_type( 'articles', $args );

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

Register Custom Taxonomy:

function taxonomies_product() {

    $labels = array(
        // labels
    );

    $args = array(
        'labels'            => $labels,
        'public'            => true,
        'hierarchical'      => true,                              // False like tag, True like category.
        'rewrite'           => array(
                                   'slug'         => 'articles',  // Contain lowercase letters and the underscore character (max. 32 char). Default: $taxonomy.
                                   'with_front'   => false,
                                   'hierarchical' => true         // Allow hierarchical urls.
                               )
    );

    register_taxonomy( 'articles_tax', 'articles', $args );

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

RewriteRule for Articles URL Structure:

function rewrite_rules_articles( $rules ) {

    $new = array();
    $new[ 'articles/([^/]+)/(.+)/?$' ] = 'index.php?articles=$matches[2]';
    $new[ 'articles/(.+)/?$' ]         = 'index.php?articles_tax=$matches[1]';

    return array_merge( $new, $rules ); // Put these rules first.

}
add_filter( 'rewrite_rules_array', 'rewrite_rules_articles' );

Replace the placeholder in the URL with the term of the taxonomy:

function handle_placeholder_term_slug( $url, $post ) {

    if ( $post->post_type == 'articles' ) {
        if ( $cats = get_the_terms( $post->ID, 'articles_tax' ) ) {
            $url = str_replace( '%articles_tax%', current( $cats )->slug, $url );
        }
    }

    return $url;

}
add_filter( 'post_type_link', 'handle_placeholder_term_slug', 10, 2 );

Remove the placeholder from the yoast breadcrumbs:

function remove_placeholder_yoast_crumb( $link_output, $link ) {

    if ( $link[ 'text' ] == 'Articles' ) {
        $link_output = str_replace( '/%articles_tax%', '', $link_output );
    }

    /* in the case of a multilingual site
    if ( in_array( $link[ 'text' ], array( 'Articles', 'Artikel', 'Articoli' ) ) ) {
        $link_output = str_replace( '/%articles_tax%', '', $link_output );
    }
    */

    return $link_output;

}
add_filter( 'wpseo_breadcrumb_single_link', 'remove_placeholder_yoast_crumb', 10 ,2 );

Your Answer

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

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