Eu li o @ nacin's Você não conhece a Consulta ontem e foi enviado um pouco como uma toca de coelho. Antes de ontem, eu estava (erroneamente) usando query_posts()
para todas as minhas necessidades de consulta. Agora estou um pouco mais sábio sobre o uso WP_Query()
, mas ainda tenho algumas áreas cinzentas.
O que acho que tenho certeza:
Se eu estiver criando loops adicionais em qualquer lugar da página - na barra lateral, no rodapé, em qualquer tipo de "postagens relacionadas" etc. - eu quero usar WP_Query()
. Eu posso usar isso repetidamente em uma única página sem nenhum dano. (direito?).
O que não sei ao certo
- Quando eu uso @ de nacin
pre_get_posts
vs.WP_Query()
? Devo usarpre_get_posts
para tudo agora? - Quando desejo modificar o loop em uma página de modelo - digamos que desejo modificar uma página de arquivo de taxonomia - removo a
if have_posts : while have_posts : the_post
peça e escrevo a minhaWP_Query()
? Ou modifico a saída usandopre_get_posts
no meu arquivo functions.php?
tl; dr
As regras tl; dr que eu gostaria de extrair disso são:
- Nunca use
query_posts
mais - Ao executar várias consultas em uma única página, use
WP_Query()
- Ao modificar um loop, faça isso __________________.
Obrigado por qualquer sabedoria
Terry
ps: Eu vi e li: Quando você deve usar WP_Query vs query_posts () vs get_posts ()? O que adiciona outra dimensão - get_posts
. Mas não lida com pre_get_posts
nada.
fonte
Respostas:
Você está certo em dizer:
pre_get_posts
pre_get_posts
é um filtro, para alterar qualquer consulta. Geralmente é usado para alterar apenas a 'consulta principal':(Eu também verificaria se
is_admin()
retornos falsos - embora isso possa ser redundante.). A consulta principal aparece nos seus modelos como:Se você sentir a necessidade de editar esse loop, use
pre_get_posts
. Se você estiver tentado a usar,query_posts()
use-opre_get_posts
.WP_Query
A consulta principal é uma instância importante de a
WP_Query object
. O WordPress o utiliza para decidir qual modelo usar, por exemplo, e quaisquer argumentos passados para o URL (por exemplo, paginação) são todos canalizados para a instância doWP_Query
objeto.Para loops secundários (por exemplo, em barras laterais ou listas de "postagens relacionadas"), você deseja criar sua própria instância separada do
WP_Query
objeto. Por exemploObserve
wp_reset_postdata();
- isso ocorre porque o loop secundário substituirá a$post
variável global que identifica a 'postagem atual'. Isso redefine essencialmente o$post
que estamos fazendo.get_posts ()
Este é essencialmente um invólucro para uma instância separada de um
WP_Query
objeto. Isso retorna uma matriz de objetos de postagem. Os métodos usados no loop acima não estão mais disponíveis para você. Este não é um 'Loop', simplesmente uma matriz de objeto de postagem.Em resposta às suas perguntas
pre_get_posts
para alterar sua consulta principal. Use umWP_Query
objeto separado (método 2) para loops secundários nas páginas do modelo.pre_get_posts
.fonte
get_posts()
é mais eficiente.get_posts()
para a consulta principal - é para consultas secundárias.Existem dois contextos diferentes para loops:
O problema
query_posts()
é que é o loop secundário que tenta ser o principal e falha miseravelmente. Assim esqueça que existe.Para modificar o loop principal
query_posts()
pre_get_posts
filtro com$query->is_main_query()
chequerequest
filtro alternadamente (um pouco áspero demais, acima é melhor)Para executar um loop secundário
Use
new WP_Query
ouget_posts()
que são praticamente intercambiáveis (este é um invólucro fino para o anterior).Limpar
Use
wp_reset_query()
se você usouquery_posts()
ou mexeu$wp_query
diretamente com o global - então quase nunca precisará.Use
wp_reset_postdata()
se você usouthe_post()
ousetup_postdata()
mexeu com o global$post
e precisa restaurar o estado inicial de itens pós-relacionados.fonte
wp_reset_postdata()
Existem cenários legítimos para usar
query_posts($query)
, por exemplo:Você deseja exibir uma lista de postagens ou postagens do tipo postagem personalizada em uma página (usando um modelo de página)
Você deseja que a paginação dessas postagens funcione
Agora, por que você deseja exibi-lo em uma página em vez de usar um modelo de arquivo morto?
É mais intuitivo para um administrador (seu cliente?) - eles podem ver a página nas "Páginas"
É melhor adicioná-lo aos menus (sem a página, eles teriam que adicionar o URL diretamente)
Se você deseja exibir conteúdo adicional (texto, miniatura da postagem ou qualquer meta-conteúdo personalizado) no modelo, é possível obtê-lo facilmente da página (e tudo faz mais sentido para o cliente também). Veja se você usou um modelo de arquivo, precisará codificar o conteúdo adicional ou usar, por exemplo, opções de tema / plug-in (o que o torna menos intuitivo para o cliente)
Aqui está um código de exemplo simplificado (que estaria no seu modelo de página - por exemplo, página-página-de-posts.php):
Agora, para ser perfeitamente claro, poderíamos evitar usar
query_posts()
aqui também e usá-loWP_Query
- assim:Mas, por que faríamos isso quando temos uma função tão agradável disponível para ela?
fonte
Modifico a consulta do WordPress a partir de functions.php:
fonte
Apenas para descrever algumas melhorias na resposta aceita, uma vez que o WordPress evoluiu ao longo do tempo e algumas coisas são diferentes agora (cinco anos depois):
Na verdade é um gancho de ação. Não é um filtro e afetará qualquer consulta.
Na verdade, isso também não é verdade. A função
have_posts
itera oglobal $wp_query
objeto que não está relacionado apenas à consulta principal.global $wp_query;
também pode ser alterado com as consultas secundárias.Hoje em dia
WP_Query
é uma classe, então temos uma instância de uma classe.Para concluir: Na época, o @StephenHarris escreveu provavelmente tudo isso era verdade, mas com o tempo as coisas no WordPress foram alteradas.
fonte
get_posts
retorna uma matriz de objetos de postagem, não umWP_Query
objeto, de modo que ainda está correto. eWP_Query
sempre foi uma classe, instância de um class = object.