Quando costruisci una pagina di backend (wp-admin) con un form, spesso vuoi offrire due possibilità per inserire un’immagine:
- Caricare un file (input type="file") e mostrare subito un’anteprima, prima dell’invio del form.
- Selezionare un’immagine già presente nella Media Library, aprendo il pannello standard di WordPress tramite le API JavaScript (
wp.media).
Questo articolo riassume e dettaglia entrambe le soluzioni partendo da uno scenario comune: un form nel backend WordPress che salva (o utilizza) un’immagine.
Obiettivo
Implementeremo:
- un pulsante “Seleziona da Media Library” che apre la Media Library e restituisce ID e URL dell’attachment scelto;
- l’anteprima immediata dell’immagine scelta tramite upload (input file), indipendente dalla Media Library;
- una gestione robusta in contesto “modale”, usando l’evento delegato (utile quando il markup viene creato o reinserito dinamicamente).
Prerequisiti e note sul contesto modale
Nel backend WordPress, la finestra Media Library (quella che vedi quando clicchi “Aggiungi media”) è pilotabile via JavaScript. Tuttavia:
- devi assicurarti che lo script
wp.mediasia caricato (in PHP conwp_enqueue_media()); - se la modale crea i contenuti via AJAX o reinserisce l’HTML, il binding diretto agli eventi può rompersi: conviene usare event delegation con
$(document).on(...).
Markup del form
Di seguito un esempio minimale di campi utili sia per la selezione da Media Library, sia per l’upload con anteprima:
<button type="button" class="button" id="ml-select">
Seleziona da Media Library
</button>
<input type="hidden" name="image_id" id="image_id" value="">
<input type="text" class="regular-text" id="image_url" value="" readonly>
<input
type="file"
id="image_upload"
name="image_upload"
accept="image/*"
/>
<p id="image_preview"></p>
Qui:
#image_idmemorizza l’ID dell’attachment (utile per salvare riferimenti stabili);#image_urlconserva l’URL (utile per debug o per usi immediati);#image_uploadgestisce l’upload dal computer;#image_previewè il contenitore dell’anteprima (in questo esempio usiamo unpvuoto, senzadiv).
Caricamento degli script nel backend
Per usare wp.media devi chiamare wp_enqueue_media() nella pagina admin in cui appare la modale. Inoltre, carica il tuo script JS:
add_action('admin_enqueue_scripts', function ($hook) {
// Facoltativo: limita a una specifica pagina admin
// if ($hook !== 'toplevel_page_mia-pagina') return;
wp_enqueue_media(); // Necessario per wp.media
wp_enqueue_script(
'mia-media-picker',
plugins_url('assets/mia-media-picker.js', __FILE__),
['jquery'],
'1.0.0',
true
);
});
Selezione di un’immagine dalla Media Library con wp.media
Nel tuo file assets/mia-media-picker.js puoi creare (e riutilizzare) un media frame. Quando l’utente seleziona un’immagine, aggiorni i campi e mostri la preview.
jQuery(function ($) {
let frame;
// Event delegation: utile in modali che inseriscono HTML dinamicamente
$(document).on('click', '#ml-select', function (e) {
e.preventDefault();
// Riusa il frame se già creato
if (frame) {
frame.open();
return;
}
frame = wp.media({
title: 'Seleziona un’immagine',
button: { text: 'Usa questa immagine' },
library: { type: 'image' },
multiple: false
});
frame.on('select', function () {
const attachment = frame.state().get('selection').first().toJSON();
// Salva ID e URL
$('#image_id').val(attachment.id);
$('#image_url').val(attachment.url);
// Scegli una dimensione più piccola se disponibile
const previewUrl =
attachment.sizes && attachment.sizes.thumbnail
? attachment.sizes.thumbnail.url
: attachment.url;
$('#image_preview').html(
'<img src="' + previewUrl + '" style="max-width:200px;height:auto;display:block;" alt="">'
);
});
frame.open();
});
});
Cosa ottieni dall’attachment
Il metodo .toJSON() restituisce un oggetto con molte proprietà utili, tra cui:
id: ID dell’attachment;url: URL del file;sizes: sotto-oggetto con le varie dimensioni generate (thumbnail, medium, large, ecc., se esistono).
In genere è consigliabile salvare l’ID nel database e derivare l’URL lato PHP quando serve, così se l’URL cambia (migrazione dominio, rigenerazione), il riferimento resta valido.
Anteprima dell’immagine scelta tramite upload (input type="file")
Se invece l’utente carica un file dal computer, puoi mostrare una preview immediata prima di inviare il form. Questa preview è client-side: l’immagine non è ancora salvata nella Media Library finché non invii e gestisci l’upload lato server.
jQuery(function ($) {
$(document).on('change', '#image_upload', function () {
const file = this.files && this.files[0];
// Nessun file selezionato: pulisci la preview
if (!file) {
$('#image_preview').empty();
return;
}
// Controllo tipo (consigliato)
if (!file.type || !file.type.startsWith('image/')) {
alert('Seleziona un file immagine valido.');
$(this).val('');
$('#image_preview').empty();
return;
}
const reader = new FileReader();
reader.onload = function (e) {
$('#image_preview').html(
'<img src="' + e.target.result + '" style="max-width:200px;height:auto;display:block;" alt="">'
);
};
reader.readAsDataURL(file);
});
});
Perché FileReader
FileReader legge il file selezionato e lo converte in un Data URL utilizzabile come src di un tag img. In questo modo hai una preview istantanea senza fare upload preliminari.
Rimozione/Reset della selezione e della preview
Spesso serve un pulsante per ripulire i campi (sia per Media Library che per upload). Ecco un esempio:
<button type="button" class="button" id="remove_image">
Rimuovi immagine
</button>
jQuery(function ($) {
$(document).on('click', '#remove_image', function () {
$('#image_id').val('');
$('#image_url').val('');
$('#image_upload').val('');
$('#image_preview').empty();
});
});
Consigli pratici
- Event delegation in modali: se la modale ricrea il DOM, lega gli eventi su
documento su un wrapper stabile. - Salva l’ID, non l’URL: per immagini selezionate dalla Media Library, l’ID è più robusto.
- Gestisci conflitti: se l’utente seleziona dalla Media Library e poi fa upload, definisci una regola (ad esempio: l’upload sovrascrive ID/URL; oppure disabilita uno dei due percorsi quando l’altro è attivo).
- Validazioni: per upload, puoi aggiungere controllo su dimensione massima (byte) e, se serve, dimensioni in pixel (caricando l’immagine in memoria).
Riepilogo
Con wp_enqueue_media() e wp.media puoi integrare rapidamente la selezione dalla Media Library anche in una pagina admin personalizzata. In parallelo, con FileReader puoi fornire un’anteprima immediata per i file caricati tramite input. Entrambe le soluzioni funzionano bene in una modale, purché gestisci correttamente gli eventi e lo stato del form.