miércoles, 10 de febrero de 2016

Usando pre_get_posts en vez de query_posts en WordPress

Como ya sabemos hay varias manera de obtener los posts en WordPress:
Vamos a centrarnos en el primero, en el muy utilizado query_posts. Vemos que el codex de WordPress ya nos avisa que algo pasa con query_posts():
“Es preferible utilizar ‘pre_get_posts’ alterando el query principal usando is_main_query”
¿Por qué nos dice esto? Vamos a ver primero cómo funciona query_posts() y entenderemos enseguida el problema.

Cómo funciona query_posts()


Al usar query_posts() estamos diciéndole a WordPress que el trabajo que ha hecho recolectando toda la información del post no vale. Le cambiamos las normas del juego después de haber jugado y le decimos que vuelva a recolectar todos los datos pero en base a unos nuevos criterios que le damos.
Otra vez a recolectar todos los datos, y así cada vez que alguien nos visita (a no ser que hayáis tomado la precaución de cachear los datos con transients o similares). La incidencia en webs con poco tráfico puede ser irrelevante, pero en webs con mucho tráfico sí deberíamos tenerlo en cuenta.
Vamos a verlo en un ejemplo. Supongamos que tenemos un archivo de taxonomías para el que queremos que no salga la categoría 13 y que además nos muestre 8 resultados por página. Si hiciéramos antes del loop:
¿Qué sucedería? WordPress llegaría con todos los datos obtenidos de la base de datos, pero le decimos: vuelve por donde has venido, pero esta vez sin entradas de la categoría 13 y con 8 resultados por página.
¿Cómo le daríamos las instrucciones pertinentes a WordPress antes de que vaya a recoger los datos la primera vez? Con pre_get_posts.

Cómo funciona pre_get_posts

pre_get_posts nos da acceso al objeto $query por referencia (no necesitas declarar globales ni devolver un valor), y se usa de la manera siguiente:
Donde “nombre_funcion” es el nombre de la función que se va a llamar. Esto deberíamos incluirlo en el archivo functions.php de nuestro tema o en un plugin. WordPress necesita crear el query antes de nada para saber qué plantilla (template) va a cargar, por lo que si pones pre_get_posts en una plantilla, como por ejemplo archive.php, será ya demasiado tarde.
Vamos a seguir con el ejemplo anterior. En nuestro archivo functions.php escribiríamos:
Como veis con $query->set establecemos las nuevas condiciones (primero que no incluya la categoría 13 y luego que nos de 8 resultados). Pero, ¿para qué son los condicionales?
Usando pre_get_posts podemos estar afectando más de lo previsto, por eso nos cubrimos las espaldas:
– Este filtro afecta a los queries de las pantallas del administrador. Tenemos por lo tanto que asegurarnos de que nuestra modificación no afecta al administrador de WordPress. De ahí el primer condicional.
– A continuación nos aseguramos de que estamos afectando sólo al query principal, y no a otros queries como los del menú o los de ciertos widgets. Esto lo hacemos comprobando que $query->is_main_query().
– Por último comprobamos que las condiciones son adecuadas para nuestra modificación. Por ejemplo, si quieres que sólo ocurra en la home, el condicional sería $query->is_home(). En nuestro caso queremos asegurarnos de que estamos en la página de archivo de la taxonomía para aplicar el filtro.
Mas ejemplos:
Por ejemplo, si tenemos establecido un número determinado de artículos por página y queremos cambiarlo para ciertas categorías:
Otro ejemplo, queremos que para cierta categoría salgan un cierto número de resultados pero sólo aquellos cuyo valor de un meta value cumpla alguna condición:


No hay comentarios.:

Publicar un comentario