J'essaie de configurer une structure de type de publication personnalisée à plusieurs niveaux avec des liens permanents qui ressemblent à authors/books/chapters
, avec des auteurs, des livres et des chapitres configurés comme leur propre type de publication personnalisé. Par exemple, une URL typique sur ce site pourrait ressembler à example.com/authors/stephen-king/the-shining/chapter-3/
Chaque chapitre ne peut appartenir qu'à un seul livre et chaque livre ne peut appartenir qu'à un seul auteur. J'ai envisagé d'utiliser des taxonomies au lieu des CPT pour les auteurs et les livres, mais je dois associer des métadonnées à chaque élément et je préfère l'interface de publication pour cela.
Je fais presque tout mon chemin en configurant simplement chaque publication personnalisée en tant qu'enfant d'une entrée dans le CPT d'un niveau supérieur. Par exemple, je crée "Chapitre 3" et assigne "The Shining" en tant que parent à l'aide d'une méta-boîte personnalisée. "The Shining" à son tour a "Stephen King" en tant que parent. Je n'ai eu aucun mal à créer ces relations.
J'utilise des balises de réécriture dans les slugs du CPT et les permaliens veulent fonctionner, mais ils ne sont pas tout à fait corrects. À l'aide d'un analyseur de réécriture, je peux voir que les règles de réécriture sont réellement générées, mais elles ne semblent pas être dans le bon ordre et les autres règles sont donc traitées en premier.
Voici comment j'ai enregistré mes CPT:
function cpt_init() {
$labels = array(
'name' => 'Authors'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array(
'slug' => 'author',
'with_front' => FALSE,
),
'with_front' => false,
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => true,
'menu_position' => null,
'supports' => array( 'title', 'editor' )
);
register_post_type('authors',$args);
$labels = array(
'name' => 'Books'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array(
'slug' => 'author/%authors%',
'with_front' => FALSE,
),
'with_front' => false,
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => true,
'menu_position' => null,
'supports' => array( 'title', 'editor' )
);
register_post_type('books',$args);
$labels = array(
'name' => 'Chapters'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array(
'slug' => 'author/%authors%/%books%',
'with_front' => FALSE,
),
'with_front' => FALSE,
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => true,
'menu_position' => null,
'supports' => array( 'title', 'editor' )
);
register_post_type('chapters',$args);
}
add_action( 'init', 'cpt_init' );
Alors, y a-t-il un moyen de changer la priorité de mes règles de réécriture afin que les auteurs, les livres et les chapitres soient tous appariés en premier?
Je sais aussi que je vais devoir ajouter un filtre post_type_link
, mais cela semble secondaire si nous obtenons les permaliens correctement. Si quelqu'un sait où je peux trouver un aperçu complet du fonctionnement de ce filtre, nous vous en serions reconnaissants.
Si vous voulez conserver les 'auteurs' comme slug de base dans les permaliens, c'est-à-dire example.com/authors/stephen-king/ pour le CPT 'auteurs', example.com/authors/stephen -king/the-shining/pour le CPT 'livres' et example.com/authors/stephen-king/the-shining/chapter-3/ pour le CPT 'chapitres', WordPress pense à peu près tout est un post "auteurs" ou un enfant hiérarchique d'un post "auteurs" et, puisque ce n'est pas le cas, WordPress devient finalement très confus.
Cela dit, il existe une solution de contournement assez basique, mais tant que votre structure de lien permanent suit toujours le même ordre: le mot "auteurs" est toujours suivi d'un slug auteur, qui est toujours suivi d'un slug livre toujours suivi. par un chapitre limace, alors vous devriez être bon pour aller.
Dans cette solution, il n'est pas nécessaire de définir le slug de réécriture dans la définition de type d'article personnalisé pour 'chapitres' et 'livres', mais définissez le slug 'auteurs' comme simplement 'auteurs', placez le code suivant dans votre functions.php fichier et "flush" vos règles de réécriture.
add_action( 'init', 'my_website_add_rewrite_tag' );
function my_website_add_rewrite_tag() {
// defines the rewrite structure for 'chapters', needs to go first because the structure is longer
// says that if the URL matches this rule, then it should display the 'chapters' post whose post name matches the last slug set
add_rewrite_rule( '^authors/([^/]*)/([^/]*)/([^/]*)/?','index.php?chapters=$matches[3]','top' );
// defines the rewrite structure for 'books'
// says that if the URL matches this rule, then it should display the 'books' post whose post name matches the last slug set
add_rewrite_rule( '^authors/([^/]*)/([^/]*)/?','index.php?books=$matches[2]','top' );
}
// this filter runs whenever WordPress requests a post permalink, i.e. get_permalink(), etc.
// we will return our custom permalink for 'books' and 'chapters'. 'authors' is already good to go since we defined its rewrite slug in the CPT definition.
add_filter( 'post_type_link', 'my_website_filter_post_type_link', 1, 4 );
function my_website_filter_post_type_link( $post_link, $post, $leavename, $sample ) {
switch( $post->post_type ) {
case 'books':
// I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
// we need to find the author the book belongs to. using array_shift() makes sure only one author is allowed
if ( $author = array_shift( wp_get_object_terms( $post->ID, 'authors' ) ) ) {
if ( isset( $author->slug ) ) {
// create the new permalink
$post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $post->post_name ) );
}
}
break;
case 'chapters':
// I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
// we need to find the book it belongs to. using array_shift() makes sure only one book is allowed
if ( $book = array_shift( wp_get_object_terms( $post->ID, 'books' ) ) ) {
// now to find the author the book belongs to. using array_shift() makes sure only one author is allowed
$author = array_shift( wp_get_object_terms( $book->term_id, 'authors' ) );
if ( isset( $book->slug ) && $author && isset( $author->slug ) ) {
// create the new permalink
$post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $book->slug . '/' . $post->post_name ) );
}
}
break;
}
return $post_link;
}
Je n'ai pas d'expérience personnelle avec un tel scénario, mais Randy Hoyt a présenté le week-end dernier à WordCamp San Fran une présentation sur les "types de publications subordonnées" qui ressemble à ce dont vous parlez.
Voici sa page de présentation contenant les diapositives de sa présentation et des liens vers un plug-in qu'il a conçu pour travailler avec des types de publication subordonnés: http://randyhoyt.com/wordpress/subordinate-post-types/
Les règles seront ajoutées à l'extra_rules_top de WP_Rewrite dans l'ordre dans lequel les privilèges supplémentaires sont ajoutés. Ainsi, en changeant l'ordre dans lequel vous enregistrez les types d'article, vous inverserez l'ordre dans lequel les règles de réécriture seront générées pour que la réécriture de chapitre soit mise en correspondance en premier. Cependant, étant donné que vous utilisez la requête_var des autres posts_types, il se peut que wp_query corresponde à l'un de ceux-ci en tant que nom de post demandé avant de faire correspondre le chapitre comme vous le souhaitez.
Je créerais de nouvelles balises de réécriture pour représenter les espaces réservés de l'auteur et du livre parent, à savoir:
add_rewrite_tag('%parent-book%', '([^/]+)', 'parent_book=');
Ce faisant, vous devrez filtrer 'query_vars' pour rendre public 'parent_book'. Ensuite, vous devrez ajouter un filtre à pre_get_posts qui convertira le nom défini en tant que parent_book query_var en post_id et le définira en tant que 'post_parent'.