WordPress | 23 de diciembre de 2014

Usar plantillas de página en custom post types de WordPress

Sigo avanzando en el rediseño de mi sitio y me he encontrado con un nuevo desafío: la necesidad de usar plantillas de página en un custom post type. A primera vista parece algo sencillo, pero me sorprendí al notar que WordPress no soporta esta característica de manera nativa.

Déjame darte algo de contexto.

¿Qué es una plantilla de página?

Cuando estás creando una página en WordPress, hay una sección («meta box«) al lado derecho llamada «Atributos de página«. Desde allí puedes seleccionar cual es la página superior, cuál es el orden de esta página y cuál es la plantilla de página que quieres aplicar.

atributos de pagina

En el ejemplo anterior puedes ver las plantillas de página que tengo en mi sitio hoy día y, dependiendo de cual seleccione para cada página, el diseño será diferente. Esta página, por ejemplo, usa la plantilla predeterminada, esta otra usa la plantilla AMK Directo y esta otra página usa la plantilla Curso Temas WordPress.

En la práctica, lo que ocurre al seleccionar diferentes plantillas de página, es que le damos a WordPress la orden de cargar uno u otro archivo desde nuestro theme para aplicar el HTML y cargar el contenido de la página. Cuando usamos la plantilla predeterminada le estamos indicando que cargue el archivo page.php, que es lo estándar de acuerdo a la jerarquía de archivos de plantilla, pero cuando usamos una plantilla especial, en mi caso «AMK Directo», estoy cargando la plantilla template-amk-directo.php desde mi tema.

El uso de las plantillas de página puede ayudarnos a crear páginas especiales para ofrecer nuestros productos (landing pages) o, recurriendo a su uso más básico, podemos aplicar simples cambios como el mostrar o no mostrar el sidebar.

La forma más fácil de crear un page template es duplicando el archivo page.php de tu tema actual, cambiar su nombre por lo que tu quieras (yo habitualmente antepongo la palabra template para darle contexto) y agregar el siguiente código al comenzar el archivo:

<?php
/*
Template Name: Mi plantilla de página
*/
?>

Con esto ya debiera aparecer en el listado de plantillas de página la opción «Mi plantilla de página«, luego solo tienes que modificar este archivo para cambiar su estructura.

Si quieres saber más aquí está la explicación en el codex.

¿Qué es un custom post type?

Un «custom post type» o CPT es un tipo de contenido nuevo que podemos crear dentro de WordPress. De manera predeterminada tenemos los «post» (entradas) y las «pages» (páginas), pero está en nuestras manos agregar nuevos contenidos como libros, películas, cursos, o cualquier otro tipo que haga sentido con la funcionalidad de nuestro sitio.

custom post typesA modo de ejemplo, así luce el menú de un sitio en el que he estado trabajando recientemente. Podrás ver que hay tipos de contenido adicionales como «Destacados», «Slider» y «Actividades», esto hace mucho más fácil la administración del sitio para el cliente y permite tener algo más de versatilidad en el diseño.

Crear un CPT para tu sitio requiere varias líneas de código, pero gracias a una herramienta llamada GenerateWP, esta tarea se hace mucho más sencilla. Sólo necesitas completar un formulario indicando las características del tipo de contenido que quieres desarrollar y la aplicación te devolverá el código que deberás agregar al archivo de funciones de tu tema o al plugin que estés utilizando para este propósito (lo más recomendado).

En mi caso, el «custom post type» que necesitaba agregar al sitio era «Cursos«, así que utilicé esta herramienta, obtuve el código y lo añadí en mi plugin. Puedes ver y utilizar mi código aquí.

Los custom post type no soportan plantillas de página

Mi intención era sencilla: crear el tipo de contenido «cursos» y, cuando fuera necesario, poder asignarle una plantilla de página específica para que el curso se pudiera mostrar de una forma más bien comercial o tipo landing page, como es el ejemplo del curso de Creación Temas WordPress Profesionales hoy día.

Parece algo sencillo, pero me encontré con la sorpresa de que no hay una forma simple y nativa de hacer que los tipos de contenido personalizados tengan la posibilidad de utilizar plantillas de páginas. 🙁

Después de dar vuelta un par de horas en internet buscando una respuesta llegué a 2 opciones:

  1. Conformarme con crear un único diseño que aplique al detalle de todos los cursos.
  2. Descargar y modificar el plugin «Page Templates for Posts«, para que pueda aplicar a mi CPT, ya que por defecto sólo aplica a los «post».

Ninguna de estas 2 opciones me servía. La primera me quitaba la posibilidad de crear un landing page por cada curso y la segunda significaba bastante trabajo de programación, probablemente más avanzada de lo que me sentiría a gusto realizando, además estaría dependiendo de que eventualmente el plugin sea actualizado y debiera rehacer todo el trabajo.

Tuve que pensar creativamente y llegué a una solución más simple y efectiva 🙂

Esta es mi solución

1. Crear un custom field

Lo primero que hice fue crear una nueva sección de opciones (meta box) a la pantalla de edición de cursos que incluyera una opción personalizada (custom field) para seleccionar una plantilla de diseño. Esto lo hice a través del plugin Advanced Custom Fields Pro (aunque también puedes conseguir exactamente lo mismo con su versión gratuita).

Desde la pantalla de opciones del plugin, creé un nuevo field group llamado «Opciones de página del curso» y dentro de él creé el custom field plantilla, que es un select con las siguientes opciones:

  • estandar (para aplicar la plantilla estándar)
  • bases (para aplicar el diseño de las bases del desarrollo de temas WordPress)
  • temas-wp (para aplicar los estilos del curso de creación de temas)
  • curso-email (para aplicar a los cursos que se entreguen vía email)

Este field group aplica solo al CPT cursos y en la pantalla de edición de cada curso luce de esta forma:

ACF plantilla de pagina

2. Crear la plantilla base

Lo que sea que se seleccione en cada curso con respecto a la plantilla, carece de sentido si no lo obtenemos desde nuestro theme, así que eso es lo que hice a continuación: creé la plantilla estándar para mostrar el detalle de cada curso (single-cursos.php) y dentro de este archivo puse el siguiente código para obtener el detalle de la opción que se haya aplicado a cada curso:

<?php 
// Obtiene información de cual es el curso que se está cargando
global $post; 

// Obtiene el valor de la plantilla que se haya seleccionado para este curso
$plantilla = get_post_meta($post->ID, 'plantilla', true);

Luego, basado en el valor aplicado, hice unas comprobaciones condicionales, y en base a ello se carga la plantilla  que corresponda usando «require_once» de PHP. Incluso, utilicé «wp_enqueue_style» para cargar algunas hojas de estilo específicas cuando corresponda:

// Si la opción es estandar
if( $plantilla == 'estandar' ) {
	
	wp_enqueue_style('estandar-style', get_stylesheet_directory_uri() . '/template-estandar/style.css');
	require_once('template-estandar/template.php');

// Si la opción es curso-email	
} elseif( $plantilla == 'curso-email' ) {
	
	
	wp_enqueue_style('email-style', get_stylesheet_directory_uri() . '/template-cursoemail/style.css');
	require_once('template-cursoemail/template.php');

// Si la opción es bases	
} elseif( $plantilla == 'bases' ) {
	
	
	wp_enqueue_style('bases-style', get_stylesheet_directory_uri() . '/template-bases/style.css');
	require_once('template-bases/template.php');

// Si la opción es temas-wp	
} elseif( $plantilla == 'temas-wp' ) {
	
	
	wp_enqueue_style('temaswp-style', get_stylesheet_directory_uri() . '/template-temaswp/style.css');
	wp_enqueue_style('magnificpopup', get_stylesheet_directory_uri() . '/template-temaswp/css/magnific-popup.css');
	require_once('template-temaswp/template.php');
	
}

 3. Desarrollar las plantillas

Con esto funcionando, lo único que queda es desarrollar el detalle de cada plantilla especial. Es mi caso he ordenado cada una de ellas dentro de una carpeta, para mantener organizado mi tema ya que varias de las plantillas usan sus propias hojas de estilo y/o archivos  JavaScript.

Así lucen los cursos

Gracias a esta solución, he conseguido que los cursos se mantengan como CPT y que cada vez que lo necesite pueda aplicar el diseño que se me antoje.

Ciertamente no es tan sencillo como si WordPress soportara las plantillas de página en los custom post types de manera nativa, pero aún así me sirve. Lo único en lo que debo poner atención es que cada vez que quiera crear una nueva plantilla deberé realizar 3 acciones:

  1. Añadir una opción nueva al custom field
  2. Actualizar la comprobación condicional
  3. Preparar el nuevo archivo de plantilla

Mira, así es como se ven algunos de los cursos gracias a esta solución:

Plantilla de curso vía email:

bases

Plantilla de curso estándar:

personalizacion-admin

Plantilla personalizada de curso Creación de Temas WordPress Profesionales:

temas-wp¿Qué opinas?

¿Crees que podría haber conseguido el mismo resultado de una forma más sencilla o que hay algún plugin que cubre esta necesidad y que nunca lo encontré? Deja tu comentario más abajo y conversemos sobre ello.

Un abrazo,
@FranciscoAMK