WordPress backend: selezione dalla Media Library e anteprima per upload

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.media sia caricato (in PHP con wp_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_id memorizza l’ID dell’attachment (utile per salvare riferimenti stabili);
  • #image_url conserva l’URL (utile per debug o per usi immediati);
  • #image_upload gestisce l’upload dal computer;
  • #image_preview è il contenitore dell’anteprima (in questo esempio usiamo un p vuoto, senza div).

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 document o 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.

Torna su