16. The WP Functions Library (V). Las plantillas

Una vez hemos creado nuestras fichas en el back-end de WordPress, obviamente queremos después visualizarlas en el front-end. Para ello, vamos a crear unas plantillas, tanto para las taxonomías (por categorías) como para las fichas individuales.

 

NOTA PREVIA MUY IMPORTANTE: Me ha costado sudor y lágrimas (casi) encontrar la solución a un problema. Una vez realizadas las plantillas, que a continuación explicaré, no conseguía visualizarlas. Después de mucho buscar, he encontrado la solución en este artículo, ‘Qué hacer si la plantilla single de un custom post type no muestra el post’. La solución, como bien dice su autor, no es nada obvia, y se puede hacer de dos maneras: la primera, manualmente, en Ajustes > Enlaces permanentes, y clicamos en ‘Guardar cambios’, o bien mediante la función flush_rewrite_rules() en el archivo functions.php, después de crear el custom post type.

 

Empezamos. La jerarquía de las plantillas del theme

Para ver cómo funciona la jerarquía de las plantillas en WordPress acudimos nuevamente a nuestro querido Codex. Tengamos en cuenta, antes de todo, que la jerarquía de plantillas en WordPress funciona desde más específico a más genérico. Así pues:

Taxonomías

  1. taxonomy-{nombre_de_la_taxonomía}-{term}.php
  2. taxonomy-{nombre_de_la_taxonomía}.php
  3. taxonomy.php
  4. archive.php
  5. index

Custom Post Types

Para mostrar el archivo de los Custom Post Type:

  1. archive-{post_type}.php
  2. archive.php
  3. index.php

Para mostrar el artículo individual, se utiliza la jerarquía de artículo individual (single post):

  1. single-{post_type}-{slug}.php
  2. single-{post_type}.php
  3. single.php
  4. singular.php
  5. index.php

En nuestro caso, creo interesante que las páginas de taxonomías (categorías) se visualicen mediante la plantilla taxonomy-clasificacion.php, mientras que los artículos individuales lo hagan a través de single-stmtwpfl.php, ya que ambos especifican las denominaciones que hemos dado a ambos elementos, y quedan libres posteriores taxonomías y Custom Post Types que deseemos crear más adelante.

 

Las URLs de nuestra The WP Functions Library

En nuestro caso, la taxonomía se visualizará con la siguiente URL:

http://midominio.com/clasificacion/slug_clase_seleccionada/

Mientras que el Custom Post Type será:

http://midominio.com/stmtwpfl/slug_articulo_seleccionado/

 

¿Qué queremos mostrar?

Bien. En este caso queremos hacer algo que nos permita visualizar las taxonomías (categorías) de una forma estructurada, incluyendo los artículos (custom posts type) que contiene cada una de ellas, por un lado, y los artículos, con todos sus metadatos y archivos adjuntos para descargar. En este último caso crearemos un widget que contenga también el menú de las taxonomías en el lateral. En el caso de las taxonomías, eliminaremos la barra lateral.

 

Las funciones del Codex para trabajar con taxonomías

Primero, vamos a tratar las funciones de WordPress para el trabajo con taxonomías, ya que la primera plantilla que he ‘atacado’, ha sido precisamente esa, taxonomy-clasificacion.php.

Las diferentes categorías y subcategorías de una taxonomía, en WordPress se denominan ‘term’. Esto puede sonar a lógico, pero lo entendí una vez estuve metido profundamente en el desarrollo de la plantilla, al comprobar que todas las funciones que estaba utilizando contenían esa palabra. Son cosas que pasan cuando uno es un principiante.

Vamos a ver algunas de las funciones que nos aporta WordPress para el trabajo con categorías y subcategorías de una taxonomía:

  • get_term( $term, $taxonomy, $output, $filter )

Proporciona todos los datos de un term que le hayamos solicitado por su ID.

Parámetros:

$term. Entero u objeto requerido. Si es un entero, lo entiende como su id. Si es un objeto, aplicará filtros y devuelve $term. Por defecto, none.

$taxonomy. La taxonomía a la que pertenece el term. NOTA: Se entiende que un nombre de categoría o subcategoría puede repetirse en diferentes taxonomías; por tanto, debemos especificar a cuál de ellas.

$output. Cadena opcional con valor por defecto OBJECT. Puede ser OBJECT (objeto), ARRAY_A (matriz asociativa) o ARRAY_N (matriz numérica). Indica la forma en que devuelve los datos del term.

$filter. Cadena opcional con valor por defecto ‘raw’, con la que le indicamos un filtro a aplicar.

Los campos retornados son:

  • term_id (entero)
  • name
  • slug
  • term_group (entero)
  • term_taxonomy_id (entero)
  • taxonomy
  • description
  • parent (entero)
  • count (entero)

NOTA: Observa que esta función devuelve los campos numéricos como enteros y no como cadenas. Esta es la diferencia con la función get_terms(), que veremos a continuación.

¿Cómo se utiliza? Fácil. Un ejemplo:

Este ejemplo mostrará por pantalla ‘Fichas’.

 

  • get_terms( $args = array() )

Devuelve los terms de una taxonomía o lista de taxonomías, según los $args pasados en la matriz.

Parámetros a pasar en la matriz:

  • ‘taxonomy’. Cadena o matriz. Nombre de taxonomía o matriz de taxonomías.
  • ‘orderby’. Cadena. Campo(s) por el(los) que ordenar los terms. Acepta ‘name’, ‘slug’, ‘term_group’, ‘term_id’, ‘id’, ‘description’, ‘count’, ‘include’, ‘meta_value’, ‘meta_value_num’, o ‘none’. Por defecto, ‘name’.
  • ‘order’. Cadena. ‘ASC’ (orden ascendente) o ‘DESC’ (orden descendente). Por defecto, ‘ASC’.
  • ‘hide_empty’. Lógico o entero. Indica si muestra los terms que no tienen posts. Los oculta con 1 o true, y los muestra con 0 o false. Por defecto, 1/true.
  • ‘include’. Matriz o cadena separada por comas con los id de los term a incluir.
  • ‘exclude’. Matriz o cadena separada por comas con los id de los term a excluir. Si ‘include’ no contiene nada, ‘exclude’ es ignorado.
  • ‘exclude_tree’. Matriz o cadena separada por comas de los id de los term a excluir con sus term descendientes. Si ‘include’ no contiene nada, ‘exclude_tree’ se ignora.
  • ‘number’. Entero o cadena con el número máximo de terms a devolver. El valor 0 o all, por defecto, los muestra todos.
  • ‘offset’. Entero que indica la cantidad de terminos que muestra.
  • ‘fields’. Cadena. Campos que devolverá la consulta. Acepta ‘all’, ‘ids’, ‘id=>parent’, ‘names’, ‘count’, ‘id=>slug’. Por defecto, ‘all’ (todos los campos).
  • ‘name’. Cadena o matriz con el nombre o nombres de los term de los cuales devolver resultados.
  • ‘slug’. Lo mismo con el slug.
  • ‘hierarchical’. Lógico que indica si incluir o no los term que tienen descendientes sin posts. Por defecto, true.
  • ‘search’. Cadena con el criterio para buscar los terms. Será con formato SQL con comodines antes y después.
  • ‘name_like’. Cadena a la que parecerse los nombes de term.
  • ‘description_like’. Cadena a la que parecerse las descripciones de term.
  • ‘pad_counts’. Lógico. Si añadir las cantidades de posts de los descendientes en el padre. Por defecto, false.
  • ‘get’. Cadena. Si devolver los terms independientemente de sus antecesores o si los terms están vacíos. Acepta ‘all’ o ‘empty’ (desactivado).
  • ‘child_of’. Entero. Id del que recuperar los terms descendientes. Por defecto, 0.
  • ‘parent’. Entero o cadena con el Id del padre, para devolver los hijos directos.
  • ‘childless’. Lógico. True limita los resultados a terms que no tienen hijos.
  • ‘cache_domain’. Cadena.
  • ‘update_term_meta_cache’
  • ‘meta_query’
  • ‘meta_key’
  • ‘meta_value’

 

  • get_term_by( $field, $value, $taxonomy, $output, $filter )

Devuelve los datos, de la base de datos, de un term por el campo.

Parámetros:

  • $field. Cadena requerida. Puede ser ‘id’, ‘slug’, ‘name’ o ‘term_taxonomy_id’. Por defecto es ‘id’.
  • $value. Cadena o entero requerido. Busca por este valor del campo del term.
  • $taxonomy. Cadena opcional. Nombre de la taxonomía: category, post_tag, link_category, nav_menu o nombre de la taxonomía personal. Por defecto, vacía.
  • $output. Cadena opcional. Puede ser OBJECT, ARRAY_A o ARRAY_N. Por defecto, OBJECT.
  • $filter. Filtro a aplicar a la función.

Esta función retorna los mismos campos que get_term, pero los números los devuelve en formato cadena.

 

  • $get_term_children( $term, $taxonomy )

Reúne todos los descendientes de un term en una única matriz.

Esta función es recursiva y une todos los descendientes y descendientes de descendientes (y así todos los niveles) de un término (term) dado.

Parámetros:

  • $term
  • $taxonomy

NOTA: Esta función, en principio, tiene utilidad. En mi caso la he desestimado, pues no muestra niveles padre/hijo.

 

  • get_term_link( $term, $taxonomy )

Devuelve el link HTML al archivo del término taxonómico.

Parámetros:

  • $term
  • $taxonomy

 

  • get_the_term_list( $id, $taxonomy, $before, $sep, $after )

Devuelve una cadena HTML de términos taxonómicos asociados con un post y taxonomía dados. Los términos son vinculados a sus respectivas páginas de taxonomías.

Parámetros:

  • $id. Entero requerido. El id del post.
  • $taxonomy. Cadena requerida. El nombre de la taxonomía.
  • $before. Cadena que se verá antes del resultado.
  • $sep. Cadena de separación entre resultados.
  • $after. Cadena que se verá después del resultado.

 

El archivo taxonomy-clasificacion.php

El archivo final queda así:

Veamos las diferentes partes:

  • Líneas 4-10: Cabecera PHP.
  • Línea 12: Llamada a header.php.
  • Línea 14: Creación de la sección id=”main”.
  • Líneas 17-46: Capa id=”taxonomías” que genera el título de la clase actual y el listado de las subclases.
  • Líneas 48-76: Loop modificado.
  • Línea 77: Fin sección id=”main”.
  • Líneas 79 y 80: Llamadas a sidebar.phpfooter.php.

 

Capa id=”taxonomías”

Aquí tenemos dos partes: la cabecera de la taxonomía actual y el listado de las subclases.

Aquí nos aparece una nueva función, get_query_var(). Con ella, lo que hacemos es buscar el término (term) y la taxonomía (taxonomy) que nos han enviado a esta página. Es decir, nos devuelve la variable de búsqueda pública de la clase WP_Query en el objeto global $wp_query.

Luego, como get_term_by() nos devuelve un objeto que metemos en $termino, referenciamos a sus campos mediante $termino->name y $termino->description.

La tabla id=”tabla_taxonomias” la generamos con el siguiente código:

Primero establecemos la variable $nivel a 0. Esta variable nos indicará el nivel en que estamos. A continuación creamos una función iterativa, tipo de función que me encanta, ya que lo que hace es llamarse a si misma para recorrer una estructura jerárquica (o de árbol).

La función iterativa( $padre, $nivel) busca los términos hijos de un término padre (‘parent’ => $padre) y, por cada uno, lo muestra en la tabla, con su nombre, enlace y cantidad de posts asociados, y a continuación, busca si tiene hijos llamando a la misma función iterativa(), con la variable $padre igual al id del elemento y un nivel superior ($nivel++).

El nivel lo mostramos mediante la función str_repeat( “–“, $nivel-1).

 

El ‘loop’ modificado

Lo llamamos un ‘loop’ modificado, porque, lo que hacemos en realidad, es seleccionar el ‘loop’ con parámetros de consulta personalizados.

Básicamente, le decimos que busque custom post types del tipo ‘stmtwpfl’, que pertenezcan a la taxonomía ‘clasificacion’ y al término $termino->name, que es en el que estamos.

Con esto arrancamos el loop, como ya vimos al inicio de la serie ‘Temas WP’. Primero, mostramos el título enlazado al permalink. Luego, mostramos la clase taxonómica a la que pertenece con la función get_the_term_list().

Ahora, lo que queremos es que nos muestre el contenido del artículo sólo en el caso de que el artículo pertenezca al término que estamos viendo.

La función get_the_terms() nos genera una matriz de términos, en el que el válido será el último. Luego lo que hacemos es recorrerla entera y, si el id del último coincide con el de la página que estamos visualizando, nos muestra el resumen.

 

Visualizar el Custom Post Type con sus Custom Fields

Si creamos el archivo single-stmtwpfl.php podremos visualizar los diferentes custom post type de nuestras fichas. Veamos lo básico:

Con esto, veremos el contenido de la ficha sin los campos personales. Para visualizar éstos, lo podemos hacer, incluyendo la función the_meta() dentro del loop, por ejemplo, después del contenido:

Con esto, tendremos el siguiente resultado:

metadatos1

Ahora bien, podemos visualizarlos de una manera más elegante, mediante la función

get_post_meta( $post_id, $key, $single )

Devuelve un campo personalizado de un artículo.

Parámetros:

  • $post_id. Entero requerido el id del post.
  • $key. Clave del campo a devolver. Por defecto, los devuelve todos.
  • $single. Si devuelve un único valor. Por defecto, false.

Así, en este caso lo vamos a hacer de esta manera:

Y, el resultado, ahora, será:

metadatos2

Con esto, en un principio, ya habríamos acabado (¡uf!, menos mal). Ahora bien, ¿cómo seguimos viendo otras fichas?¿Dando al botón volver atrás?

No. Convendría crear otra vez nuestra tabla índice de fichas. Para ello, vamos a copiar en este archivo, después de la finalización del ‘loop’ con la función endwhile, el snippet (fragmento de código) que he empleado en la página de taxonomías:

En este caso, como no tenemos un term_id de inicio, hemos de buscar el de aquel término que no tenga padre. Para eso, buscamos un término con ‘parent’ => 0 y lo ponemos en $inicio.

Con su id, ejecutamos la función

iterativa( $inicio->term_id, $nivel )

Quedando, finalmente, este resultado:

metadatos3

 

Conclusiones

En este artículo hemos visto cómo visualizar en el front-end de WordPress las taxonomías, los Custom Posts Type y los Custom Fields que habíamos creado y rellenado en el back-end.

Sin embargo, recordemos que estas plantillas se encuentran en el directorio de plugins, por pertenecer a uno, y no en el directorio del tema, ya que, al pertenecer a un plugin permanecerán en él aunque el usuario cambie el tema, sin perder lo que hemos creado.

Por tanto, en el próximo artículo veremos cómo indicar al núcleo de WordPress dónde están las plantillas, para que acuda a ellas sea cual sea el tema que se esté utilizando.

Obviamente, a estas alturas, dejo para cada uno la disposición de los elementos y los estilos con los que se visualizarán, ya que bastante extenso me está quedando ya este artículo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *