Filtrar e listar postagens de uma taxonomia personalizada

2

Eu tenho uma taxonomia personalizada chamada 'owner' e ela tem várias postagens como nomes de proprietários (usando como categoria) para que eu possa filtrar postagens por taxonomia de 'proprietário'.

Estou tentando criar uma página de índice de todos os nomes de proprietários, começando com a letra 'A'. Consegui listar todos os proprietários com o seguinte código.

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

O problema que enfrento é que quero mostrar uma paginação na parte inferior da página porque existem centenas de estrelas de autores com 'A'.

    
por madhushankarox 11.10.2015 / 18:49

2 respostas

5

Antes de analisarmos a paginação, pelo que eu encontrei na sua pergunta, você só precisa de termos começando com A . Nesse caso, você pode usar o parâmetro name__like em get_terms para obter somente os termos que começam com A . Apenas uma nota sobre isso, a operação do parâmetro foi alterada no Wordpress V3.7, então você precisará aplicar o seguinte filtro para que isso funcione como esperado ( Crédito para @s_ha_dum, veja sua resposta aqui . NOTA: O código requer o 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 uma lista de termos, precisamos:

  • O número da página atual

  • A quantidade total de termos na lista

  • Total de páginas, haverá

Para obter o número da página atual ou qualquer página é fácil. Isso funcionará em todas as páginas, incluindo páginas frontais estáticas e páginas de postagem ú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;
}

Agora precisamos saber o total de termos da taxonomia. Aqui, podemos usar wp_count_terms() , que usa get_terms() ou usa get_terms() em si. Lembre-se, se usarmos o filtro para obter termos por uma letra / nome específico, o filtro será aplicado a essa execução de get_terms() / wp_count_terms() , assim como estamos usando um fechamento

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

Agora, temos o total de termos que correspondem aos nossos critérios. Lembre-se, se você for usar wp_count_terms() , lembre-se de definir hide_empty como verdadeiro se não precisar incluir termos vazios. Por padrão, wp_count_terms() define isso como false

Agora podemos calcular nossa quantidade 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 obter links de paginação para as páginas seguintes e anteriores, é muito fácil. A única coisa que uma função de paginação precisa saber de qualquer consulta é a quantidade máxima de páginas, nada mais. Não precisa saber o que deve paginar. Portanto, podemos simplesmente usar as funções next_posts_link() e previous_posts_link() . Você também pode usar paginate_links() ou até mesmo escrever sua própria função para atender às suas necessidades. Apenas lembre-se de passar $max_num_pages como a quantidade máxima de páginas para a função de paginação

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

A única coisa que ainda precisamos fazer é paginar get_terms() , o que também é muito fácil. Faremos uso do parâmetro offset para compensar os termos de acordo com a página e number para obter a quantidade necessária de termos 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
];

Agora podemos juntar tudo

TODOS JUNTOS AGORA

Pouco antes de fazermos, algumas notas importantes

  • Todo o código não foi testado

  • O código precisa pelo menos do PHP 5.4, que é a versão mínima do PHP que você deve estar executando no momento deste post

  • Modifique e separe conforme necessário

Aqui está o 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' );

}
    
por Pieter Goosen 17.10.2015 / 08:53
2

Se você quiser apenas limitar visualmente o número de nomes exibidos, você pode usar javascript ou jQuery e CSS para paginar os resultados em partes menores que os visitantes possam ler. Mas isso não criará páginas reais e distintas.

Eu atualizarei esta resposta com um pedaço de código que usei para limitar uma longa lista em X números de itens, que você navega com um link anterior / próximo, mas também pode facilmente adicionar uma paginação numerada.

Caso contrário, uma pesquisa rápida produziu esse (WordPress) plugin, mas eu não testei, e não tenho certeza sobre a compatibilidade com as versões atuais do WP: enlace Parece que faz exatamente o que você quer (PHP) na forma de um shortcode.

Atualização: eu havia limpado a maior parte deste código de algum lugar e modifiquei-o para atender às minhas necessidades. No meu aplicativo eu usei funções para desabilitar e habilitar elementos, etc, que reverti aqui em jQuery direto, então leve em consideração que pode haver uma peça ou outro código personalizado que permanece lá e precisará ser alterado para trabalhar com o seu negócio.

Isso em 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);
        } 
    });
};

E funcionaria com 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>
    
por gloria 16.10.2015 / 20:40