Seguimos nuestra saga de WordPress Avanzado, y ahora crearemos los famosos Campos Personalizados sin utilizar plugins, todo esto con buenas prácticas y con corazón de desarrollador 💛
En el post anterior hablamos sobre cómo crear las plantillas de los Custom Post Type que realizamos, y realmente fue un buen tutorial, porque no solo hablamos de crearlos, sino de darles un diseño profesional con algo de Grid en CSS. ¿te gustó?, seguro que si. Así que ahora veamos, ¿qué son los campos personalizados y por qué deberíamos crear algunos?
¿Qué son los campos personalizados?
Los campos personalizados son metadatos que se pueden añadir a cada entrada o post. WordPress los soporta por defecto, pero vamos a ir un paso más allá y crear campos personalizados con interfaz gráfica, para facilitar la edición desde el panel de administración.
Para esta saga de tutoriales, vamos a crear tres campos personalizados para los manuales:
- Nivel de dificultad del manual
- Tiempo estimado de lectura
- Video de soporte o presentación
Lo mejor de todo es que lo haremos manual, con código puro. No usaremos plugins como es el caso de ACF que lo hace de manera similar e incluso más avanzado, sin embargo nuestro propósito es aprender a entender mucho mejor WordPress.
Paso 1: Agregar la interfaz al admin con add_meta_box()
Nuevamente vamos a trabajar en nuestro functions.php
de nuestro tema hijo:

Nuestro código en cuestión es:
function labcj_agregar_campos_personalizados() {
add_meta_box(
'labcj_campos_manual', // ID
'Información del Manual', // Título
'labcj_mostrar_campos_manual', // Callback
'manuales', // CPT al que se aplica
'normal', // Posición
'high' // Prioridad
);
}
add_action( 'add_meta_boxes', 'labcj_agregar_campos_personalizados' );
Si gustas, puedes leer un poco de los Meta Boxes en el Core de WordPress
Paso 2: Crear el formulario HTML de los campos
Ahora necesitamos crear el formulario que será visible al momento de poner los campos personalizados, este código lo pegaremos justo debajo del código anterior.
function labcj_mostrar_campos_manual( $post ) {
// Valores actuales
$nivel = get_post_meta( $post->ID, '_nivel_manual', true );
$tiempo = get_post_meta( $post->ID, '_tiempo_lectura', true );
$video = get_post_meta( $post->ID, '_video_url', true );
?>
<p>
<label for="nivel_manual"><strong>Nivel:</strong></label><br>
<select name="nivel_manual" id="nivel_manual">
<option value="básico" <?php selected( $nivel, 'básico' ); ?>>Básico</option>
<option value="intermedio" <?php selected( $nivel, 'intermedio' ); ?>>Intermedio</option>
<option value="avanzado" <?php selected( $nivel, 'avanzado' ); ?>>Avanzado</option>
</select>
</p>
<p>
<label for="tiempo_lectura"><strong>Tiempo estimado de lectura:</strong></label><br>
<input type="text" name="tiempo_lectura" id="tiempo_lectura" value="<?php echo esc_attr( $tiempo ); ?>" />
</p>
<p>
<label for="video_url"><strong>URL del video:</strong></label><br>
<input type="url" name="video_url" id="video_url" value="<?php echo esc_url( $video ); ?>" />
</p>
<?php
}
Y finalizamos con guardar los datos.
Paso 3: Guardar los datos con save_post
Ahora colocaremos la última parte importante de los campos personalizados, el hook de save_post
function labcj_guardar_campos_manual( $post_id ) {
// Evita autoguardados
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// Guarda datos si están presentes
if ( isset( $_POST['nivel_manual'] ) ) {
update_post_meta( $post_id, '_nivel_manual', sanitize_text_field( $_POST['nivel_manual'] ) );
}
if ( isset( $_POST['tiempo_lectura'] ) ) {
update_post_meta( $post_id, '_tiempo_lectura', sanitize_text_field( $_POST['tiempo_lectura'] ) );
}
if ( isset( $_POST['video_url'] ) ) {
update_post_meta( $post_id, '_video_url', esc_url_raw( $_POST['video_url'] ) );
}
}
add_action( 'save_post', 'labcj_guardar_campos_manual' );
Usar los hooks add_meta_boxes
y save_post
junto con la API de post_meta
(get_post_meta
, update_post_meta
) es el enfoque recomendado y "mejor" para manejar campos personalizados a medida porque nos permite integrar fluidamente la UI de administración de WordPress.
Paso 4: Mostrar los campos en el single-manuales.php
Aquí es importante que prestes atención, la plantilla individual que tenemos de single-manuales.php
la vamos a modificar, por lo tanto sugiero que si estás tomando el curso que estamos dando con esta saga de WordPress avanzado, trates de borrar todo el código previamente existente en single-manuales.php y en su defecto, pongas el siguiente que ya incluye los get_post_meta de los campos personalizados.
<?php
get_header();
?>
<main class="wp-block-group alignwide">
<?php
while ( have_posts() ) : the_post();
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="wp-block-group">
<h1 class="wp-block-heading"><?php the_title(); ?></h1>
<div class="wp-block-group">
<strong>Temática:</strong>
<?php the_terms( get_the_ID(), 'tematicas' ); ?>
<?php
// --- Código de los campos personalizados insertado aquí ---
$nivel = get_post_meta( get_the_ID(), '_nivel_manual', true );
$tiempo = get_post_meta( get_the_ID(), '_tiempo_lectura', true );
$video = get_post_meta( get_the_ID(), '_video_url', true );
?>
<section class="wp-block-group">
<p><strong>Nivel:</strong> <?php echo esc_html( ucfirst($nivel) ); ?></p>
<p><strong>Tiempo de lectura:</strong> <?php echo esc_html( $tiempo ); ?></p>
<?php if ( $video ) : ?>
<p><strong>Video:</strong> <a href="<?php echo esc_url( $video ); ?>" target="_blank">Ver video</a></p>
<?php endif; ?>
</section>
<?php // --- Fin del código de campos personalizados --- ?>
</div>
</header>
<div class="wp-block-post-content">
<?php the_content(); ?>
</div>
</article>
<?php
endwhile;
?>
</main>
<?php
get_footer();
?>
Conclusión
Aunque no lo creas, ya hemos terminado, ¿cómo comprobamos con éxito que funciona?, vamos a dirigirnos a nuestro manual, entraremos a editar un manual, y deberás observar lo siguiente:

Llena los tres campos personalizados y observa el resultado final (para ello deberás darle click en Actualizar).

Y listo, tenemos el tutorial terminado. ¿te gustó?. Espero que te haya servido, un gusto y un abrazo. 🤓🚀
Deja una respuesta
Estos temas te pueden interesar