Wordpress Recomienda
Alterar el Query en un tema de WordPress es tarea de cada día. Cada proyecto tiene sus propias necesidades, y si lo planeamos bien, acabaremos con muchos queries personalizados a través de nuestros proyectos.

Sin embargo, aveces, un cliente nos pide que modifiquemos algo que ya existe, que trabajemos sobre el trabajo de otros programadores, o necesita nuevas funcionalidades.

La semana pasada, un antiguo cliente nos pidió un cambio importante en su web.

El requerimiento

Necesitamos que todos los eventos de tipo académico se ordenen por la fecha del evento, no por la publicación del evento, y que esto solo suceda para aquellos eventos que no son del subtipo Formación, ya que estos son permanentes.

Queda bastante claro no?

El problema

El tema no seguía las mejores prácticas de desarrollo, y todos los Custom Post Types utilizaban archive.php para mostrarse, aunque tenían vistas y estilos distintos. Así que tenemos un archive.php lleno de condicionales que llaman distintos templates según la ocasión.

La Solución

En vez de complicar más aún un template ya tugurizado de condicionales, sobre escrituras y notas a desarrolladores futuros, decidí optar por una práctica más limpia, e interceptar el query de wordpress desde functions.php

Utilizando el pre_get_posts hook, modificaremos el query natural para que cumpla los siguientes parámetros

Nuevo Query
  • Si estamos alterando el main query y no uno personalizado
  • Si se está requiriendo un archivo
  • Si este query es a un taxonomy del tipo “categories_academicos”
  • Si este query NO es del tipo “categories_academicos” subtipo “formaciones
  • Si este query no se realiza en el panel de administración
  • Elige solo los posts cuyo meta_field start_date tenga una fecha mayor o igual a hoy.

En este proyecto estamos usando Advanced Custom Fields para manejar los meta_fields. El campo start_date es un campo de tipo DatePicker y para facilitar el query en la BBDD he optado por guardar los datos en el formato Ymd, de manera que es fácil convertir este valor a NUMERIC y compararlo.



function order_filter_academicos( $query ) {
    // definimos condicones para sobreescribir el query
    if ( 
    	$query->is_archive() && 
    	$query->is_main_query() && 
    	$query->is_tax("categories_academicos") &&
    	!$query->is_tax("categories_academicos", "formaciones") &&
    	!is_admin() 
    ) {
        // construimos el meta query array
        $today = date('Ymd');
        
        $meta_query = array(	
    		"key" => "start_date",
    		"value" => $today,
    		"compare" => ">=",
    		"type" => "NUMERIC"
        );

        // sobre escribimos el main query seteando los valores que deseamos 
        $query->set( 'meta_key', 'start_date' );
        $query->set("meta_query", $meta_query);

        $query->set("orderby", "meta_value");
        $query->set("order", "ASC");        
    }
    

}
add_action( 'pre_get_posts', 'order_filter_academicos' );

y listo!

Trabajar queries de esta manera tiene muchas ventajas. Personalmente me gusta por qué el código está más ordenado, y permite no complicar los templates con funcionalidades que podrían estar fuera como configuraciones generales.
La próxima versión de Oniros incluirá buenas prácticas para este tipo de situaciones.