web-dev-qa-db-fra.com

Filtrer et répertorier les publications d'une taxonomie personnalisée

J'ai une taxonomie personnalisée appelée "propriétaire" et elle comporte plusieurs publications en tant que noms de propriétaire (Utilisation en tant que catégorie) afin que je puisse filtrer les publications en fonction de la taxonomie "propriétaire".

J'essaie de faire une page d'index de tous les noms de propriétaires qui commence par la lettre 'A'. J'ai pu lister tous les propriétaires avec le code suivant.

foreach ( get_terms( 'owner' ) as $o ){
        $owner = $o -> name;
        if($owner[0] === 'A'){
            // Coding here...
        }
}

Le problème auquel je suis confronté est que je veux montrer une pagination au bas de la page car il y a des centaines d'auteurs stars avec "A".

2
madhushankarox

Avant d'examiner la pagination, d'après ce que j'ai relevé dans votre question, vous n'avez besoin que de termes commençant par A. Si tel est le cas, vous pouvez utiliser le paramètre name__like dans get_terms pour obtenir uniquement les termes commençant par A. Juste une note à ce sujet, le fonctionnement du paramètre a été modifié dans Wordpress V3.7, vous devrez donc appliquer le filtre suivant pour que cela fonctionne comme prévu (, à la hauteur de @s_ha_dum, voir sa réponse.) ici . REMARQUE: le code nécessite PHP 5.4 + )

add_filter( 'terms_clauses', function ($clauses) 
{
  remove_filter( 'term_clauses', __FUNCTION__ );

  $pattern = '|(name LIKE )\'%(.+%)\'|';
  $clauses['where'] = preg_replace($pattern,'$1 \'$2\'',$clauses['where']);
  return $clauses;
});

$terms = get_terms( 'ownwer' ['name__like' => 'A'] );

Pour paginer une liste de termes, nous avons besoin de:

  • Le numéro de page actuel

  • La quantité totale de termes dans la liste

  • La quantité totale de pages il y aura

Pour obtenir le numéro de page de la page en cours ou une page est facile. Cela fonctionnera sur toutes les pages, y compris les pages de garde statiques et les pages à publication unique.

if ( get_query_var( 'paged' ) ) {
    $current_page = get_query_var( 'paged' );
} elseif ( get_query_var( 'page' ) ) {
    $current_page = get_query_var( 'page' );
} else {
    $current_page = 1;
}

Nous devons maintenant connaître le nombre total de termes de la taxonomie. Ici, nous pouvons utiliser wp_count_terms() , qui utilise get_terms() ou utiliser get_terms() lui-même. Rappelez-vous, si nous utilisons le filtre pour obtenir les termes avec une lettre/un nom spécifique, le filtre sera appliqué à cette exécution de get_terms()/wp_count_terms() ainsi que l'utilisation que nous faisons d'une fermeture

$terms_count = get_terms( 'owner', ['name__like' => 'A', 'fields' => 'count'] );

Nous avons maintenant le nombre total de termes correspondant à nos critères. Rappelez-vous simplement que si vous allez utiliser wp_count_terms(), n'oubliez pas de définir hide_empty sur true si vous n'avez pas besoin d'inclure des termes vides. Par défaut, wp_count_terms() définit ceci sur false

Maintenant, nous pouvons calculer notre nombre maximum de pages

// Set the amount of terms we need to display per page
$terms_per_page = 10;
// Get the total amount of pages
$max_num_pages = $terms_count / $terms_per_page;

Pour obtenir des liens de pagination vers les pages suivantes et précédentes, c'est très simple. La seule chose qu'une fonction de pagination a besoin de savoir d'une requête est le nombre maximal de pages, rien d'autre. Il n'a pas besoin de savoir ce qu'il faut paginer. Nous pouvons donc simplement utiliser les fonctions next_posts_link() et previous_posts_link(). Vous pouvez également utiliser paginate_links() ou même écrire votre propre fonction pour répondre à vos besoins. N'oubliez pas de passer $max_num_pages comme nombre maximal de pages à la fonction de pagination

next_posts_link( 'Next terms', $max_num_pages );
previous_posts_link( 'Previous terms' );

La seule chose qu'il nous reste à faire est de paginer get_terms(), ce qui est également très facile. Nous utiliserons le paramètre offset pour décaler les termes en fonction de page et number pour obtenir le nombre requis de termes par page.

// Calculate offset
$offset = ( $current_page == 1) ? 0 : ( ($current_page - 1) * $terms_per_page );
// Setup our arguments
$args = [
    'number' => $terms_per_page,
    'offset' => $offset
];

Nous pouvons maintenant tout mettre ensemble

TOUS ENSEMBLE MAINTENANT

Juste avant, quelques notes importantes

  • Tout le code n'est pas testé

  • Le code nécessite au moins PHP 5.4, ce qui correspond au minimum absolu PHP version que vous devriez exécuter au moment de ce message.

  • Modifier et déchirer si nécessaire

Voici le code, enfin

add_filter( 'terms_clauses', function ($clauses) 
{
  remove_filter( 'term_clauses', __FUNCTION__ );

  $pattern = '|(name LIKE )\'%(.+%)\'|';
  $clauses['where'] = preg_replace($pattern,'$1 \'$2\'',$clauses['where']);
  return $clauses;
});

$taxonomy = 'owner';

$terms_count = get_terms( $taxonomy, ['name__like' => 'A', 'fields' => 'count'] );
if ( $terms_count && !is_wp_error( $terms ) ) {

    if ( get_query_var( 'paged' ) ) {
        $current_page = get_query_var( 'paged' );
    } elseif ( get_query_var( 'page' ) ) {
        $current_page = get_query_var( 'page' );
    } else {
        $current_page = 1;
    }


    // Set the amount of terms we need to display per page
    $terms_per_page = 10;
    // Get the total amount of pages
    $max_num_pages = $terms_count / $terms_per_page;

    // Calculate offset
    $offset = ( $current_page == 1) ? 0 : ( ($current_page - 1) * $terms_per_page );
    // Setup our arguments
    $args = [
        'number' => $terms_per_page,
        'offset' => $offset,
        'name__like' => 'A'
    ];
    $terms = get_terms( $taxonomy, $args );

    // Do what you need to do with $terms

    next_posts_link( 'Next terms', $max_num_pages );
    previous_posts_link( 'Previous terms' );

}
5
Pieter Goosen

Si vous souhaitez uniquement limiter visuellement le nombre de noms affichés, vous pouvez utiliser javascript ou jQuery et CSS pour paginer les résultats en fragments plus petits que les visiteurs peuvent lire. Mais cela ne créera pas de pages réelles et distinctes.

Je mettrai à jour cette réponse avec un morceau de code que j'avais l'habitude de limiter à une longue liste de X nombres d'éléments, que vous parcourez avec un lien précédent/suivant, mais que vous pouvez facilement ajouter à une pagination numérotée.

Sinon, une recherche rapide a produit ce plugin (WordPress), mais je ne l’ai pas testé et je ne suis pas sûr de la compatibilité avec les versions actuelles de WP: http: // wordpress .mfields.org/plugins/taxonomy-list-shortcode/ Il semble que cela fasse exactement ce que vous voulez (PHP) sous la forme d’un shortcode.

Mise à jour: j'avais récupéré la majeure partie de ce code et je l'avais modifié pour l'adapter à mes besoins. Dans mon application, j'ai utilisé des fonctions pour désactiver et activer des éléments, etc., que j’ai converties ici en jQuery droit. Tenez-vous donc au courant qu’il pourrait rester un morceau de code personnalisé qui aurait besoin d’être modifié pour fonctionner avec votre composant.

Ceci dans jQuery:

var paginate_list = function(items) {
    var pageSize = items; // How many items per page
    var numberOfPages = Math.ceil(($('.lists li').length)/pageSize); // I used list items but you can use anything, this counts how many elements in total, and divides by the previous to know how many pages total
    var pageCounter = $("#current-page"); // I store the current page number in a hidden input value for my particular situation but you can keep track of it anyway else
    var prev = $('#navigation .key-prev');
    var next = $('#navigation .key-next'); // the navigation buttons
    pageCounter.val(1); // initialize to page 1, also peculiar to my application
    prev.attr('disable', true); // disable prev button if page 1
    if ( numberOfPages <= 1 ) {
        next.attr('disable', true); // disable next if only 1 page
    }
    next.on('click', function () {
        // calculate the list offset
        $(".lists li:nth-child(-n+" + ((pageCounter.val() * pageSize) + pageSize) + ")").show();
        $(".lists li:nth-child(-n+" + pageCounter.val() * pageSize + ")").hide();
        pageCounter.val(Number(pageCounter.val()) + 1); // update page counter
        if (pageCounter.val() != 1) {
            prev.attr('disable', false); // enable previous button
        }
        if (pageCounter.val() == numberOfPages) {
            $(this).attr('disable', true); // disable the next button when you reach the end
        }
    });
    prev.on('click', function () {
        // the same in reverse
        pageCounter.val(Number(pageCounter.val()) - 1);
        $(".lists li").hide();
        $(".lists li:nth-child(-n+" + (pageCounter.val() * pageSize) + ")").show();
        $(".lists li:nth-child(-n+" + ((pageCounter.val() * pageSize) - pageSize) + ")").hide();
        if (pageCounter.val() == 1) {
            $(this).attr('disable', true);
        } 
        if (pageCounter.val() < numberOfPages) {
            next.attr('disable', false);
        } 
    });
};

Et cela fonctionnerait avec des listes comme celle-ci:

<ul class="lists">
  <li><!-- your first item --></li>
  <li><!-- your second item --></li>
  <li><!-- your third item --></li>
  <li><!-- your fourth item etc... --></li>
</ul>
2
gloria