Entre uno de los muchos proyectos que realizo para clientes, tengo entre manos un portfolio que requería añadir información a las imágenes que lo conformaban.

Esto se podría hacer de varias formas, como por ejemplo creando un custom post type y dándole forma gracias a los Metaboxes y el juego que nos dan los campos personalizados en la creación de themes.

Sin embargo, el portfolio en sí era muy sencillo, sólo requería un campo de texto por cada imagen para poder colocar información más allá de la leyenda, descripción y demás campos que permite incluir WordPress por defecto.

Para este porfolio en el que todos los elementos van organizados por fecha de publicación, sólo constan de una imagen y no necesitan cosas extrañas; decidí que lo mejor era añadir este campo extra a la propia librería de WordPress y activar un checkbox que permitiese decirle a WordPress si esa imagen en cuestión pertenecía o no al portfolio.

Así, el cliente sólo tiene que subir la imagen (arrastrándola, gracias al drag and drop de la librería multimedia de WordPress por esto), rellenar el campo extra y marcar el checkbox para agregar elementos a su portfolio. El blog, las páginas y todas las demás funcionalidades siguen intactas.

Los Hooks o ganchos

Tal y como hicimos con los Metaboxes (la idea es un 80% similar), disponemos de dos funciones, hooks o ganchos a los que “engancharle” cosas.

attachment_fields_to_edit

Al igual que con los metaboxes, el primer paso es crear los campos personalizados, para ello vamos a nuestro functions.php y agregamos la siguiente función:

function get_attachment_fields_to_edit($post, $errors = null) {
    // ...
    $form_fields = apply_filters("attachment_fields_to_edit", $form_fields, $post);
    // ...
}
  • $form_fields es un array especial, pero lo veremos más adelante.
  • $post es el fichero adjunto como objeto (ya sabes que los ficheros adjuntos se tratan como posts en WordPress).

attachment_fields_to_save

function media_upload_form_handler() {
    // ...
    $post = apply_filters("attachment_fields_to_save", $post, $attachment);
    // ...
}
  • $post es el archivo adjunto como array(ya sabes que los ficheros adjuntos se tratan como posts en WordPress).
  • $attachment es la parte que incluirá la configuración de campos que se engancharán a través de attachment_fields_to_edit.

Tranquilo, lo entenderemos más adelante con los ejemplos. Sí que quiero que te des cuenta que en la primera función $post es un objeto y en la segunda es un array.

Explotando attachment_fields_to_edit

Una vez que hemos visto los dos hooks o ganchos que nos permitirán editar la librería, es hora de entender cada uno de los ganchos.

/**
 * Agregando campos personalizados al array $form_fields
 * 
 * @param array $form_fields
 * @param object $post
 * @return array
 */
function my_custom_fields_image_attachment($form_fields, $post) {
    $form_fields["custom1"] = array(
        "label" => __("Custom Text Field"),
        "input" => "text", // this is default if "input" is omitted
        "value" => get_post_meta($post->ID, "_custom1", true)
    );
    return $form_fields;
}
// Añadimos nuestra nueva función al hook o gancho correspondiente:
add_filter("attachment_fields_to_edit", "my_image_attachment_fields_to_edit", null, 2);

Para entender esta función, vamos a ver cada una de las partes que la componen, después de leerlas vuelve a echar un vistazo a la función, todo será más claro:

  • Lo primero que te voy a explicar es que $form_fields es un array especial (tal y como te dije arriba) que contiene los campos que se mostrarán en el formulario de los ficheros adjuntos.
  • $post es lo que tenemos guardado del fichero adjunto en la base de datos. Destaco que $post->post_type equivale a “attachment”; los ficheros adjuntos son tratados como posts en WordPress.

Una vez que ya hemos creado los campos necesarios (en el ejemplo es un simple input) sólo tenemos que engancharlo al gancho correspondiente con el add_filter del final.

Tipos de campos que podemos agregar

Input de tipo texto

// input type="text"
$form_fields["custom_input"]["label"] = __("Esto es un campo personalizado.");
$form_fields["custom_input"]["input"] = "text"; // Si omitimos esta línea, por defecto siempre será de tipo "input"
$form_fields["custom_input"]["value"] = get_post_meta($post->ID, "_custom1", true);

Textarea

// textarea
$form_fields["custom_textarea"]["label"] = __("Textarea personalizado");
$form_fields["custom_textarea"]["input"] = "textarea";
$form_fields["custom_textarea"]["value"] = get_post_meta($post->ID, "_custom2", true);

Campo oculto (Hidden field)

// input type="hidden"
// no need for a label
$form_fields["custom_hidden"]["input"] = "hidden";
$form_fields["custom_hidden"]["value"] = get_post_meta($post->ID, "_custom3", true);

Otros tipos de campos personalizados
Si quieres agregar un select o checkbox, la cosa se complica. Te dejo los códigos para que lo hagas sin preocuparte de nada:

$form_fields["custom_select"]["label"] = __("Select Personalizado");
$form_fields["custom_select"]["input"] = "html";
$form_fields["custom_select"]["html"] = "
<select name='attachments[{$post->ID}][custom_select]' id='attachments[{$post->ID}][custom_select]'>
    <option value='1'>Opción 1</option>
    <option value='2'>Opción 2</option>
    <option value='3'>Opción 3</option>
</select>";
 
// another example 
$form_fields["custom_checkbox"]["label"] = __("Checkbox Personalizado");
$form_fields["custom_checkbox"]["input"] = "html";
$form_fields["custom_checkbox"]["html"] = "La salida HTML va aquí, como en un checkbox: 
<input type='checkbox' value='1'
    name='attachments[{$post-/>ID}][custom_checkbox]'
    id='attachments[{$post->ID}][custom_checkbox]' />";

Atributos especiales
Además, podemos agregar atributos especiales que mejoran la usabilidad y agregan un extra a lo que agreguemos:

Helps: Mostrará un texto de ayuda al usuario.

// Campo personalizado con texto de ayuda
$form_fields["custom_help"]["label"] = __("Campo personalizado con texto de ayuda");
$form_fields["custom_help"]["value"] = get_post_meta($post->ID, "_custom6", true);
$form_fields["custom_help"]["helps"] = "Aquí va el texto de ayuda.";

Required: Campo obligatorio de rellenar.

$form_fields["custom_required"]["label"] = __("Campo Obligatorio");
$form_fields["custom_required"]["value"] = get_post_meta($post->ID, "_custom7", true);
$form_fields["custom_required"]["required"] = TRUE; // Por defecto es FALSE

Guardar los datos con attachment_fields_to_save

Ya casi terminamos, lo más complicado ya está hecho y te aseguro que guardar los datos es mucho más simple de lo que crees.

De lo que nos tenemos que preocupar es de dos cosas; por un lado asegurarnos de si el campo ha sido rellenado y, en caso afirmativo, guardar el contenido en la base de datos como un post meta normal.

function my_image_attachment_fields_to_save($post, $attachment) {
    if( isset($attachment['mi_campo']) ){
        // update_post_meta(postID, meta_key, meta_value);
        update_post_meta($post['ID'], '_mi_campo', $attachment['mi_campo']);
    }
    return $post;
}

Tendremos que modificar donde dice “mi_campo” por lo que hayamos puesto en el array $form_fields (en los ejemplos anteriores sería una de estas opciones: custom_input, custom_textarea, custom_hidden, custom_select o custom_checkbox) y también hacer la modificación correspondiente en el update_post_meta, donde pasamos el parámetro “_mi_campo”, donde sería lo que hayamos puesto en el mismo array ($form_fields).

Conclusión

Como ves, no es complicado exprimir un poco más WordPress y utilizarlo como Framework.

Algunas ideas que me dan esta entrada: Crear categorías en las imágenes de WordPress o añadir un tipo de fichero para poder mostrarlo de diferentes formas en el Front-end de la web.

Como siempre, si te gusta compártelo y deja un comentario con tus dudas o lo que te apetezca compartir.

2 comentarios en “Añadir campos personalizados a los archivos multimedia de WordPress

  1. Hola. Gracias por tu aportación y por compartir tu sabiduría con los que no tenemos conocimientos. Me has ayudado mucho!!
    Si es posible, me gustaría saber cómo has mostrado los resultados en la parte pública. Yo he creado un archivo de plantilla tipo page y estoy intentando hacer una consulta con el objecto new WP_Query, pero no no sale nada. Así que algo estoy haciendo mal :-(
    Si puedieras, te agradecería un montón que me ayudaras a resolver este problema.
    Un saludo y mil gracias por ser tan solidario!!

Deja un comentario

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