Leí ayer la consulta No sabes de Nacin @ y me enviaron un poco por una madriguera de conejos. Antes de ayer, estaba usando (erróneamente) para todas mis necesidades de consulta. Ahora soy un poco más sabio sobre el uso , pero todavía tengo algunas áreas grises.query_posts()
WP_Query()
Lo que creo que sé con certeza:
Si estoy haciendo bucles adicionales en cualquier lugar de una página, en la barra lateral, en un pie de página, cualquier tipo de "publicaciones relacionadas", etc., quiero usar WP_Query()
. Puedo usar eso repetidamente en una sola página sin ningún daño. (¿derecho?).
Lo que no sé con certeza
- ¿Cuándo uso @ nacin's
pre_get_posts
vs.WP_Query()
? ¿Debo usarpre_get_posts
para todo ahora? - Cuando quiero modificar el bucle en una página de plantilla, digamos que quiero modificar una página de archivo de taxonomía, ¿elimino la
if have_posts : while have_posts : the_post
parte y escribo la míaWP_Query()
? ¿O modifico la salida usandopre_get_posts
mi archivo functions.php?
tl; dr
Las reglas de tl; dr que me gustaría sacar de esto son:
- Nunca
query_posts
más uso - Cuando ejecute múltiples consultas en una sola página, use
WP_Query()
- Al modificar un bucle, haga esto __________________.
Gracias por cualquier sabiduría
Terry
ps: He visto y leído: ¿ Cuándo deberías usar WP_Query vs query_posts () vs get_posts ()? Lo que agrega otra dimensión - get_posts
. Pero no trata pre_get_posts
en absoluto.
fuente
Respuestas:
Tienes razón al decir:
pre_get_posts
pre_get_posts
es un filtro, para alterar cualquier consulta. Se usa con mayor frecuencia para alterar solo la 'consulta principal':(También verificaría que
is_admin()
devuelva falso , aunque esto puede ser redundante). La consulta principal aparece en sus plantillas como:Si alguna vez siente la necesidad de editar este bucle, úselo
pre_get_posts
. es decir, si tiene la tentación de usarquery_posts()
, usepre_get_posts
en su lugar.WP_Query
La consulta principal es una instancia importante de a
WP_Query object
. WordPress lo usa para decidir qué plantilla usar, por ejemplo, y cualquier argumento pasado a la url (por ejemplo, paginación) se canaliza a esa instancia delWP_Query
objeto.Para los bucles secundarios (por ejemplo, en barras laterales o listas de 'publicaciones relacionadas'), querrá crear su propia instancia separada del
WP_Query
objeto. P.ejAviso
wp_reset_postdata();
: esto se debe a que el bucle secundario anulará la$post
variable global que identifica la 'publicación actual'. Esto esencialmente restablece eso a lo$post
que estamos.get_posts ()
Esto es esencialmente un contenedor para una instancia separada de un
WP_Query
objeto. Esto devuelve una matriz de objetos de publicación. Los métodos utilizados en el ciclo anterior ya no están disponibles para usted. Esto no es un 'Loop', simplemente una matriz de objetos de publicación.En respuesta a sus preguntas
pre_get_posts
para alterar su consulta principal. Use unWP_Query
objeto separado (método 2) para bucles secundarios en las páginas de la plantilla.pre_get_posts
.fuente
get_posts()
es más eficiente.get_posts()
para la consulta principal, es para consultas secundarias.Hay dos contextos diferentes para los bucles:
El problema
query_posts()
es que es un bucle secundario que intenta ser el principal y falla miserablemente. Por lo tanto, olvide que existe.Para modificar el bucle principal
query_posts()
pre_get_posts
filtro con$query->is_main_query()
chequerequest
filtro (un poco demasiado rugoso, por lo que lo anterior es mejor)Para ejecutar el bucle secundario
Use
new WP_Query
oget_posts()
que sean bastante intercambiables (este último es un envoltorio delgado para el anterior).Limpiar
Úselo
wp_reset_query()
si utilizóquery_posts()
o se metió con global$wp_query
directamente, por lo que casi nunca lo necesitará.Úselo
wp_reset_postdata()
si utilizóthe_post()
o sesetup_postdata()
metió con global$post
y necesita restaurar el estado inicial de las cosas relacionadas con la publicación.fuente
wp_reset_postdata()
Hay escenarios legítimos para usar
query_posts($query)
, por ejemplo:Desea mostrar una lista de publicaciones o publicaciones de tipo de publicación personalizada en una página (usando una plantilla de página)
Desea hacer que la paginación de esas publicaciones funcione
Ahora, ¿por qué querría mostrarlo en una página en lugar de usar una plantilla de archivo?
Es más intuitivo para un administrador (¿su cliente?): Pueden ver la página en 'Páginas'
Es mejor agregarlo a los menús (sin la página, tendrían que agregar la URL directamente)
Si desea mostrar contenido adicional (texto, miniatura de publicación o cualquier meta contenido personalizado) en la plantilla, puede obtenerlo fácilmente desde la página (y todo tiene más sentido para el cliente también). Vea si utilizó una plantilla de archivo, ya sea que necesita codificar el contenido adicional o utilizar, por ejemplo, opciones de tema / complemento (lo que lo hace menos intuitivo para el cliente)
Aquí hay un código de ejemplo simplificado (que estaría en la plantilla de su página, por ejemplo, page-page-of-posts.php):
Ahora, para ser perfectamente claros, podríamos evitar usar
query_posts()
aquí también y usarWP_Query
en su lugar, así:Pero, ¿por qué haríamos eso cuando tenemos una pequeña función tan agradable disponible?
fuente
Modifico la consulta de WordPress desde functions.php:
fuente
Solo para describir algunas mejoras en la respuesta aceptada, ya que WordPress evolucionó con el tiempo y algunas cosas son diferentes ahora (cinco años después):
En realidad es un gancho de acción. No es un filtro, y afectará cualquier consulta.
En realidad, esto tampoco es cierto. La función
have_posts
itera elglobal $wp_query
objeto que no está relacionado solo con la consulta principal.global $wp_query;
puede ser alterado con las consultas secundarias también.En realidad, hoy en día
WP_Query
es una clase, por lo que tenemos una instancia de una clase.Para concluir: en el momento @StephenHarris escribió muy probablemente todo esto era cierto, pero con el tiempo las cosas en WordPress han cambiado.
fuente
get_posts
devuelve una matriz de objetos de publicación, no unWP_Query
objeto, por lo que de hecho sigue siendo correcto. yWP_Query
siempre ha sido una clase, instancia de una clase = objeto.