Como paginar uma lista de termos de taxonomia personalizados?

Eu fiz uma taxonomia personalizada chamada “livros” e com uma pequena ajuda no SE, eu consegui exibir seus conteúdos em uma grade de imagem, o código abaixo mostra como eu fiz isso:

add_shortcode('taxography' , 'execute_taxography' ); function execute_taxography() { $wpbtags = get_terms( 'books' ); $output.= ''; return $output; } 

Agora eu apenas crio uma nova página e coloco o shortcode [taxography] e funciona, mas o que estou tentando fazer é adicionar uma paginação para que esta página exiba apenas uma quantidade específica de livros (ex: 12 livros). Eu segui essa resposta e muitos outros, mas ainda não consigo resolver esse problema! Alguma ideia?

Solutions Collecting From Web of "Como paginar uma lista de termos de taxonomia personalizados?"

Seu shortcode é extremamente caro para executar. get_term_link() não é amigável quando você o alimenta com ID de termo, pois resulta em uma consulta db para consultar o termo object. Se você alimentar o termo object para get_term_link() , é feliz e não precisa fazer nenhum trabalho para obter o termo object.

Apenas veja rapidamente essa seção

 function get_term_link( $term, $taxonomy = '' ) { global $wp_rewrite; if ( !is_object($term) ) { if ( is_int( $term ) ) { $term = get_term( $term, $taxonomy ); } else { $term = get_term_by( 'slug', $term, $taxonomy ); } } 

Como você pode ver, se o $term não é um object de termo, mas o termo ID ou slug, chamadas extras são feitas para db para obter o termo object. Tudo isso significa que, se você tiver 100 termos e você precisa obter o link para a página do termo, e você passa a ID ou slug para get_term_link() , você está fazendo 100 chamadas db extras. Porque você já tem o termo object, simplesmente alimente isso para get_term_link() e você economiza chamadas de 100 db.

Quanto à paginação e como fazê-lo funcionar, você só precisa saber quantos termos você tem, divida-o por quantos termos por página você precisa e terá a quantidade máxima de páginas que haverá. Você também precisa calcular o deslocamento do termo, que será a quantidade de termos por página vezes o número da página atual

Apenas uma nota, você não gostaria de URL de código rígido, você gostaria de usar o valor dynamic. Olhe para wp_upload_dir() para retornar o caminho para o diretório de upload, por isso certifique-se de alterar isso em conformidade no seu código curto

 add_shortcode( 'taxography', function ( $atts ) { $attributes = shortcode_atts( [ 'terms_per_page' => 12, 'taxonomy' => 'books', // Add any attribute which you seem fit ], $atts, 'taxography' ); // Sanitize and validate our inputs and set variables $tpp = filter_var( $attributes['terms_per_page'], FILTER_VALIDATE_INT ); $taxonomy = filter_var( $attributes['taxonomy'], FILTER_SANITIZE_STRING ); // Make sure our taxonomy exists to avoid unnecessary work if ( !taxonomy_exists( $taxonomy ) ) return false; // Our taxonomy exists, lets continue // Get the term count to calculate pagination. $term_count = get_terms( $taxonomy, ['fields' => 'count'] ); // Check if we have terms to avoid bugs if ( !$term_count ) return false; // We have terms, now calculate pagination $max_num_pages = ceil( $term_count / $tpp ); // Get current page number. Take static front pages into account as well if ( get_query_var( 'paged' ) { $paged = get_query_var( 'paged' ); } elseif ( get_query_var( 'page' ) { $paged = get_query_var( 'page' ); } else { $paged = 1; } // Calculate term offset $offset = ( ( $paged - 1 ) * $tpp ); // We can now get our terms and paginate it $args = [ 'number' => $tpp, // Amount of terms to return 'offset' => $offset // The amount to offset the list by for pagination ]; // Set our variable to hold our string $output = ''; $wpbtags = get_terms( $taxonomy, $args ); $output.= '
'; // Add our pagination links, I have used the default 'get_*_posts_link()'. Adjust accordingly $output .= get_next_posts_link( 'Next Terms', $max_num_pages ) . ''; $output .= get_previous_posts_link( 'Previous Terms' ) . ''; return $output; });

É uma boa idéia também verificar a API do Shortcode sobre como criar corretamente códigos curtos e como deve ser usado

EDITAR

Para links de paginação numerados, você pode usar uma versão modificada minha function de paginação que escrevi aqui em uma resposta . Certifique-se de verificar a minha resposta sobre como o código deve ser usado e como ele funciona.

Aqui está uma versão modificada para trabalhar com código como o seu, bem como para todo o tipo de consultas. Você deve poder usar a function conforme descrito, com a única modificação é que você pode passar um valor inteiro para query qual será a quantidade máxima de páginas

 /** * @author Pieter Goosen * @license GPLv2 * @link http://www.gnu.org/licenses/gpl-2.0.html * * This function returns numbered pagination links or text pagination links * depending what is been set * * Paginated numbered links uses get_pagenum_link() to return links to the * required pages * @uses http://wpseek.com/function/get_pagenum_link/ * * The pagination links uses next_posts_link() and previous_posts_link() * @uses http://codex.wordpress.org/Function_Reference/next_posts_link * @uses http://codex.wordpress.org/Template_Tags/previous_posts_link * * @param array $args An array of key => value arguments. Defaults below * - string query variable 'query' => $GLOBALS['wp_query'], * - string Previous page text 'previous_page_text' => __( '«' ), * - string Next page text 'next_page_text' => __( '»' ), * - string First page link text 'first_page_text' => __( 'First' ), * - string Last page link text 'last_page_text' => __( 'Last' ), * - string Older posts text 'next_link_text' => __( 'Older Entries' ), * - string Newer posts text 'previous_link_text' => __( 'Newer Entries' ), * - bool Whether to use links 'show_posts_links' => false, * - int Amount of numbered links to show 'range' => 5, * * @return string $paginated_text */ function get_paginated_numbers( $args = [] ) { //Set defaults to use $defaults = [ 'query' => $GLOBALS['wp_query'], 'previous_page_text' => __( '«' ), 'next_page_text' => __( '»' ), 'first_page_text' => __( 'First' ), 'last_page_text' => __( 'Last' ), 'next_link_text' => __( 'Older Entries' ), 'previous_link_text' => __( 'Newer Entries' ), 'show_posts_links' => false, 'range' => 5, ]; // Merge default arguments with user set arguments $args = wp_parse_args( $args, $defaults ); /** * Get current page if query is paginated and more than one page exists * The first page is set to 1 * * Static front pages is included * * @see WP_Query pagination parameter 'paged' * @link http://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters * */ 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; } // Get the amount of pages from the query $max_pages = ( is_object( $args['query'] ) ) ? (int) $args['query']->max_num_pages : (int) $args['query']; /** * If $args['show_posts_links'] is set to false, numbered paginated links are returned * If $args['show_posts_links'] is set to true, pagination links are returned */ if( false === $args['show_posts_links'] ) { // Don't display links if only one page exists if( 1 === $max_pages ) { $paginated_text = ''; }else{ /** * For multi-paged queries, we need to set the variable ranges which will be used to check * the current page against and according to that set the correct output for the paginated numbers */ $mid_range = (int) floor( $args['range'] / 2 ); $start_range = range( 1 , $mid_range ); $end_range = range( ( $max_pages - $mid_range +1 ) , $max_pages ); $exclude = array_merge( $start_range, $end_range ); /** * The amount of pages must now be checked against $args['range']. If the total amount of pages * is less than $args['range'], the numbered links must be returned as is * * If the total amount of pages is more than $args['range'], then we need to calculate the offset * to just return the amount of page numbers specified in $args['range']. This defaults to 5, so at any * given instance, there will be 5 page numbers displayed */ $check_range = ( $args['range'] > $max_pages ) ? true : false; if( true === $check_range ) { $range_numbers = range( 1, $max_pages ); }elseif( false === $check_range ) { if( !in_array( $current_page, $exclude ) ) { $range_numbers = range( ( $current_page - $mid_range ), ( $current_page + $mid_range ) ); }elseif( in_array( $current_page, $start_range ) && ( $current_page - $mid_range ) < = 0 ) { $range_numbers = range( 1, $args['range'] ); }elseif( in_array( $current_page, $end_range ) && ( $current_page + $mid_range ) >= $max_pages ) { $range_numbers = range( ( $max_pages - $args['range'] +1 ), $max_pages ); } } /** * The page numbers are set into an array through this foreach loop. The current page, or active page * gets the class 'current' assigned to it. All the other pages get the class 'inactive' assigned to it */ foreach ( $range_numbers as $v ) { if ( $v == $current_page ) { $page_numbers[] = '' . $v . ''; }else{ $page_numbers[] = '' . $v . ''; } } /** * All the texts are set here and when they should be displayed which will link back to: * - $previous_page The previous page from the current active page * - $next_page The next page from the current active page * - $first_page Links back to page number 1 * - $last_page Links to the last page */ $previous_page = ( $current_page !== 1 ) ? '' . $args['previous_page_text'] . '' : ''; $next_page = ( $current_page !== $max_pages ) ? '' . $args['next_page_text'] . '' : ''; $first_page = ( !in_array( 1, $range_numbers ) ) ? '' . $args['first_page_text'] . '' : ''; $last_page = ( !in_array( $max_pages, $range_numbers ) ) ? '' . $args['last_page_text'] . '' : ''; /** * Text to display before the page numbers * This is set to the following structure: * - Page X of Y */ $page_text = '' . sprintf( __( 'Page %s of %s' ), $current_page, $max_pages ) . ''; // Turn the array of page numbers into a string $numbers_string = implode( ' ', $page_numbers ); // The final output of the function $paginated_text = ''; } }elseif( true === $args['show_posts_links'] ) { /** * If $args['show_posts_links'] is set to true, only links to the previous and next pages are displayed * The $max_pages parameter is already set by the function to accommodate custom queries */ $paginated_text = next_posts_link( '', $max_pages ); $paginated_text .= previous_posts_link( '' ); } // Finally return the output text from the function return $paginated_text; } 

Você pode simplesmente adicioná-lo em qualquer lugar em suas functions.php ou em um plugin e, em seguida, ligue-o como segue em seu shortcode

Substituir

 // Add our pagination links, I have used the default 'get_*_posts_link()'. Adjust accordingly $output .= get_next_posts_link( 'Next Terms', $max_num_pages ) . ''; $output .= get_previous_posts_link( 'Previous Terms' ) . ''; 

com

 if ( function_exists( 'get_paginated_numbers' ) ) $output .= get_paginated_numbers( ['query' => $max_num_pages] );