Mejoras en la legibilidad de WP_Query (para mantenimiento)
Trabajar con WP_Query, especialmente cuando está haciendo un trabajo personalizado fuera del habitual "obtener algunas publicaciones y mostrarlas en una plantilla", puede ser poderoso. Esto es especialmente cierto para algunos de los argumentos avanzados (como usar WP_Meta_Query, por ejemplo) .
También es bueno que la configuración del proceso tenga una forma estándar de hacer las cosas. A saber:
- Definir los argumentos,
- Instanciar WP_Query,
- Compruebe si hay publicaciones,
- Bucle a través de ellos,
- Terminarlos.
Pero si llega a donde está haciendo un trabajo avanzado, como trabajar con un tipo de publicación personalizada de una solución de terceros, tener que descargar medios, determinar si existe algo antes de trabajar con él, entonces puede ser un un poco más complicado para trabajar, ¿no?
Descubrí que, como con cualquier cosa en la programación, dividirlo en módulos mucho más legibles (o funciones o piezas o como quiera llamarlos) puede hacer que sea mucho más fácil trabajar con ellos.
Así que aquí hay una forma en que trabajo para mejorar la legibilidad de WP_Query en una variedad de cosas que he hecho últimamente.
Mejoras en la legibilidad de WP_Query
Antes de analizar cualquier ejemplo, vale la pena señalar que hay algunas cosas que la forma en que WP_Query está configurado que no podemos hacer.
Por ejemplo, una vez que se crea una instancia de la consulta, es posible que no podamos hacer cosas mucho más avanzadas con ella (es decir, configurar cualquier prueba unitaria que no requiera el núcleo de WordPress va a ser imposible).
Esta es la cara de alguien que no puede seguir tu código.
Dicho esto, aquí hay un ejemplo de cómo puede verse cuando comienza y luego cómo se puede refactorizar para tener funciones más pequeñas, cada una de las cuales es más intencional que un método largo.
Un ejemplo
Para esta publicación, digamos que necesito consultar la base de datos para todas las publicaciones y publicaciones publicadas y quiero ordenarlas por ID.
A continuación, quiero determinar si alguna herramienta de terceros le asignó algunos metadatos que corresponden a una plantilla que luego puedo asignar mediante programación dado un tema que tengo.
Quizás la versión inicial del código podría verse así :
<?php
// Assume this is defined within the context of a class.
const MAPPING = [
'employers' => 'page-past-word.php',
'biography' => 'page-biography.php',
'accomplishments' => 'page-csv.php',
];
/* Snip the rest of the class for brevity */
public function map_templates() {
$args = [
'post_type' => array( 'post', 'page' ),
'post_status' => 'publish',
'orderby' => 'ID',
'order' => 'ASC',
'posts_per_page' => -1,
];
$template_query = new WP_Query( $args );
if ($template_query->have_posts()) {
while ($template_query->have_posts()) {
$template_query->the_post();
$template_id = get_post_meta( $post_id, 'third_party_template_id', true );
if ('' === $template_id) {
continue;
}
// The third-party's template post name can be used to map our custom template.
$template_info = get_post( $template_id );
$template_name = $template_info->post_name;
if (isset( self::MAPPING[ $template_name ])) {
$template_file = self::MAPPING[ $template_name ];
update_post_meta( $post_id, '_wp_page_template', $template_file );
}
}
}
}
Eso es mucho código para hacer bastante trabajo para una función. Como mínimo, establece todo lo que debe suceder, ¿no es así?
Antes de seguir leyendo, tenga en cuenta que la matriz de mapeo es solo un ejemplo, pero las claves representan la clave meta para mapearlo, y eso nos ayuda a mapear la definición del valor _wp_page_template cuando llega el momento de mapearlo a los archivos de plantilla de WordPress reales.
Entonces, ¿cómo se puede descomponer esto?
1 Patea todo el asunto
Lo primero que queremos hacer es crear una función que ponga todo en movimiento. Hay algunas maneras que puede elegir para hacer esto.
Así es como he optado por hacerlo :
<?php
public function map_page_templates() {
$posts = $this->load_posts_and_pages();
if ($posts->have_posts()) {
$this->assign_templates( $posts );
}
}
En pocas palabras, usará algunas funciones auxiliares, todas las cuales documentaré a continuación, y luego asignará las plantillas que tengamos en la matriz de mapeo definida anteriormente.
2 Cargar publicaciones y páginas
Naturalmente, lo primero que queremos hacer es configurar una función para llamar que devolverá los resultados de la consulta:
<?php
private function load_posts_and_pages() {
$args = [
'post_type' => array( 'post', 'page' ),
'post_status' => 'publish',
'orderby' => 'ID',
'order' => 'ASC',
'posts_per_page' => -1,
];
$posts = new WP_Query( $args );
return $posts;
}
Esto devuelve los resultados de la consulta. De esta manera, podemos determinar si necesitamos hacer algún trabajo adicional que decimos en esencia en el paso anterior:
<?php
public function map_page_templates() {
$posts = $this->load_posts_and_pages();
if ($posts->have_posts()) {
$this->assign_templates( $posts );
}
}
Si no, entonces hemos terminado. De lo contrario, obviamente, seguimos adelante.
3 Recuperar el ID de la plantilla de terceros
A continuación, la idea de asignar plantillas, como se muestra en el código anterior, parece bastante simple, pero hay algunas cosas que debemos hacer primero:
- iterar a través de las publicaciones,
- tome la identificación de terceros de la plantilla,
- toma el nombre de la plantilla de terceros,
- asigne la plantilla de la constante de mapeo definida anteriormente en la clase.
La iteración inicial de la función puede verse así :
<?php
private function assign_templates( WP_Query $posts) {
while ($posts->have_posts()) {
$posts->the_post();
$template_id = $this->get_template_id( get_the_ID() );
if ('' === $template_id) {
continue;
}
$template_name = $this->get_template_name( $template_id );
if (null === $template_name) {
continue;
}
$this->assign_template( get_the_ID(), $template_name );
}
wp_reset_postdata();
}
Pero como puede ver, todavía hay funciones auxiliares que necesitan definiciones. Cosas como la capacidad de obtener la ID de la plantilla, el nombre de la plantilla y, en última instancia, asignar la plantilla.
Tenga en cuenta, sin embargo, que si alguna de las funciones auxiliares no devuelve un valor útil, entonces continuamos con el bucle. Esto es necesario aunque solo sea para asegurarnos de que no estamos tratando de mapear plantillas que no existen (pero creo que también hace que sea un poco más fácil de leer).
4 Encuentre el archivo al que se asigna la ID de plantilla
A continuación, se puede usar una pequeña función para ver el ID de la plantilla de terceros y determinar si podemos asignar este valor a las páginas que existen en nuestra base de datos.
<?php
private function get_template_id( $post_id) {
$template_id = get_post_meta( $post_id, 'third_party_template_id', true );
return $template_id;
}
Si no puede, entonces podemos devolver una cadena vacía y luego hacer que la función que invocó este cheque en particular verifique si vale la pena continuar con el ciclo que hemos definido.
5 Tome el nombre de la plantilla
Suponiendo que tenemos una ID de publicación válida, ahora debemos recuperar el nombre de la plantilla de la matriz de mapeo definida anteriormente en la publicación:
<?php
private function get_template_name( $template_id) {
$template_info = get_post( $template_id );
$template_name = $template_info->post_name;
if (isset( self::MAPPING[ $template_name ])) {
return $template_name;
} else {
return null;
}
}
Aquí está la cuestión: o bien devolveremos el nombre de la plantilla, o bien devolveremos un valor nulo. Nuevamente, esto es para que podamos determinar si necesitamos continuar con el ciclo de asignación de plantillas o no.
6 Asigne la plantilla
Finalmente, podemos obtener la ID de la plantilla proporcionada por el tercero y usarla para asignarla al archivo que hemos incluido con nuestro trabajo como se describe anteriormente en la publicación:
<?php
private function assign_template( $post_id, $template_name) {
$template_file = self::MAPPING[ $template_name ];
update_post_meta( $post_id, '_wp_page_template', $template_file );
}
Y así es en última instancia cómo puede crear código y funciones mucho más pequeños, más fáciles de leer y más fáciles de usar cuando se trabaja con consultas un poco más complicadas.
Y por lo tanto, mejoras de legibilidad
Para aquellos acostumbrados a escribir, leer métodos largos o hacer las cosas de la forma en que muchos de los tutoriales en la web muestran cómo hacer las cosas en WordPress, esto puede parecer un montón de código sin sentido.
Pero considera esto:
- Los métodos más largos son más difíciles de leer,
- Pueden ser más difíciles de depurar,
- Y no descomponen el problema en partes más manejables.
Claro, me encantaría dividir esto en más clases con sus responsabilidades, y creo que se puede hacer, pero dada la naturaleza de WP_Query, requeriría un poco más de trabajo.
Así que he tratado de encontrar tantos puntos medios como sea posible.
Si está trabajando con usos incluso un poco más avanzados de WP_Query, le recomiendo al menos considerar dividirlo en partes más pequeñas.
Esto ayuda a cuidar la legibilidad, potencialmente cualquier capacidad de mantenimiento, y a escribir un código más limpio en lugar de un método largo con demasiados condicionales y dependencia de una variedad de otros datos.