template single

Cómo definir una plantilla diferente por categoría para el detalle de los posts

En WordPress se usa la plantilla single.php para el detalle de los posts. Podemos crear plantillas para los posts de un custom post type concreto siguiendo la nomenclatura single-{$posttype}.php, ¿pero qué pasa si queremos tener plantillas single.php diferentes para cada categoría?

El poder diferenciar las plantillas de los posts por categoría es una una situación que nos podemos encontrar comúnmente. Por ejemplo, tener una categoría «noticias» y querer que la plantilla de todos los posts de noticias tenga una maquetación diferente, o cargue algún elemento adicional en el sidebar, etc…

En este artículo vamos a ver un par de soluciones a este problema. La primera pasa por duplicar el archivo single.php y renombrarlo por single-default.php. A continuación editamos el archivo single.php y usando los condicionales de WordPress podemos filtrar la categoría (por ID o por slug) y cargar mediante PHP la plantilla correspondiente:

<?php

// Filtrando por ID
if (in_category(1)) {
    include(TEMPLATEPATH . '/single1.php');
} elseif (in_category(2)) {
    include(TEMPLATEPATH . '/single2.php');
} else {
    include(TEMPLATEPATH . '/single-default.php');
}

// Filtrando por slug
if (in_category('noticias')) {
    include(TEMPLATEPATH . '/single-noticias.php');
} elseif (in_category('eventos')) {
    include(TEMPLATEPATH . '/single-eventos.php');
} else { // Sino, cargo otro single por defecto
    include(TEMPLATEPATH . '/single-default.php');
}

De este modo incluiremos el archivo correspondiente si cumple cualquier condición de las que hemos planteado, y en caso contrario cargaremos el archivo single-default.php, que recordemos es copia del archivo single.php original.

Vamos a ver ahora otra solución más elegante: utilizaremos el filtro single_template de WordPress, donde llamaremos a una función que recorrerá las categorías del post, y cargará si encuentra un archivo single-nombredelacategoria.php (buscaremos por el slug de la categoría). En caso contrario devolverá single.php. Pondremos en nuestro functions.php:

<?php

function custom_single_template($the_template) {
    foreach ( (array) get_the_category() as $cat ) {
        if ( locate_template("single-{$cat->slug}.php") ) {
            return locate_template("single-{$cat->slug}.php");
        }
    }
    return $the_template;
}
add_filter( 'single_template', 'custom_single_template');

NOTA

Hay que tener en cuenta que el nombre que asignemos al fichero no coincida con el patrón single-{$posttype}.php de un custom post type existente. Es decir, si tenemos un custom post type Eventos y una categoría con el mismo nombre, se produciría un conflicto. Utilizamos la función locate_template() para buscar en nuestro tema la plantilla correspondiente. Busca primero en STYLESHEETPATH, luego en TEMPLATEPATH. De este modo, un tema hijo puede sobreescibir una plantilla del tema padre. Éste aporte es gracias a Juan Padial

Con éste simple código podremos crear plantillas diferentes en función de nuestras necesidades para los posts de cada categoría.

¿Te ha resultado útil esta información? 🍺

Si este post te ha resuelto un problema, invítame a un café o a una cerveza. Con este pequeño gesto me animas a seguir escribiendo.

Comentarios

8 comentarios en Cómo definir una plantilla diferente por categoría para el detalle de los posts

  1. Muy bueno, gracias…pero una pregunta, como puedo quitar el encabezado y el pie solo en
    single-nombredelacategoria.php. se puede hacer esto? como? .

      1. Buenas Pablo, he retomado el trabajo por el cual te hice la pregunta «»como puedo quitar el encabezado y el pie solo en single-nombredelacategoria.php. se puede hacer esto? cómo?»», y he visto tu respuesta, pero yo no soy programador, se html y css y ahí me quede. Me hace falta hacer esto para poder insertar una determinada categoria en una aplicación. Hago una página con las entradas de la categoría en concreto, a esa página con opciones del tema le quito la cabecera y el pie, pero al darle «leer más» me salta a la single.php principal y no se como quitarle el pie y la cabecera…se puede hace?

        1. Quizá lo más fácil es lo siguiente:

          Imaginamos que tu categoría concreta se llama «Noticias»

          – duplica tu archivo header.php y llámalo header-noticias.php
          – Edítalo y borra los menús, el logo, o lo que no quieras que aparezca en la categoría noticias.
          – Edita la plantilla single-noticias.php y donde tienes la llamada a get_header() cámbialo por get_header( ‘noticias’ );
          – De este modo, cuando estés en esa plantilla, cargarás la cabecera donde has eliminado el menú, el logo o lo que tengas
          – Lo mismo para el footer

    1. Mira, este artículo es interesante para que veas que tipo de «loquesea.php» se pueden usar por defecto, y WordPress va a entender: https://developer.wordpress.org/themes/basics/template-hierarchy/. Como ves, no hay una forma contemplada de «post de X categoría» para que te cargue con una plantilla PHP concreta. La forma de hacerlo sería la indicada por Pablo 😉

      De hecho, salvo que la plantilla sea considerablemente diferente, siempre es mejor hacer condicionales para no tener código duplicado.

  2. No te falta razón. Pero en este post no hablo de la página que muestra un listado de posts de una determinada categoría. Es para crear las páginas de detalle (los single) de los posts de una determinada categoría.

    Saludos

  3. Buen dia, gracias por el dato, como puedo lograr cambiar el GRID de visualización de los productos solo en algunas id categorias.

    Es decir en la categoría 3410 quiero que el grid de productos sea de 4 y en el resto de 3.

    He intentado con este código pero no me funciona en WP con plantilla Sayara.

    En el fichero: woocommerce/content-product-cat.php
    Agrego:

    <div >

    <div >

    Nota: Separo los cierres de php y apertura para que se pueda ver

    1. Hola Jose Pablo. No se ha guardado el código que has enviado. Pero para hacer lo que comentas, simplemente habría que poner un condicional que pregunte por tu categoría y el HTML correspondiente al grid de 4, y en caso contrario, el correspondiente a 3

Deja un comentario

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

  • El fin del tratamiento es únicamente la moderación de comentarios para evitar spam
  • La legitimación es tu consentimiento al comentar
  • No se comunicará ningún dato a terceros salvo por obligación legal
  • Tienes derecho al acceso, rectificación y eliminación de los comentarios