web-dev-qa-db-fra.com

Type d'article personnalisé avec taxonomie imbriquée et fichiers de modèle

J'ai un type de message personnalisé de "Portfolio" avec un slug de réécriture de portfolio. Donc, l'URL sur le frontend est: domain.com/portfolio.

J'ai une taxonomie personnalisée de "Catégories" avec un slug de réécriture de portfolio/category. Donc, l'URL sur le frontend est: domain.com/portfolio/category/<term-slug>/

Lorsque je visite domain.com/portfolio/, le modèle de type de message s’affiche parfaitement.

Lorsque je visite domain.com/portfolio/category/<term-slug>/, le modèle de terme de taxonomie s’affiche parfaitement.

Cependant, lorsque je visite: domain.com/portfolio/category/, le modèle de taxonomie ne fonctionne pas. Je reçois une erreur 404.

J'ai même testé sur le type de message principal: post et la taxonomie: category, avec la page de messages définie sur /blog/.

Même chose...

  • domain.com/blog/ Affiche parfaitement les messages, servis à partir du modèle home.php.
  • domain.com/blog/category/<term-slug>/ Affiche parfaitement, servi à partir du modèle category.php.
  • domain.com/blog/category/ Affiche l'erreur 404.

Une voie alternative que j'ai empruntée dans le passé consiste à créer une "page" pour ces erreurs 404. Ainsi, par exemple, /blog/ crée déjà une "page". Ensuite, je créerais /blog/category/ sur une autre page, de sorte que je ne reçoive pas d'erreur 404 lorsque l'utilisateur accède à: domain.com/blog/category/.

Est-ce comportement attendu? Y at-il un travail autour de ne pas avoir à créer des pages pour ces "archives de la taxonomie"?

Comment puis-je avoir une URL de taxonomie imbriquée et faire fonctionner le modèle taxonomy.php ou même archive.php?

1
Michael Ecklund

Ajout de termes de taxonomie à des URL de type de publication

Je pense avoir mis au point une solution temporaire à partir de diverses sources aléatoires en ligne.

J'aimerais que quelqu'un développe ma réponse pour la rendre plus "à l'épreuve des balles", pour ainsi dire. Cependant, à court terme, cette solution fonctionne.


Accrochez-vous aux règles de réécriture actuelles.

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

Nous ajouterons de nouvelles règles de réécriture à nos règles de réécriture existantes.

function mbe_rewrite_rules_array($rules){
    $new_rules = mbe_get_new_rewrite_rules();
    return ($new_rules + $rules);
}

Ajoutez de nouvelles règles de réécriture ... (À mon avis, certaines améliorations sont nécessaires - je ne suis pas averti des règles de réécriture.)

function mbe_get_new_rewrite_rules(){

    $post_type = 'mbe-portfolio';
    $post_type_slug = 'portfolio';

    $taxonomy = 'mbe-portfolio-categories';
    $taxonomy_slug = 'category';

    $slug = $post_type_slug.'/'.$taxonomy_slug;

    return array(
        "{$slug}/?$" => "index.php?post_type={$post_type}&taxonomy={$taxonomy}"
    );

}

En ajoutant la nouvelle règle de réécriture, WordPress ne voit plus domain.com/portfolio/category/ en tant que 404, mais en tant qu'archive Post Type.

Accrochez-vous dans le système de modèles pour afficher taxonomy.php lors de l'affichage de domain.com/portfolio/category/

add_filter('archive_template', 'mbe_taxonomy_template');

function mbe_taxonomy_template($template){

    $templates = array();

    $post_type = 'mbe-portfolio';
    $taxonomy = 'mbe-portfolio-categories';

    if(get_query_var('post_type') == $post_type && !get_query_var('taxonomy')){
        return $template;
    }

    if(get_query_var('post_type') == $post_type && get_query_var('taxonomy') == $taxonomy){
        $templates[] = 'taxonomy.php';
    }

    $templates[] = $template;

    return locate_template($templates);

}

Maintenant, si vous allez à domain.com/portfolio/category/, il charge taxonomy.php à partir de votre répertoire de thèmes WordPress actuellement actif.

Alors j'ai réfléchi un peu. Alors que taxonomy.php est chargé, plutôt que de vérifier si nous devrions afficher des informations sur une taxonomie ou des informations sur un terme de la taxonomie. J'ai décidé de créer un nouveau fichier modèle appelé term.php afin d'éviter toute confusion.

Accrochez-vous dans le système de modèles pour afficher term.php lors de l'affichage de domain.com/portfolio/category/<term-slug>

add_filter('taxonomy_template', 'mbe_term_template');

function mbe_term_template($template){

    $templates = array();

    $queried_object = get_queried_object();

    if(property_exists($queried_object, 'term_id')){
        $templates[] = 'term.php';
    }

    $templates[] = $template;

    return locate_template($templates);

}

Maintenant, si vous allez à domain.com/portfolio/category/<term-slug>, il charge term.php à partir de votre répertoire de thèmes WordPress actuellement actif.


Conclusion

  1. Lors de l'affichage de domain.com/portfolio/ - Les modèles d'archive par défaut sont chargés comme d'habitude. (archive.php, archive-posttype.php, etc.) de votre thème WordPress actuellement actif.
  2. Lors de l'affichage de domain.com/portfolio/category/ - Le fichier de modèle taxonomy.php est chargé à partir de votre thème WordPress actuellement actif.
  3. Lors de l'affichage de domain.com/portfolio/category/<term-slug> - Le fichier de modèle term.php est chargé à partir de votre thème WordPress actuellement actif.

Vous pouvez facilement tester pour voir si cela fonctionne. Vous avez seulement besoin de trois fichiers dans votre répertoire de thèmes WordPress actuellement actif. (archive.php ou archive-posttype.php, taxonomy.php et term.php)

Mettez ceci dans archive.php ou archive-posttype.php

$current_post_type = get_query_var('post_type');

echo '<p><strong>Current View:</strong> Post Type</p>'.PHP_EOL;
echo '<p><strong>Current Post Type:</strong> <code>'.$current_post_type.'</code></p>'.PHP_EOL;

Mettez ceci dans taxonomy.php

$current_post_type = get_query_var('post_type');
$current_taxonomy = get_query_var('taxonomy');

echo '<p><strong>Current View:</strong> Taxonomy</p>'.PHP_EOL;
echo '<p><strong>Current Post Type:</strong> <code>'.$current_post_type.'</code></p>'.PHP_EOL;
echo '<p><strong>Current View:</strong> <code>'.$current_taxonomy.'</code></p>'.PHP_EOL;

Mettez ceci dans term.php

$current_term = get_queried_object();

echo '<p><strong>Current View:</strong> Term</p>'.PHP_EOL;
echo '<p><strong>Current Term Name:</strong> <code>'.$current_term->name.'</code></p>'.PHP_EOL;
echo '<p><strong>Current Taxonomy:</strong> <code>'.$current_term->taxonomy.'</code></p>'.PHP_EOL;

S'il vous plaît ne sautez pas directement sur ce lien. Cependant, si vous avez lu toute la question et accepté la solution, vous êtes toujours perplexe. J'ai écrit un article de blog légèrement plus détaillé, ce qui pourrait vous aider à mieux comprendre.

1
Michael Ecklund

Cela est prévu et comment hiérarchie de modèles fonctionne. Je sais qu'il y a quelques années, un ticket de piste a été soulevé concernant cette question si un index pour les archives devait être introduit dans le noyau ou non. ( EDIT: trouvé le ticket, vérifiez-le ici: Ticket # 13816 Il devrait y avoir des pages d'index intégrées pour les taxonomies) Cette idée a été abandonnée et ne verra jamais la lumière en son centre. Donc, il y aura toujours cet espace pour une page d'index d'archive dans la hiérarchie de modèles

Vous pouvez toutefois créer une page d'index pour toutes vos archives séparées à l'aide de modèles de page. Par exemple, créez une nouvelle page, ajoutez ce que vous devez ajouter à cette page et attribuez-lui un slug de category. Désormais, lorsque vous visiterez domain.com/blog/category/, vous verrez la page de contenu/index que vous avez créée.

En dehors de cela, il n'y a pas d'autre solution à ma connaissance.

3
Pieter Goosen