Introducción
Este tutorial explica, paso a paso y con todo lujo de detalles, cómo crear un grid (rejilla) de entradas de WordPress filtrado por categoría usando únicamente CSS y código en tu tema (sin plugins). Incluye un shortcode reutilizable, ejemplos de plantilla, el CSS necesario, recomendaciones de accesibilidad y rendimiento, y soluciones a problemas comunes. Todo el código necesario está listo para copiar y pegar.
Requisitos y buenas prácticas previas
- Usar un child theme o un tema personalizado para no perder cambios en actualizaciones.
- Hacer copia de seguridad antes de editar functions.php o archivos de plantilla.
- Tener imágenes destacadas habilitadas y generación de miniaturas configurada (Apariencia → Personalizar → Imágenes destacadas o mediante add_theme_support(post-thumbnails)).
- Conocer la categoría por slug o por ID que quieres mostrar.
1) Crear un shortcode PHP para mostrar la rejilla por categoría
El método más flexible es registrar un shortcode que acepte parámetros: categoría (slug o ID), número de posts, columnas, longitud del extracto, mostrar fecha, etc. Pega este código en el archivo functions.php del child theme o en un plugin de funcionalidades.
, // slug o ID de la categoría
posts => 6,
cols => 3,
excerpt => 18,
show_date => 1,
class => , // clases adicionales
), atts, cat_grid )
// Preparar args para WP_Query
query_args = array(
posts_per_page => intval(atts[posts]),
post_status => publish,
ignore_sticky_posts => true,
)
// Soportar tanto slug (category_name) como ID (cat)
if ( is_numeric( atts[cat] ) intval( atts[cat] ) > 0 ) {
query_args[cat] = intval( atts[cat] )
} elseif ( ! empty( atts[cat] ) ) {
query_args[category_name] = sanitize_text_field( atts[cat] )
}
q = new WP_Query( query_args )
// Construir clases para el grid
cols = max(1, intval(atts[cols]))
grid_class = cat-grid cols- . cols
if ( ! empty( atts[class] ) ) {
grid_class .= . sanitize_html_class( atts[class] )
}
ob_start()
if ( q->have_posts() ) {
echo ltdiv class= . esc_attr( grid_class ) . role=listgt
while ( q->have_posts() ) {
q->the_post()
post_id = get_the_ID()
title = get_the_title()
permalink = get_permalink()
has_thumb = has_post_thumbnail(post_id)
excerpt = wp_trim_words( get_the_excerpt() ? get_the_excerpt() : get_the_content(), intval(atts[excerpt]), ... )
date_html = atts[show_date] ? lttime datetime= . esc_attr( get_the_date( c ) ) . class=post-dategt . esc_html( get_the_date() ) . lt/timegt :
echo ltarticle class=cat-grid-item role=listitemgt
// Imagen destacada (con fallbacks)
if ( has_thumb ) {
thumb = get_the_post_thumbnail( post_id, medium, array(loading => lazy, alt => get_the_title(post_id)) )
echo ltdiv class=cat-grid-mediagtlta href= . esc_url( permalink ) . gt . thumb . lt/agtlt/divgt
} else {
// Fallback: elemento vacío con clase para estilizar
echo ltdiv class=cat-grid-media no-thumbgtlta href= . esc_url( permalink ) . gtltspan class=no-thumb-innergt . esc_html( title ) . lt/spangtlt/agtlt/divgt
}
// Contenido
echo ltdiv class=cat-grid-bodygt
echo lth3 class=cat-grid-titlegtlta href= . esc_url( permalink ) . gt . esc_html( title ) . lt/agtlt/h3gt
if ( date_html ) {
echo date_html
}
echo ltdiv class=cat-grid-excerptgt . wp_kses_post( wpautop( excerpt ) ) . lt/divgt
echo lta class=cat-grid-more href= . esc_url( permalink ) . gtLeer máslt/agt
echo lt/divgt
echo lt/articlegt
}
echo lt/divgt // .cat-grid
} else {
echo ltp class=cat-grid-no-resultsgtNo hay entradas en esta categoría.lt/pgt
}
wp_reset_postdata()
return ob_get_clean()
}
add_shortcode(cat_grid, wp_cat_grid_shortcode)
?>
Uso del shortcode
Ejemplos de uso dentro del editor de entradas/páginas o en bloques de texto:
- [cat_grid cat=noticias posts=6 cols=3] — grid de 6 posts de la categoría con slug noticias en 3 columnas.
- [cat_grid cat=12 posts=8 cols=4 excerpt=20] — usando ID de categoría 12, 8 entradas, 4 columnas.
2) CSS para el grid (responsivo y moderno)
Pega este CSS en el archivo style.css de tu tema, o en Apariencia → Personalizar → CSS adicional. Ajusta colores, fuentes y medidas según tu diseño.
/ Grid base /
.cat-grid {
display: grid
gap: 1.25rem
margin: 0
padding: 0
}
/ Columnas: clases .cols-1 .cols-2 .cols-3 .cols-4 /
.cat-grid.cols-1 { grid-template-columns: 1fr }
.cat-grid.cols-2 { grid-template-columns: repeat(2, 1fr) }
.cat-grid.cols-3 { grid-template-columns: repeat(3, 1fr) }
.cat-grid.cols-4 { grid-template-columns: repeat(4, 1fr) }
/ Responsive: adaptamos para móviles /
@media (max-width: 900px) {
.cat-grid.cols-4, .cat-grid.cols-3 { grid-template-columns: repeat(2, 1fr) }
}
@media (max-width: 520px) {
.cat-grid { grid-template-columns: 1fr }
}
/ Card /
.cat-grid-item {
background: #ffffff
border: 1px solid #e5e7eb
display: flex
flex-direction: column
overflow: hidden
border-radius: 6px
transition: transform .18s ease, box-shadow .18s ease
}
/ Elevación en hover /
.cat-grid-item:hover {
transform: translateY(-6px)
box-shadow: 0 8px 24px rgba(16,24,40,0.08)
}
/ Media (imagen) - mantener ratio consistente /
.cat-grid-media {
width: 100%
aspect-ratio: 16/9 / si el navegador no soporta, sustituir por padding-top hack /
overflow: hidden
background: #f3f4f6
display: block
}
.cat-grid-media img {
width: 100%
height: 100%
object-fit: cover
display: block
}
/ Fallback cuando no hay miniatura /
.cat-grid-media.no-thumb {
display: flex
align-items: center
justify-content: center
padding: 1rem
color: #374151
font-weight: 600
text-align: center
}
.cat-grid-media.no-thumb .no-thumb-inner {
display: block
}
/ Body: título, meta y excerpt /
.cat-grid-body {
padding: 1rem
display: flex
flex-direction: column
gap: 0.5rem
flex: 1 1 auto
}
.cat-grid-title {
margin: 0
font-size: 1.05rem
line-height: 1.3
}
.cat-grid-title a {
color: #0f172a
text-decoration: none
}
.cat-grid-title a:hover {
color: #2563eb
text-decoration: underline
}
.post-date {
color: #6b7280
font-size: 0.875rem
}
/ Excerpt /
.cat-grid-excerpt {
color: #374151
font-size: 0.95rem
margin-top: 0.25rem
flex: 1 1 auto
}
/ Botón Leer más /
.cat-grid-more {
display: inline-block
margin-top: 0.5rem
color: #2563eb
text-decoration: none
font-weight: 600
}
.cat-grid-more:hover { text-decoration: underline }
/ Ajustes visuales menores /
.cat-grid-no-results { color: #6b7280 }
3) Alternativa: insertar el grid directamente en una plantilla (por ejemplo category.php)
Si prefieres mostrar la rejilla automáticamente en una plantilla (por ejemplo en archive de categoría), puedes usar una variante del loop dentro de tu archivo category.php o un template part. Ejemplo de código para insertar en una plantilla:
cat->term_id,
posts_per_page => 12,
ignore_sticky_posts => true,
)
q = new WP_Query(args)
if (q->have_posts()) : ?>
ltdiv class=cat-grid cols-3gt
have_posts()) : q->the_post() ?>
ltarticle class=cat-grid-itemgt
ltdiv class=cat-grid-mediagt
lta href=lt?php the_permalink() ?gtgtlt?php the_post_thumbnail(medium) ?gtlt/agt
lt/divgt
ltdiv class=cat-grid-bodygt
lth3 class=cat-grid-titlegtlta href=lt?php the_permalink() ?gtgtlt?php the_title() ?gtlt/agtlt/h3gt
ltdiv class=cat-grid-excerptgtlt?php echo wp_trim_words(get_the_excerpt(), 18, ...) ?gtlt/divgt
lta class=cat-grid-more href=lt?php the_permalink() ?gtgtLeer máslt/agt
lt/divgt
lt/articlegt
lt/divgt
lt?php wp_reset_postdata() ?gt
lt?php endif ?gt
4) Mejoras opcionales y personalizaciones
- Lazy loading: WordPress 5.5 ya añade loading=lazy a las imágenes generadas por funciones como the_post_thumbnail. En el shortcode anterior ya se añade para compatibilidad.
- Regenerar miniaturas: si cambias tamaños de imagen, usa plugin Regenerate Thumbnails o comandos WP-CLI para regenerar.
- Paginación: si quieres paginar la lista en vez de limitar a X posts, reemplaza posts_per_page y añade paginación con get_query_var(paged) y functions como get_the_posts_pagination().
- Filtros por múltiples categorías: extiende query_args con tax_query para mostrar varias categorías o excluir alguna.
- Personalizar columnas dinámicamente: ya se soporta con el atributo cols del shortcode (cols=234).
- Cache: para tráfico alto, cachea la salida del shortcode con transients o sistema de cache de objetos.
5) Accesibilidad y SEO
- Usa títulos en h3 dentro del grid y enlaces con texto descriptivo.
- Incluye atributos alt en imágenes destacadas (WordPress gestiona esto si subiste alt en la biblioteca).
- Utiliza etiquetas time con datetime para las fechas (ya incluidas en el shortcode ejemplo).
- Evita el uso de imágenes únicamente decorativas sin texto alternativo.
6) Solución de problemas comunes
- No se muestran imágenes destacadas: asegúrate de que la entrada tenga imagen destacada y que el tema soporte post-thumbnails (add_theme_support(post-thumbnails)). Regenera miniaturas si es necesario.
- Clases CSS no aplican: verifica que el CSS esté cargado (style.css activo) y limpia cache del navegador y cache del sitio.
- Shortcode no funciona: confirma que pegaste el código en functions.php del tema activo y que no hay errores de PHP (activa WP_DEBUG si hace falta).
- Quiero más control del markup: copia la función del shortcode y personalízala en tu tema para modificar etiquetas o añadir microdatos.
7) Ejemplo final: todo junto (uso básico)
1) Añade la función del shortcode en functions.php. 2) Añade el CSS en style.css. 3) Inserta en una página: [cat_grid cat=noticias posts=6 cols=3].
Conclusión
Con unas pocas líneas de PHP y CSS puedes obtener una rejilla de entradas por categoría completamente personalizada, ligera y sin plugins. El enfoque con shortcode facilita reutilizar la rejilla en cualquier página o plantilla el enfoque de plantilla integra la rejilla directamente en páginas de archivo. Ajusta estilos y estructura según tu diseño y aplica las recomendaciones de accesibilidad y rendimiento para obtener un resultado profesional.
Leave a Reply