campos personalizados

Cómo añadir campos personalizados o custom fields al back-end de WordPress de forma elegante

En esta entrada vamos a ver como añadir campos personalizados o custom fields al back-end de WordPress de manera elegante, es decir, utilizando meta_boxes.

Actualmente puedes añadir campos personalizados sin la necesidad de utilizar plugins. Simplemente puedes dirigirte a editar una entrada, desplegar el menú colgante Opciones de pantalla situado en la parte superior derecha, y verificar que se encuentra activa la casilla Campos personalizados.

Una vez activada vemos que al final de la página nos genera un meta_box llamado Campos personalizados donde puedes agregar tantos campos como quieras. Los custom fields se almacenan en la tabla wp_postmeta, relacionados al id del post y compuestos por una key y un value.

custom fields defecto

Los campos personalizados son una manera muy útil de añadir información y enriquecer el contenido de tus páginas. Pero, ¿qué pasa cuando quieres ir un poco más allá? Es muy común en los desarrollos a medida querer presentar esta información de una manera más elegante, o adaptarlos a unas necesidades concretas. Si necesitamos agregar un campo personalizado que sea un combo donde pueda escoger entre varias opciones, o queremos agruparlos por secciones…la opción por defecto que nos da WordPress se nos queda corta.

Podemos entonces utilizar un plugin sobre el que ya hablamos en este blog como Advanced Custom Fields. Con éste potentísimo plugin podemos añadir prácticamente cualquier funcionalidad y cualquier tipo de campo a cualquier elemento de WordPress: selector de fecha, selector de color, relaciones con otros posts, google maps, etc…

Pero en ocasiones, no podemos utilizar plugins de terceros por requerimientos de cliente, o simplemente no queremos sobrecargar la web con un uso desmesurado de plugins y preferimos hacer el desarrollo nosotros mismos.

Después de ésta introducción vamos a lo que nos ocupa, con un ejemplo práctico. Vamos a agregar información relacionada (fecha, población, provincia, e-mail de contacto) a un custom post type Eventos. Lo primero de todo es agregar un meta_box con la función add_meta_box(). Crearemos una función personalizada para agregar éste meta_box sólo en el caso en el que estemos editando o añadiendo una entrada perteneciente al custom post type Eventos, y la añadiremos al action add_meta_boxes:

<?php

function events_metabox() {
  add_meta_box( 'events-metabox', 'Información relacionada Eventos', 'campos_eventos', 'eventos', 'normal', 'high' );
}
add_action( 'add_meta_boxes', 'events_metabox' );

Cómo podemos observar la función add_meta_box() acepta los siguientes parámetros:

  • id: Identificador del meta_box.
  • title: Título o nombre que aparece en la parte superior o cabecera.
  • callback: Función a la que llamaremos para crear nuestros campos personalizados dentro del meta_box.
  • screen: Pantallas de la administración de WordPress donde aparecerá el meta_box. Los valores que acepta son ‘post’, ‘page’, ‘dashboard’, ‘link’, ‘attachment’, ‘custom_post_type’, ‘comment’, donde custom_post_type es el slug de nuestro custom post type (eventos).
  • context: Lugar de la pantalla de edición donde aparecerá. Los valores que acepta son ‘normal’, ‘advanced’, o ‘side’.
  • priority: La prioridad dentro del contexto. Los valores que acepta son ‘high’, ‘core’, ‘default’ o ‘low’.

El siguiente paso es crear la función campos_eventos que llamamos en el callback, y que creará nuestros campos fecha, población, provincia e e-mail dentro del meta_box:

<?php

function campos_eventos($post) {
  //si existen se recuperan los valores de los metadatos
  $event_date = get_post_meta( $post->ID, 'event_date', true );
  $event_town = get_post_meta( $post->ID, 'event_town', true );
  $event_province = get_post_meta( $post->ID, 'event_province', true );
  $event_email = get_post_meta( $post->ID, 'event_email', true );

  //Almacenamos las provincias en un array para montar un select
  $array_provinces = array("Seleccione una Provincia", "Álava", "Albacete", "Alicante", "Almería", "Ávila", "Badajoz", "Baleares", "Barcelona", "Burgos", "Cáceres", "Cádiz", "Castellón", "Ciudad Real", "Córdoba", "La Coruña", "Cuenca", "Gerona", "Granada", "Guadalajara", "Guipúzcoa", "Huelva", "Huesca", "Jaén", "León", "Lérida", "La Rioja", "Lugo", "Madrid", "Málaga", "Murcia", "Navarra", "Ourense", "Principado de Asturias", "Palencia", "Las Palmas", "Pontevedra", "Salamanca", "Santa Cruz de Tenerife", "Cantabria", "Segovia", "Sevilla", "Soria", "Tarragona", "Teruel", "Toledo", "Valencia", "Valladolid", "Vizcaya", "Zamora", "Zaragoza", "Ceuta", "Melilla");

  // Se añade un campo nonce para probarlo más adelante cuando validemos
  wp_nonce_field( 'campos_eventos_metabox', 'campos_eventos_metabox_nonce' );?>

  <table width="100%" cellpadding="1" cellspacing="1" border="0">
    <tr>
      <td width="20%"><strong>Fecha</strong><br /><small>(dd/mm/aaaa)</small></td>
      <td width="80%"><input type="text" name="event_date" value="<?php echo sanitize_text_field($event_date);?>" class="large-text" placeholder="Fecha" /></td>
    </tr>
    <tr>
      <td><strong>Localidad</strong></td>
      <td><input type="text" name="event_town" value="<?php echo sanitize_text_field($event_town);?>" class="large-text" placeholder="Localidad" /></td>
    </tr>
    <tr>
      <td><strong>Provincia</strong><br /><small>(Máx 255 caracteres)</small></td>
      <td><select name="event_province" class="postform">
        <?php foreach ($array_provinces as $key => $province) {?>
          <option value="<?php echo ($key);?>" <?php if ($event_province == $key){?>selected="selected"<?php }?>><?php echo $province;?></option>
        <?php }?>
      </select></td>
    </tr>
    <tr>
      <td><strong>E-mail</strong></td>
      <td><input type="email" name="event_email" value="<?php echo sanitize_email($event_email);?>" class="large-text" placeholder="E-mail de contacto" /></td>
    </tr>
  </table>
<?php }?>

Ya tenemos nuestro meta_box con los campos personalizados, el siguiente paso es guardar la meta información cuando actualizamos el post. Para ello vamos a crear una función y la añadiremos al action save_post. Antes de guardar los datos realizaremos las siguientes comprobaciones:

  • Hemos establecido un campo nonce, verificaremos que es correcto
  • Comprobaremos si es un autoguardado, en este caso no realizaremos acción alguna
  • Comprobaremos los permisos de usuario
  • Si estas tres premisas son válidas, guardaremos los datos
<?php

function campos_eventos_save_data($post_id) {
  // Comprobamos si se ha definido el nonce.
  if ( ! isset( $_POST['campos_eventos_metabox_nonce'] ) ) {
    return $post_id;
  }
  $nonce = $_POST['campos_eventos_metabox_nonce'];

  // Verificamos que el nonce es válido.
  if ( !wp_verify_nonce( $nonce, 'campos_eventos_metabox' ) ) {
    return $post_id;
  }

  // Si es un autoguardado nuestro formulario no se enviará, ya que aún no queremos hacer nada.
  if ( defined( 'DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
    return $post_id;
  }

  // Comprobamos los permisos de usuario.
  if ( $_POST['post_type'] == 'page' ) {
    if ( !current_user_can( 'edit_page', $post_id ) )
      return $post_id;
  } else {
    if ( !current_user_can( 'edit_post', $post_id ) )
      return $post_id;
  }

  // Vale, ya es seguro que guardemos los datos.

  // Si existen entradas antiguas las recuperamos
  $old_event_date = get_post_meta( $post_id, 'event_date', true );
  $old_event_town = get_post_meta( $post_id, 'event_town', true );
  $old_event_province = get_post_meta( $post_id, 'event_province', true );
  $old_event_email = get_post_meta( $post_id, 'event_email', true );

  // Saneamos lo introducido por el usuario.
  $event_date = sanitize_text_field( $_POST['event_date'] );
  $event_town = sanitize_text_field( $_POST['event_town'] );
  $event_province = sanitize_text_field( $_POST['event_province'] );
  $event_email = sanitize_text_field( $_POST['event_email'] );

  // Actualizamos el campo meta en la base de datos.
  update_post_meta( $post_id, 'event_date', $event_date, $old_event_date );
  update_post_meta( $post_id, 'event_town', $event_town, $old_event_town );
  update_post_meta( $post_id, 'event_province', $event_province, $old_event_province );
  update_post_meta( $post_id, 'event_email', $event_email, $old_event_email );
}
add_action( 'save_post', 'campos_eventos_save_data' );

Ya tenemos la funcionalidad complete para trabajar con custom fields personalizados en nuestro back-end. Para un editor es más facil si lo presentamos de este modo, quedando así:

custom fields personalizados

Para recuperar esta información en el front-end haremos uso de la función get_post_meta(). Obtendremos los datos que hemos almacenado en nuestro custom post type Eventos y podremos mostrársela a los usuarios de la manera que necesitemos, e incluso generar un pequeño formulario de contacto donde el receptor sea el e-mail establecido.

¿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

6 comentarios en Cómo añadir campos personalizados o custom fields al back-end de WordPress de forma elegante

  1. Alguna idea del por que, cuando llamo get_post_meta(‘event_province’) en vez de mostrarme la provincia, me muestra un numero?

    1. Si. Para este ejemplo construyo el select de provincias a partir de un array. Lo normal sería hacerlo a través de una tabla en BBDD. Al construir el select dinámicamente asigno al value de cada option el «key» del foreach que en este caso es 0, 1, 2, 3….por eso te devuelve un número.

      Ese número es el índice del array de provincias

  2. Hola, muy bien el articulo, podrias ir a un nivel un poco mas avanzado y explicarnos como hacer que el campo select de colores obtenga los valores de una tabla dentro de la base de datos de wordpress?

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