Añadir campos personalizados a los archivos multimedia de WordPress

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);
    // ...
}

attachment_fields_to_save

function media_upload_form_handler() {
    // ...
    $post = apply_filters("attachment_fields_to_save", $post, $attachment);
    // ...
}

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:

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.

¡MANTENME INFORMADO!

¡Gracias por tu interés en estar informado del próximo lanzamiento de mis cursos! 😎

¡No hago spam! Lee la política de privacidad para tener más información.

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 una respuesta

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

*

*

DARÍO BALBONTÍN FERNÁNDEZ es el Responsable del tratamiento de los datos personales del usuario y le informa que estos datos serán tratados de conformidad con lo dispuesto en el Reglamento (UE) 2016/679 de 27 de abril (GDPR) y la Ley Orgánica 3/2018 de 5 de diciembre (LOPDGDD), por lo que se le facilita la siguiente información del tratamiento: Fin del tratamiento: mantener una relación comercial y el envío de comunicaciones sobre nuestros productos y servicios. Criterios de conservación de los datos: se conservarán mientras exista un interés mutuo para mantener el fin del tratamiento y cuando ya no sea necesario para tal fin, se suprimirán con medidas de seguridad adecuadas para garantizar la seudonimización de los datos o la destrucción total de los mismos.Comunicación de los datos: No se comunicarán los datos a terceros, salvo obligación legal. Derechos que asisten al usuario: Derecho a retirar el consentimiento en cualquier momento. Derecho de acceso, rectificación, portabilidad y supresión de sus datos y a la limitación u oposición al su tratamiento. Derecho a presentar una reclamación ante la Autoridad de control (agpd.es) si considera que el tratamiento no se ajusta a la normativa vigente. Datos de contacto para ejercer sus derechos: contacto@dariobf.com.