Esto es ideal, si tienes elaborado tu Custom Post Type y necesitas filtrar de forma personalizada en una página en concreto, es cómo un buscador interno para tus Custom Post Types, lo que haremos será crear dicho filtro personalizado que permitirá al usuario seleccionar manuales según campos personalizados como el nivel, duración, o si tiene vídeo por ejemplo. Todo sin plugins . Esto no solo le da un aspecto profesional a tu sitio web o proyecto, sino que también mejor la UX y el SEO
Introducción
Nuestra saga de temas de WordPress Avanzado va a tope, y estamos resolviendo dudas de muchos desarrolladores, creadores de contenido, diseñadores web e incluso aficionados al código, así que si pusiste atención en nuestra saga, te diste cuenta que ya usamos WP_Query para mostrar un listado dinámico de Manuales Avanzados. Pero ahora, vamos a un paso más allá: Vamos a permitirle al usuario filtrar los manuales desde el frontend.
Deseamos algo así cómo:
"Muéstrame solo los manuales de nivel avanzado que duran menos de 15 minutos y que tienen video"
Y lo vamos a lograr.
Estructura que ya tenemos (la base)
Tenemos hasta ahora un CPT llamado manuales
con campos personalizados como:
- _nivel_manual → Básico / Intermedio / Avanzado
_tiempo_lectura
→ en minutos_video_url
→ opcional
Paso 1: Crear el formulario de filtros
Vamos a crear una nueva plantilla llamada page-manuales-filtrados.php

<?php
/*
* Template Name: Filtro de Manuales
*/
get_header();
?>
<main class="wp-block-group">
<div class="wp-block-group">
<h1>Filtra los manuales</h1>
<form method="GET">
<label for="nivel">Nivel:</label>
<select name="nivel" id="nivel">
<option value="">Todos</option>
<option value="basico" <?php selected($_GET['nivel'], 'basico'); ?>>Básico</option>
<option value="intermedio" <?php selected($_GET['nivel'], 'intermedio'); ?>>Intermedio</option>
<option value="avanzado" <?php selected($_GET['nivel'], 'avanzado'); ?>>Avanzado</option>
</select>
<label for="duracion">Duración máxima (min):</label>
<input type="number" name="duracion" id="duracion" value="<?php echo esc_attr($_GET['duracion'] ?? ''); ?>" min="1">
<label>
<input type="checkbox" name="con_video" <?php checked(isset($_GET['con_video'])); ?>>
Solo con video
</label>
<button type="submit">Filtrar</button>
</form>
Vamos a dividir el código en dos partes, la primera será para la estructura del template, y la otra para el WP_Query
Paso 2: Construir la consulta con WP_Query
Después del <form>
, colocamos esto:
<?php
$args = array(
'post_type' => 'manuales',
'posts_per_page' => -1,
'meta_query' => array()
);
if ( !empty($_GET['nivel']) ) {
$args['meta_query'][] = array(
'key' => '_nivel_manual',
'value' => sanitize_text_field($_GET['nivel']),
'compare' => '='
);
}
if ( !empty($_GET['duracion']) ) {
$args['meta_query'][] = array(
'key' => '_tiempo_lectura',
'value' => (int) $_GET['duracion'],
'type' => 'NUMERIC',
'compare' => '<='
);
}
if ( isset($_GET['con_video']) ) {
$args['meta_query'][] = array(
'key' => '_video_url',
'compare' => 'EXISTS'
);
}
if ( count($args['meta_query']) > 1 ) {
$args['meta_query']['relation'] = 'AND';
}
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
echo '<ul>';
while ( $query->have_posts() ) : $query->the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
<p><strong>Nivel:</strong> <?php echo get_post_meta(get_the_ID(), '_nivel_manual', true); ?></p>
<p><strong>Duración:</strong> <?php echo get_post_meta(get_the_ID(), '_tiempo_lectura', true); ?> min</p>
<?php if ( get_post_meta(get_the_ID(), '_video_url', true) ) : ?>
<p>🎥 Incluye video</p>
<?php endif; ?>
</li>
<?php endwhile;
echo '</ul>';
else :
echo '<p>No se encontraron manuales con esos criterios.</p>';
endif;
wp_reset_postdata();
?>
y cerramos el main
:
</div>
</main>
<?php get_footer(); ?>
Guarda los cambios realizados en el template:
Si tienes dudas de cómo debería ser el código completo, te proporciono el código en GitHub:
Paso 3: Agregar estilos CSS Sugeridos para el formulario de filtrado
Vamos añadir estos estilos en nuestro código style.css para estilizar el formulario:
form {
display: flex;
flex-direction: column;
gap: 1rem;
background: #f9f9f9;
padding: 1rem;
border-radius: 10px;
margin-bottom: 2rem;
}
form label {
font-weight: bold;
}
form input, form select, form button {
padding: 0.5rem;
border-radius: 5px;
border: 1px solid #ccc;
}
Paso 4: Probar plantilla de filtros
Una vez que hemos creado el nuevo template, y tenemos agregado código CSS de nuestra hoja de estilos. Vamos a crear la plantilla en nuestro panel de WordPress, así que vamos a darle click en crear nueva página.

Después asignaremos un nombre a la plantilla y posteriormente seleccionaremos la plantilla adecuada para este caso:

Puedes darle click en Publicar para ver los resultados logrados:

Excelente, ahora puedes filtrar los manuales, por defecto aparecen todos, recuerda que puedes intentar hacer las siguientes pruebas:
- Filtrar por nivel: solo “avanzado”
- Filtrar por nivel + duración
- Filtrar por nivel + duración + con video
- Solo con video
- Sin filtros (muestra todo)
Conclusiones
Llegamos al final de nuestro tutorial, ¿por qué es importante tener un filtro para nuestro CPT?, creo que no hay mejor resumen que estos puntos:
- ✅ 100% personalizable
- ✅ Sin depender de plugins
- ✅ Total control sobre el HTML
- ✅ Escalable para agregar más filtros como etiquetas, categorías, fechas...
Espero que te haya servido, un gusto y un abrazo. 🤓🚀
Deja una respuesta
Estos temas te pueden interesar