web-dev-qa-db-fra.com

Faire deux vues d'archive de type de publication avec deux URL

Mises à jour du 6 février 2014 à préciser comme demandé dans les commentaires.

J'ai un type de message, nous l'appellerons "Projets", avec le slug "projets" pour lequel je voudrais offrir deux vues:

  1. liste vue (valeur par défaut)
  2. vue de la carte

J'aimerais que ces vues soient aux permaliens suivants:

  1. example.org/projects/ (page d'archive de type d'article par défaut, archive-projects.php)
  2. example.org/projects/map/

Comment puis-je gérer le fait d'indiquer à WordPress d'utiliser un modèle spécifique pour accéder à cette URL spécifique qui impliquerait sinon une publication Projects spécifique? Ce serait bien si cette redirection réussissait à conserver la requête d'archive de type post par défaut, mais je peux écrire une boucle secondaire dans le modèle si nécessaire. J'avais d'abord pensé que les terminaux étaient la solution, mais je suis à peu près sûr que ce n'est pas vrai.


Poste originale

J'ai un type de message - "Projets" - pour lequel je voudrais deux vues de son archive de type message. Le premier est une liste assez simple de projets triés par catégorie et le second est une vue cartographiée des projets. Créer des modèles pour ces deux vues ne pose pas de problème.

Comment puis-je créer ces deux vues différentes de l'archive Post Type, chacune avec une URL unique?

Idéalement, j'aimerais que le premier modèle soit celui par défaut à /projects/ et que le second affichage soit à /projects/map/.

Cela semblait être un critère de jugement personnalisé, mais ce commentaire sur une vieille question dont le titre décrit parfaitement ce que je cherche, laisse penser qu'il est impossible de définir un point de terminaison uniquement pour un critère personnalisé. post type archive.

Devrais-je alors utiliser une réécriture personnalisée ou devrais-je même envisager d’utiliser une solution davantage axée sur jQuery?

4
mrwweb

Approche mise à jour

La première pensée/suggestion que j'ai faite - comme vous l'avez dit - ne fonctionne pas tel que je le comprenais. Au moins, j'ai essayé et je ne pouvais pas le comprendre. Cela dit, ce que vous voulez est toujours réalisable, mais pas en utilisant un point de terminaison, ou du moins pas en utilisant la fonction add_rewrite_endpoint().

Cependant, je pensais que cela devrait être possible via une configuration de réécriture "ordinaire". Le code ci-dessous montre comment configurer une type de publication _, une variable de requête et une règle de réécriture, pour créer une vue personnalisée de l'archive de type de publication. Enfin et surtout, nous devons nous assurer de charger le bon modèle. Ceci est possible pour imiter un point final. Le code exemplaire devrait vous orienter dans la bonne direction afin que vous puissiez l'adapter à vos besoins.

Code:

// minimal setup to register the new post type
add_action( 'init', 'wpse130664_pt_rw_ep_cpt');
function wpse130664_pt_rw_ep_cpt() { 
    register_post_type( 'rw_ep_cpt', 
        array(
            'label' => __( 'rw_ep_cpt', 'rw_ep_cpt_textdomain' ),
            'public' => true,
            // the archive slug defaults to the post type name »rw_ep_cpt«
            'has_archive' => true
        )
    );  
} 

// add a new query variable
add_filter('init', 'wpse130664_pt_archive_qv');
function wpse130664_pt_archive_qv() {
    global $wp;
    $wp->add_query_var('aview');
}

// add a new rewrite rule
add_filter('init', 'wpse130664_pt_archive_rw_rule');
function wpse130664_pt_archive_rw_rule() {
    // we're adding »aview« as a possibility to the slug 
    // of the custom post type archive we registered above
    // no need to match anything, e.g. with »$matches[1]«
    // so we're defaulting the aview query variable to 1
    // this kind of emulates a endpoint
    add_rewrite_rule( "rw_ep_cpt/aview$", "index.php?post_type=rw_ep_cpt" . '&aview=1', 'top' );
}

// load the »aview« template
add_filter( 'template_include', 'wpse130664_aview_tmpl_red' );
function wpse130664_aview_tmpl_red( $original_template ) {
    // we're loading the template conditionally, 
    // but only if we're actually at the »aview« "endpoint"
    if ( 1 == intval(get_query_var('aview')) ) {
        // you've to create the template you want to use here
        return get_template_directory().'/archive-aview.php';
    } else {
        return $original_template;
    }
}


Répondre au commentaire

En attendant, je suis curieux de savoir pourquoi vous avez choisi d'utiliser les méthodes du $wp global plutôt que les fonctions get_query_var() et add_query_var()?

Pour être honnête, j'ai réutilisé du code que j'ai écrit il y a quelque temps, je ne l'ai que légèrement adapté pour l'adapter à vos besoins. Là, j'ai utilisé l'approche ci-dessus, avec le $wp global. Mais bien sûr, ce n’est pas une explication pour le pourquoi, alors j’essaie de répondre à cela aussi.

Si je ne me trompe pas complètement, add_query_var() est uniquement disponible en tant que fonction/méthode de la classe WP. Donc, la manière ci-dessus est juste la façon de le faire.

En ce qui concerne get_query_var(), vous pouvez utiliser celui-ci à la place, mais il globalise $wp_query et utilise la fonction/méthode get() de la classe WP_Query. D'une certaine manière, la différence n'est pas ou ne devrait pas être grande.

En plus de cela, encore une pensée, l'objet WP_Query est susceptible d'être plus gros que l'objet WP, si ce n'est toujours. Donc, le faire via $wp global pourrait en fait être une bonne chose.
Mais en réalité, je n’ai pas pensé et testé ce creux, je l’ai utilisé comme ça et cela fonctionne dans ma configuration, donc j’ai été satisfait de ce code. Il pourrait donc y avoir un inconvénient dans une autre configuration/cas d’utilisation. Ou le faire autrement pourrait être plus utile/bénéfique dans d'autres cas. Mais comme je l’ai dit plus haut, c’est pour commencer, vous devez l’adapter vous-même à vos besoins.

Mise à jour après commentaire

Un billet de blog au bon moment de @MarkJaquith m'a activé le filtre template_include qui convient mieux à l'inclusion d'un nouveau fichier de modèle. J'ai mis à jour mon code pour utiliser ce filtre et je vous recommande également de mettre à jour l'exemple de code.

Comme @mrwweb l'a souligné et expliqué dans l'article lié ci-dessus, le filtre template_redirect n'est pas optimal pour choisir un autre modèle. Ou comme @MarkJaquith conclut simplement:

→ template _ redirect est pour redirections .
→ template _ include est pour includes .

Il m'a convaincu, alors j'ai changé la façon dont le modèle "aview" se charge dans le filtre template_include dans le code ci-dessus.




Première pensée/approche


Avertissement:
Je garde cela, à cause de sa valeur informative, mais ceci ne fonctionnera pas pour l'archive de type publication personnalisée. Cependant, utiliser ep_mask est pratique pour créer des points de terminaison pour les publications de type publication personnalisée unique.


D'après ce que je comprends, les points limites peuvent être atteints dans de tels cas. J'ai récemment lu cela, mais je n'ai jamais eu à le faire. Au meilleur de ma connaissance, peut-être que quelqu'un avec beaucoup plus de ressources viendra éclaircir les choses.

Vous avez raison avec ce que vous avez dit:

Si j'ai bien compris, les ordinateurs d'extrémité ne fonctionnent pas pour les archives de type publication. Ils sont destinés aux publications de ce type de publication mais pas à l'archive elle-même.


Vous pouvez donc utiliser le paramètre ep_mask comme décrit ci-dessous pour les publications d'un type de publication personnalisé, mais not pour l'archive. A côté de cela, jouer avec Cela m'a fait comprendre à quel point un ep_mask personnalisé peut être pratique pour la création de noeuds finaux de type message personnalisé.

Fondamentalement, ce que j'ai lu pinnacled en utilisant l'argumentep_maskque vous avez disponible lorsque vous utilisez

et

rewrite argument.

Jetez un coup d’œil au ticket trac 19275 . Vous pouvez trouver des informations supplémentaires éventuellement utiles sur la page de codex register_post_type() à la description de permalink_epmask, en particulier le ticket trac 12605 .

En ce qui concerne les points finaux:

Voici une réponse sur:

bien sûr, pour les catégories, il existe déjà EP_CATEGORIES, mais cela montre que cela devrait vraiment être possible si vous utilisez l’argument ep_mask.

5
Nicolai

Mise à jour du 03/12/17

Le plugin mentionné ci-dessous est abandonné, ce que je maintiens actuellement est un autre paquet, Cortex


Considérez ma réponse comme une alternative.

J'ai développé un plugin, Clever Rules , qui permet de spécifier un itinéraire, une requête et (entre autres) un modèle spécifique.

Ce dont vous avez besoin avec Clever Rules, c'est d'enregistrer une règle, mais veuillez noter qu'avec la version actuelle vous ne pouvez enregistrer de règles que dans des plugins, pas dans themes .

Téléchargez Clever Rules, activez-le. Maintenant, vous avez besoin d'un plugin pour enregistrer vos règles: vous pouvez créer un nouveau plugin ou insérer le code suivant dans un plugin que vous développez ...

add_action('plugins_loaded', 'register_my_rules');

function register_my_rules() {

    // next line ensure function runs only if Clever Rules is installed
    if ( ! function_exists('register_clever_rule') ) return;

    $args = array( 'route' => '/projects/map/', 'query' => 'post_type=projects' );

    register_clever_rule( $args )->template('your-specific-template.php');

}

Ces 3 lignes de code est la seule chose dont vous avez besoin . Si vous avez créé un nouveau plugin pour cela, activez-le, bien sûr.

Aucune des URL par défaut ne sera affectée.

'votre-spécifique-template.php' peut être un fichier de modèle dans le thème parent ou même enfant. Bien sûr, vous pouvez personnaliser la requête comme bon vous semble et utiliser d'autres fonctionnalités du plugin.

Et si vous aimez le système, vous pouvez utiliser le même plugi pour enregistrer toutes les règles dont vous avez besoin.

Remarques

Je développe une nouvelle version de ce plugin, qui sera un peu plus performante (quand il y a beaucoup de règles, une seule n'est pas un problème), permet l'enregistrement des règles dans les thèmes, a une API légèrement différente et quelques fonctionnalités supplémentaires. Il sera bientôt publié, cependant, la version actuelle fonctionne aussi.

1
gmazzap