Filtrar y listar publicaciones de una taxonomía personalizada

2

Tengo una taxonomía personalizada llamada "propietario" y tiene varias publicaciones como nombres de propietarios (se usa como una categoría), por lo que puedo filtrar las publicaciones según la taxonomía de "propietario".

Estoy tratando de hacer una página de índice de todos los nombres de propietarios que comienza con la letra 'A'. Pude listar a todos los propietarios con el siguiente código.

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

El problema al que me enfrento es que quiero mostrar una paginación en la parte inferior de la página porque hay cientos de autores estrellas con 'A'.

    
pregunta madhushankarox 11.10.2015 - 18:49

2 respuestas

5

Antes de ver la paginación, de lo que he recogido en su pregunta, solo necesita términos que comiencen con A . Si es así, puede utilizar el parámetro name__like en get_terms para obtener los términos que comienzan con A . Solo una nota al respecto, la operación del parámetro se cambió en Wordpress V3.7, por lo que deberá aplicar el siguiente filtro para que funcione como se esperaba ( Crédito a @s_ha_dum, vea su respuesta aquí . NOTA: El código requiere 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'] );

Para paginar una lista de términos, necesitamos:

  • El número de la página actual

  • La cantidad total de términos en la lista

  • Total de páginas que habrá

Para obtener el número de página de la página actual o de cualquier página es fácil. Esto funcionará en todas las páginas, incluidas las páginas frontales estáticas y las páginas de publicación única

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;
}

Ahora necesitamos saber la cantidad total de términos de la taxonomía. Aquí podemos usar wp_count_terms() , que usa get_terms() o usa get_terms() . Recuerde, si usamos el filtro para obtener términos por una letra / nombre específico, el filtro se aplicará a esta ejecución de get_terms() / wp_count_terms() , así como también estamos haciendo uso de un cierre

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

Ahora tenemos la cantidad total de términos que coinciden con nuestros criterios. Solo recuerde, si va a utilizar wp_count_terms() , recuerde establecer hide_empty en verdadero si no necesita incluir términos vacíos. De forma predeterminada, wp_count_terms() establece esto en false

Ahora podemos calcular nuestra cantidad máxima de páginas

// 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;

Para obtener enlaces de paginación a las páginas siguientes y anteriores, es realmente fácil. Lo único que una función de paginación necesita saber de cualquier consulta es la cantidad máxima de páginas, nada más. No necesita saber lo que debe paginar. Así que simplemente podemos usar las funciones next_posts_link() y previous_posts_link() . También puede hacer uso de paginate_links() o incluso escribir su propia función para satisfacer sus necesidades. Solo recuerde pasar $max_num_pages como la cantidad máxima de páginas a la función de paginación

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

Lo único que todavía tenemos que hacer es paginar get_terms() , que también es muy fácil. Haremos uso del parámetro offset para compensar los términos según la página y number para obtener la cantidad requerida de términos por página

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

Ahora podemos poner todo junto

TODOS JUNTOS AHORA

Antes de que lo hagamos, un par de notas importantes

  • Todo el código no está probado

  • El código necesita al menos PHP 5.4, que es la versión mínima absoluta de PHP que debe estar ejecutando en el momento de esta publicación

  • Modifique y desmonte según sea necesario

Aquí está el código, finalmente

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' );

}
    
respondido por el Pieter Goosen 17.10.2015 - 08:53
2

Si solo quiere limitar visualmente el número de nombres mostrados, puede usar javascript o jQuery y CSS para compaginar los resultados en fragmentos más pequeños que los visitantes puedan leer. Pero esto no creará páginas reales y distintas.

Actualizaré esta respuesta con un fragmento de código que utilicé para limitar una larga lista a X números de elementos, que navegas con un enlace anterior / siguiente, pero también puede agregar fácilmente una paginación numerada a.

De lo contrario, una búsqueda rápida produjo ese complemento (de WordPress), pero no lo he probado, y no estoy seguro de la compatibilidad con las versiones actuales de WP: enlace Parece que hace exactamente lo que quieres (PHP) en forma de código corto.

Actualización: había eliminado la mayor parte de este código de algún lugar y lo había modificado para adaptarlo a mis necesidades. En mi aplicación utilicé funciones para deshabilitar y habilitar elementos, etc., que revertí aquí a jQuery directo, así que tenga en cuenta que podría haber una pieza u otra de código personalizado que permanecerá allí y que deberá cambiar para que funcione con su cosa.

Esto en 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);
        } 
    });
};

Y funcionaría con listas como esta:

<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>
    
respondido por el gloria 16.10.2015 - 20:40

Lea otras preguntas en las etiquetas