web-dev-qa-db-fra.com

Fixation de la pagination avec une archive de taxonomie personnalisée

J'ai essayé de mettre en place un moyen d'écrire des articles d'une série sur mon site. L'idée est que chaque publication peut appartenir à une série différente dans une taxonomie personnalisée. J'ai à peu près tout configuré comme je le veux ... à une exception près.

Enregistrement de la taxonomie

Cette partie fonctionne. J'ai déposé le code suivant dans un plug-in:

function jdm_build_series_taxonomy() {
    $labels = array(
        'name' => _x('Series Labels', 'taxonomy general name'),
        'singular_name' => _x('Series Label', 'taxonomy singular name'),
        'search_items' => __('Search Series Labels'),
        'popular_items' => __('Popular Series Labels'),
        'all_items' => __('All Series Labels'),
        'parent_item' => __('Parent Series Label'),
        'parent_item_colon' => __('Parent Series Label:'),
        'edit_item' => __('Edit Series Label'),
        'update_item' => __('Update Series Label'),
        'add_new_item' => __('Add New Series Label'),
        'new_item_name' => __('New Series Label Name')
    );

    register_taxonomy(
        'series',
        'post',
        array(
            'hierarchical' => true,
            'label' => __('Series'),
            'labels' => $labels,
            'query_var' => true,
            'rewrite' => true
        )
    );
}

add_action( 'init', 'jdm_build_series_taxonomy', 0 );

Cela ajoute "Étiquettes de série" au menu déroulant Messages et me donne une boîte "Étiquettes de série" sur l'écran d'édition. Tout fonctionne, et je peux parfaitement marquer les posts dans une série. Le problème réside dans la section suivante ...

Liste des éléments dans la taxonomie

Mon objectif est de permettre aux lecteurs de parcourir une série de publications, poste par message, en commençant par le plus ancien, puis chronologiquement. Ceci est différent d’une page d’archive classique, car j’ai 10 articles par page pour mes archives, mais je veux évidemment un seul article par page pour les archives de ma série.

J'ai créé un fichier taxonomy-series.php dans mon modèle. Et il half fonctionne. La première page fonctionnera parfaitement - http://localhost/wp/series/my-test-series/ affiche le premier article de la série avec le lien "Entrée suivante" "au bas de la page. Jusqu'ici tout va bien ...

Mais lorsque vous cliquez sur "Entrée suivante" "et passez à la page suivante (http://localhost/wp/series/my-test-series/page/2/), c'est a) le mauvais article et b) le mauvais modèle!

Cependant, si je règle "Les pages de blog tout au plus:" sur "1" sur la page de lecture (il est normalement réglé sur 10), tout se passe bien. La page 2 affiche le deuxième article, la page 3, le troisième, etc.

Alors ... que dois-je vérifier pour forcer la page d'archive de taxonomie à n'afficher qu'un seul post sur chaque page? J'ai essayé ce qui suit:

$new_query = wp_parse_args(
    $query_string, 
    array(
        'posts_per_page' => 1,
        'paged' => $paged
    )
);

query_posts($new_query);

et

query_posts($query_string.'&posts_per_page=1&paged='.$paged);

en vain ... des idées? Conseils? Suggestions?

4
EAMann

Bonjour @EAMann :

Je ressens à chaque fois que je dois faire quelque chose de créatif avec les URL dans WordPress, car le système d'URL est de loin l'aspect le plus inélégant de WordPress. J'ai toujours le sentiment que je dois me battre avec WordPress pour le faire faire ce que je veux, et que WordPress me défend activement en ce qui concerne les URL. Donc, avec cette ouverture ...

En réfléchissant à votre problème, je vais faire une suggestion qui ne correspond pas exactement à ce que vous avez demandé. Si vous ne trouvez pas ce que vous cherchez, ce n'est pas grave, ne votez pas, il vous suffit de voter à voix basse, car j'essaie simplement de vous aider.

La taxonomie n'est pas simple et n'a pas de méta

Un des problèmes avec ce que vous essayez de faire est le système de taxonomie ne fait pas un seul ordre d’incréments et il n’a pas de méta . Par exemple, dans une série de 3 publications, vous pouvez trouver des termes avec IDs de 373, 411 et 492; vous pouvez comprendre que 373 = #1, 411 = #2 et 492 = #3, mais c'est tout un hasard et relatif l'un par rapport à l'autre. C'est comme essayer de localiser la racine de votre site WordPress dans le code du plugin, mais vous ne savez pas combien de niveaux votre code sera stocké. Bien sûr, je peux écrire du code pour comprendre tout cela et le mapper, mais cela devient difficile et je ne suis pas sûr que vous auriez beaucoup de valeur à essayer de le comprendre au lieu d'utiliser une approche différente.

Attribuer explicitement vos numéros de page

Donc, la première chose que je suggérerais est que vous attribuez explicitement vos numéros de page pour chaque message de votre série en utilisant les champs posts meta/custom (j'ai choisi plutôt le terme installment de page car cela me paraissait plus logique, mais vous pouvez utiliser n'importe quel terme qui convient à votre cas d'utilisation.)

L'attribution de numéros de page/de versement vous permet de contrôler parfaitement les choses. Ainsi, vous saurez quoi régler en cas de problème. Si vous souhaitez modifier l'ordre de votre commande, vous pouvez le faire en changeant simplement les numéros. Je suppose que vous aurez une métabox d'édition pour un nom de champ personnalisé _installment pour la sélection des numéros d'acomptes provisionnels (et qu'il pourrait même gérer/jongler avec les numéros d'acomptes provisionnels via AJAX si vous voulez faire preuve de créativité afin de ne jamais les pages ne sont pas synchronisées.)

Utilisez $wp_rewrite->add_rule() pour attribuer explicitement votre URL

Je n’entrerai pas dans les détails, car je sais que vous avez généralement des compétences en colère pour WordPress, je tiens donc à souligner que $wp_rewrite->add_rule() est le moyen de faire en sorte que tout cela fonctionne. Tout le reste ne fait que fournir un soutien autour du résultat de cette fonction. Utilisez le hook init pour attribuer votre règle d'URL:

<?php
add_action('init', 'add_series_installment_url');
function add_series_installment_url() {
  global $wp,$wp_rewrite;
  $wp->add_query_var('series');
  $wp->add_query_var('installment');
  $wp_rewrite->add_rule('series/([^/]+)/(installment-\d+)','index.php?series=$matches[1]&installment=$matches[2]','top');
  $wp_rewrite->flush_rules(false);  // This should really be done in a plugin activation
}

Utilisez le crochet parse_query pour convertir l'URL en requête Vars

La 2ème moitié de cette solution utilise le hook parse_query que je connais fort bien. En général, nous capturons le query_vars défini dans init et capturé via la règle d'URL et les convertissons en objets nécessaires pour interroger les publications WordPress avec taxonomy + term traitant votre series et meta_key + meta_value traitant le versement explicitement assigné:

<?php
add_action('parse_query', 'apply_series_installment_to_query');
function apply_series_installment_to_query(&$query) {
  if (isset($query->query['series']) && isset($query->query['installment']) && 
     preg_match('#^installment-(\d+)$#',$query->query['installment'],$match)) {
    $query->query_vars['post_type'] = 'post';
    $query->query_vars['taxonomy'] = 'series';
    $query->query_vars['term'] = $query->query['series'];
    $query->query_vars['meta_key'] = '_installment';
    $query->query_vars['meta_value'] = $match[1];
    unset($query->query_vars['series']);            // You don't need this
    unset($query->query_vars['installment']);       // or this
    unset($query->query_vars['name']);              // or this
  }
}

Résumé

Normalement, j'aurais beaucoup approfondi pour expliquer une réponse, mais il est tard, j'ai trop peu dormi depuis 48 heures et, surtout, je sais que vous pouvez le comprendre, vous avez probablement besoin d'une chose que j'ai mentionnée ici. .

J'espère donc que vous aimez cette solution. Même si vous ne possédez pas les deux parties avec init et parse_query et les fonctions $wp_rewrite->add_rule() et $query->query_vars[] respectivement, vous en aurez besoin, même si vous souhaitez conserver votre architecture d'origine. Bonne chance et au plaisir de le voir quand vous l'avez fait et en ligne!

Quoi qu'il en soit, espérons que cela aide.

6
MikeSchinkel

Voici le code que j'utilise pour modifier le nombre de publications sur les pages d'archives de catégories et de balises:

query_posts( array_merge( array(
'posts_per_page' => 1
), $wp_query->query ) );

Si vous ne pouvez pas utiliser cette taxonomie personnalisée, essayez avec native (categories, tags) de vérifier si le problème provient du code lui-même, de la taxonomie ou de tout autre élément.

De plus, je ne sais pas si vous avez manqué ceci ou si vous l'avez omis, mais $ paged n'est pas une variable globale. Il doit être récupéré en tant que get_query_var ('paged')

2
Rarst

Une fois que j’ai rencontré un problème à ce sujet et que j’ai passé des moments difficiles en tirant les cheveux. J'ai cherché sur Google et n'ai trouvé aucune solution spécifique sur les sujets. J'ai trouvé plusieurs articles de talents mais ils ne satisfaisaient pas mes problèmes. En fait, la pagination des pages d'archive de taxonomie personnalisée dépend de certains paramètres d'arguments de fonctions connexes. Je vais donc ici partager mes réflexions sur la résolution du problème de pagination des archives de taxonomie.

Cinq choses dont vous avez besoin pour que la pagination de page d'archive de taxonomie personnalisée fonctionne parfaitement:

(1) Ne mettez pas la clé de paramètre exclude_from_search comme paramètre d'argument register_post_type, ni définissez-la 'exclude_from_search' => false. Par défaut, il est défini false.

(2) La taxonomie qui sera utilisée avec le type de message personnalisé définissez 'taxonomies' => 'custom_taxonomy_name' en tant que paramètre register_post_type d'argument ou utilisez directement register_taxonomy_for_object_type(). Les taxonomies personnalisées doivent encore être enregistrées avec register_taxonomy().

(3) en interrogeant dans new WP_Query ($args)

i) Si non défini dans admin static front page, utiliser avant new WP_Query($args)

$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;

et utiliser $query = new WP_Query( array( 'paged' => $paged ) );

ii) S'il est défini dans la page d'accueil statique statique, utilisez avant 'new WP_Query ($ args)':

  $paged = ( get_query_var('page') ) ? get_query_var('page') : 1;

et utiliser $query = new WP_Query( array( 'page' => $paged ) );

N'oubliez pas d'utiliser les paramètres posts_per_page et paged dans le tableau d'arguments new WP_Query($arg).

Si vous ne définissez pas de page de garde statique, vous devez utiliser le paramètre page dans le tableau d'arguments new WP_Query ($arg).

(4) Utilisez la fonction Wordpress paginate_links( $args ) comme dans l'exemple ci-dessous pour afficher la pagination dans le fichier de modèle d'archive.

<?php $big = 999999999; // need an unlikely integer
echo paginate_links( array(
                  'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
                  'format' => '?paged=%#%',  or   '/paged=%#%',  // if using pretty permalink
                   'current' => max( 1, get_query_var('paged') ),
                   'total' => $query->max_num_pages ) ); // Here $max_num_pages is the properties of  new WP_Query() object . It is total number of pages. Is the result of $found_posts / $posts_per_page
 ?>

(5) La fonction paginate_links() affiche la liste ul li avec la classe page-numbers. Si vous utilisez bootstrap, injectez la classe pagination dans la ul à l’aide de javascript ou de jquery et une pagination de Nice fantaisie sera générée.

J'espère que vous pourrez maintenant profiter de la pagination dans le modèle d'archive de taxonomie sans aucun problème 404 :-)

0
saifulmasud