Paginação WP_Query em single-custom.php


16

O que eu estou procurando fazer:

Configurar WP_Querypaginação em um arquivo de modelo single-post-post-type.php

O que eu fiz

1) Criou um tipo de postagem chamado "autores". Cada postagem nesse tipo de postagem é um autor individual.

2) As páginas da tela de edição padrão contêm uma lista suspensa que lista todas as postagens (autores) do tipo de postagem personalizada dos autores.

3) Criou um modelo single-autores.php que consulta todas as postagens com os metadados do autor no menu suspenso; portanto, o resultado é uma lista de postagens que têm o mesmo autor atribuído a elas (como um arquivo):

<?php

// set the "paged" parameter (use 'page' if the query is on a static front page)
global $paged;

/*We need this here to add and maintain Pagination if Template is assigned to Front Page*/
if ( get_query_var( 'paged' ) ) {
    $paged = get_query_var('paged');
} elseif ( get_query_var( 'page' ) ) {
    $paged = get_query_var( 'page' );
} else {
    $paged = 1;
}

$args = array(
    'posts_per_page'    =>  10,
    'meta_key'          => 'author_select',
    'meta_value'        => $author_id,
    'paged'             => $paged,
);

$temp = $wp_query;
$wp_query = NULL;

$wp_query = new WP_Query($args);

?>

<?php if( $wp_query->have_posts() ) : ?>    
    <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
    <?php // Successfully outputs the results of the above query, so I've omitted the code from this example. ?>

    <?php endwhile; ?>

<div class="single_navigation"> 
    <?php if( get_adjacent_post( false, '', true ) ) { ?>
        <span class="prev"><?php previous_post_link( '&lt; %link' ) ?></span>
    <?php } ?>

    <?php if( get_adjacent_post( false, '', false ) ) { ?>
        <span class="next"><?php next_post_link( '%link &gt;' ) ?></span>
    <?php } ?>
    </div><!--/single navigation-->
<?php endif; ?>

<?php
    $wp_query = null;
    $wp_query = $temp;
    wp_reset_query();
?>

No que estou preso

Os links de paginação não aparecem. Eu fiz algumas pesquisas e descobri que eles usam a $wp_queryvariável; no entanto, quando mudei minha variável de consulta para $wp_query, os links apareceram, mas, quando clicados, não fizeram nada.

Alguma idéia de onde estou errado?

Editar:

Para responder a algumas de suas perguntas, minha consulta gera com êxito as postagens que estou consultando, $ author_id já possui um valor que eu não incluí neste snippet de código. Da mesma forma, deixei de fora a saída real do conteúdo no loop while, porque essa parte não é o problema. O problema é que eu preciso paginar o conteúdo que já existe nesta única postagem.

O objetivo dessa funcionalidade era permitir que as postagens tivessem autores personalizados (fora do sistema Usuários interno) e o objetivo deste modelo é gerar todas as postagens para um determinado autor (que já está funcionando).


3
Um voto positivo para uma pergunta bem formatada, embora você não tenha descrito por que está fazendo isso, é uma publicação relacionada à caixa do autor atual?
Tom J Nowell

11
Eu realmente concordo com @TomJNowell. +1
Pieter Goosen

2
Independentes, mas não é necessário para ecoarthe_title()
Pieter Goosen

2
Está 'meta_value' => $author_idsendo preenchido a partir do menu suspenso mencionado? E ao selecionar cada autor pelo menu suspenso, as dez primeiras postagens são exibidas corretamente?
Stephen S.

11
Você garantiu que $author_query->have_posts()retorne truee que $author_queryrealmente contenha postagens?
Kaiser #

Respostas:


17

Você tem 2 problemas.

Primeiro problema

A linha

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

falhará, porque na exibição de postagem singular, quando o URL contém '/page/XX/', a variável WordPress define é 'page'e não 'paged'.

Você pode pensar em usar em 'page'vez de 'paged', mas isso também não funcionará, porque uma vez que a 'page'variável se destina a ser usada para postagem singular de várias páginas (separação de páginas usando <!--nextpage-->) e uma vez que a postagem não é de várias páginas, o WordPress redirecionará a solicitação para o URL sem '/page/XX/'.

É o que acontece quando você nomeia sua variável de consulta $wp_query.

A solução é impedir esse redirecionamento removendo a função responsável por ele, que está 'redirect_canonical'conectada a 'template_redirect':

Então, no seu functions.phpadd:

add_action( 'template_redirect', function() {
    if ( is_singular( 'authors' ) ) {
        global $wp_query;
        $page = ( int ) $wp_query->get( 'page' );
        if ( $page > 1 ) {
            // convert 'page' to 'paged'
            $wp_query->set( 'page', 1 );
            $wp_query->set( 'paged', $page );
        }
        // prevent redirect
        remove_action( 'template_redirect', 'redirect_canonical' );
    }
}, 0 ); // on priority 0 to remove 'redirect_canonical' added with priority 10

Agora, o WordPress não redirecionará mais e definirá corretamente a 'paged'consulta var.

Segundo problema

next_posts_link()e previous_posts_link()ambos marcam if ( ! is_single() )para exibir a paginação.

Agora, isso is_single()é verdade no seu caso, porque você está em uma única postagem do tipo 'autor', portanto essas funções não podem funcionar conforme o esperado.

Você tem 3 possibilidades:

  1. Use query_postspara substituir a consulta principal (realmente não recomendada)
  2. Use um modelo de página personalizado em vez de um tipo de postagem personalizado, porque is_single()é falso para páginas, e seu código funcionará lá.
  3. Escreva sua própria função de paginação e use essa

Esse é o código da solução número 3:

function my_pagination_link( $label = NULL, $dir = 'next', WP_Query $query = NULL ) {
    if ( is_null( $query ) ) {
        $query = $GLOBALS['wp_query'];
    }
    $max_page = ( int ) $query->max_num_pages;
    // only one page for the query, do nothing
    if ( $max_page <= 1 ) {
        return;
    }
    $paged = ( int ) $query->get( 'paged' );
    if ( empty( $paged ) ) {
        $paged = 1;
    }
    $target_page = $dir === 'next' ?  $paged + 1 : $paged - 1;
    // if 1st page requiring previous or last page requiring next, do nothing
    if ( $target_page < 1 || $target_page > $max_page ) {
        return;
    }
    if ( null === $label ) {
        $label = __( 'Next Page &raquo;' );
    }

    $label = preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label );
    printf( '<a href="%s">%s</a>', get_pagenum_link( $target_page ), esc_html( $label ) );
}

e use-o assim no single-authors.php:

my_pagination_link( 'Older Entries', 'next', $author_query );
my_pagination_link( 'Newer Entries', 'prev', $author_query );

Resposta muito detalhada, obrigado! Isso funciona para o lado em inglês do site, mas, no lado francês, os links de paginação não fazem nada, apenas atualizam a página. Estou usando o WPML.
Shane

11
@ Shane parece que o WPML executa algum filtro que impede o código de funcionar. Mas é um plugin tão grande e, portanto, não posso cavar milhares de linhas de código para entender onde está o conflito. Tente pedir suporte ao WPML.
gmazzap

@ Shane Os fóruns de suporte do WPML - e se acima funcionar para (o que eu assumo), marque-o como solução. O conflito WPML está fora do tópico / fora do escopo deste site.
Kaiser #

Resposta fantástica, principalmente porque me ajudou a resolver meu problema de paginação. Eu tenho feito uma tarefa semelhante e criei um segundo WP_Query para fazer o loop. Liguei, the_posts_paginationmas tive que tirar uma cópia do wp_query original, conforme descrito nesta pergunta: wordpress.stackexchange.com/questions/216821/…
Alexander Holsgrove

11
Você está correto @HongPong, corrigido, obrigado.
gmazzap

0

Com base em outra pergunta semelhante do WPSE "A paginação não está funcionando com os valores dos campos personalizados wp_query ", sugiro adicionar global $paged;ao início do seu arquivo de modelo:

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

11
Obrigado pela resposta! Infelizmente, isso não parece fazer nenhuma diferença. Os links de paginação não aparecem
Shane

11
Stephen, por que isso ajudaria? Sim, isso o traria do contexto global, mas até agora você não está fazendo nada com isso. Se você deseja substituir o global, use $GLOBALS['paged'] = get_query_var( 'paged' );. Caso contrário, basta usar o conteúdo global.
Kaiser

@ Shane Hmm, a página do modelo está sendo usada como uma página estática?
Stephen S.

Não, ele está sendo usado apenas como um único modelo de postagem para o tipo de postagem personalizada. Tentei alterar minha consulta de $author_querypara $wp_querye isso pareceu fazer a paginação aparecer, mas quando clico nela, a página é atualizada e na verdade não passa para a próxima página, mesmo que haja várias páginas. Atualizei minha resposta para refletir essas alterações.
Shane

11
A explicação do php.net não é tão ruim assim. Eu sugiro apenas brincando com globale $GLOBALS. Um pouco de var_dump(), algumas funções e você está bem. Para realmente entendê-lo com um pouco de tentativa / erro, você terá aprox. precisa de meia hora. Isso o ajudará a entender melhor as funções versus as classes e a abordagem OOP como um todo também. E isso vai claramente trazer mais perto de namespaces compreensão :)
kaiser
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.