web-dev-qa-db-fra.com

Lien permanent Structure CPT avec taxonomie personnalisée échoue

La configuration de la structure d'URL correcte pour un type de message Cutom avec une taxonomie personnalisée me rend assez frustrée.

J'ai un type de message personnalisé appelé courses avec une taxonomie personnalisée appelée course-type.

  1. La structure de l'URL devrait être: site.com/courses/course-type/course-single-post/.
  2. Par exemple: site.com/courses/science/rocket-to-the-moon/

J'ai réussi à atteindre cet objectif, mais toutes les parties de l'URL ne se comportent pas correctement.

  • site.com/courses/ - retourne un 404
  • site.com/courses/science/ - Affiche une page d'archive avec toutes les publications dans cette taxonomie personnalisée qui est correcte
  • site.com/courses/science/rocket-to-the-moon/ - Affiche le type de message personnalisé unique qui est également correct

Je ne sais pas pourquoi le site.com/courses/ renvoie un 404 au lieu d'afficher une page d'archive répertoriant tous les types de messages personnalisés ...?

C'est le code que j'ai utilisé:

<?php 

/*Courses Custom Post Type*/
function my_custom_post_courses() {
$labels = array(
    'name'               => _x( 'Courses', 'post type general name' ),
    'singular_name'      => _x( 'Course', 'post type singular name' ),
    'add_new'            => _x( 'New course', 'reis' ),
    'add_new_item'       => __( 'Add new course' ),
    'edit_item'          => __( 'Edit course' ),
    'new_item'           => __( 'New item' ),
    'all_items'          => __( 'All courses' ),
    'view_item'          => __( 'View courses' ),
    'search_items'       => __( 'Search courses' ),
    'not_found'          => __( 'Nothing found  ' ),
    'not_found_in_trash' => __( 'Nothing found in the trash' ),
    'parent_item_colon'  => '',
    'menu_name'          => 'Courses'
);
$args = array(
    'labels'        => $labels,
    'description'   => 'Enter a new course',
    'public'        => true,
    'menu_position' => 5,
    'supports'      => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
    'has_archive'   => true,
    'hierarchical'  => true,
    'rewrite'       => array('slug' => 'courses/%course-type%','with_front' => false),
    'query_var'     => true,
    //'rewrite'     => true,
    //'publicly_queryable' => false,
);
register_post_type( 'courses', $args );
}
add_action( 'init', 'my_custom_post_courses' );

/* Courses custom taxonomy */
function my_taxonomies_course_type() {
$labels = array(
    'name'              => _x( 'Course type', 'taxonomy general name' ),
    'singular_name'     => _x( 'Course type', 'taxonomy singular name' ),
    'search_items'      => __( 'Search course types' ),
    'all_items'         => __( 'All course types' ),
    'parent_item'       => __( 'Parent course type' ),
    'parent_item_colon' => __( 'Parent course type:' ),
    'edit_item'         => __( 'Edit course type' ),
    'update_item'       => __( 'Update course type ' ),
    'add_new_item'      => __( 'Add new course type' ),
    'new_item_name'     => __( 'New course type' ),
    'menu_name'         => __( 'Course type' ),
);
$args = array(
    'labels' => $labels,
    'hierarchical'  => true,
    'public'        => true,
    'query_var'     => 'course-type',
    'rewrite'       =>  array('slug' => 'courses' ),
    '_builtin'      => false,
);
register_taxonomy( 'course-type', 'courses', $args );
}
add_action( 'init', 'my_taxonomies_course_type', 0 );

/* Permalink filter Courses */
add_filter('post_link', 'course_permalink', 1, 3);
add_filter('post_type_link', 'course_permalink', 1, 3);

function course_permalink($permalink, $post_id, $leavename) {
if (strpos($permalink, '%course-type%') === FALSE) return $permalink;
    // Get post
    $post = get_post($post_id);
    if (!$post) return $permalink;

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

return str_replace('%course-type%', $taxonomy_slug, $permalink);
}
1
NielsPilon

Si vous définissez has_archive sur true, WordPress génère une règle de réécriture de l'archive à l'aide du slug de réécriture, ce qui n'est pas ce que vous souhaitez dans votre cas. Au lieu de cela, spécifiez explicitement l'archive slug en tant que chaîne et les règles correctes seront générées:

$args = array(
    'has_archive'   => 'courses',
    'rewrite'       => array('slug' => 'courses/%course-type%','with_front' => false),
    // the rest of your args...
);
register_post_type( 'courses', $args );
2
Milo

Avec votre structure d'URL permalien souhaitée ... WordPress gère automatiquement la création de règles de réécriture pour ce que vous avez entré (courses/%course-type%) pour votre slug Post Type. Bien entendu, vous devez modifier le lien Type de publication pour substituer le remplaçant à la valeur réelle (comme vous l'avez déjà fait).

Cependant, WordPress n'attend pas ce type de comportement dans un slug Post Type. Typiquement, WordPress s'attend à quelque chose de simple comme courses (au lieu de courses/%course-type%).

Ce n'est pas grave, WordPress nous permet de nous adapter à presque toutes les situations grâce à son incroyable flexibilité et à ses fonctionnalités de personnalisation.

Tout ce que vous avez à faire est d’ajuster les règles de réécriture pour gérer la "base" de votre slug de type de publication (courses).

Cela peut être fait proprement dans deux fonctions qui pourraient être collées dans votre fichier de thème functions.php actuellement activé (ou plus idéalement ... dans un fichier de plugin.)

Étape 1 - Ajustez les règles de réécriture.

Dans cette étape, vous demandez de nouvelles règles de réécriture à ajouter aux règles de réécriture existantes. Les nouvelles règles de réécriture sont créées automatiquement dans la fonction mbe_get_new_rewrite_rules();.

if ( ! function_exists( 'mbe_adjust_rewrite_rules' ) ) {

    function mbe_adjust_rewrite_rules( $rules ) {

        if ( ! function_exists( 'mbe_get_new_rewrite_rules' ) ) {
            return $rules;
        }

        $new_rules = mbe_get_new_rewrite_rules( 'courses' );

        return ( $new_rules + $rules );

    }

    add_action( 'rewrite_rules_array', 'mbe_adjust_rewrite_rules', 100 );

}

Étape 2 - Créez les nouvelles règles de réécriture.

Remarque: cette fonction nécessite le nom du type de poste en tant que paramètre.

Cette fonction prend le nom de type de post spécifié et récupère automatiquement son slug de réécriture (spécifié lors de l’enregistrement de type de post).

Cette fonction continuera ensuite à rechercher d'éventuelles barres obliques dans le slug Post Type. S'il en trouve un, il faudra tout avant la première barre oblique (AKA, le slug de base) et générer une règle de réécriture appropriée pour le slug de base de votre type de message. (Comme cela aurait été le cas si vous veniez de spécifier un slug de réécriture simple de courses lors de l'enregistrement de Post Type au lieu de courses/%course-type%.)

if ( ! function_exists( 'mbe_get_new_rewrite_rules' ) ) {

    function mbe_get_new_rewrite_rules( $post_type = '' ) {

        $new_rules = array();

        $post_type_object = get_post_type_object( $post_type );

        if ( ! $post_type_object ) {
            return $new_rules;
        }

        $post_type_slug      = $post_type_object->rewrite['slug'];
        $post_type_slug_base = substr( $post_type_slug, 0, strpos( $post_type_slug, '/' ) );

        if ( ! empty( $post_type_slug_base ) ) {
            $new_rules["{$post_type_slug_base}/?$"] = "index.php?post_type={$post_type}";
        }

        return $new_rules;

    }

}

Voilà. Trois URL valides et fonctionnelles. Selon votre demande.

  1. domain.com/courses/
  2. domain.com/courses/course-type/
  3. domain.com/courses/course-type/course-name/

N'oubliez pas de vider les règles de réécriture par programme ou de visiter: Dashboard -> Settings -> Permalinks pour que les nouvelles règles de réécriture prennent effet.

0
Michael Ecklund