Tutorial WordPress: Convertir imágenes del post en figuras con pie (figcaption) estilizado

·

·

Introducción

Este tutorial explica, paso a paso y con todo lujo de detalles, cómo convertir las imágenes insertadas en las entradas de WordPress en elementos semánticos figure con su correspondiente figcaption estilizado. La solución que propongo es segura, compatible con imágenes enlazadas, respeta clases de alineación y aprovecha la información de la propia librería de medios (caption / alt). Incluye el código PHP que puedes añadir en tu theme (functions.php) o como plugin mu, y también el CSS para estilizar los figcaption.

Por qué hacerlo

Descripción general de la técnica

La idea principal es interceptar el contenido de la entrada con el filtro the_content, procesar el HTML y convertir cada ltimggt (o su enlace padre ltagt) en un ltfiguregt que contenga la imagen y un ltfigcaptiongt con la leyenda. La leyenda se obtiene, en este orden de prioridad:

  1. La caption (extracto) del attachment en la biblioteca de medios (wp_get_attachment_caption / post_excerpt).
  2. Si no existe, el atributo alt de la etiqueta ltimggt.
  3. Si no hay nada, se omite el ltfigcaptiongt.

Consideraciones y buenas prácticas

Implementación PHP (recomendada)

Sigue este fragmento y pégalo en el functions.php de tu child theme o crea un pequeño plugin (MU plugin recomendado si quieres que se aplique aunque cambies de tema).

lt?php
/
  Wrap post images in ltfiguregt with ltfigcaptiongt.
  Put this code in your child themes functions.php or in a small plugin.
 /
function wp_wrap_post_images_with_figures( content ) {
    // Only run on front-end single posts/pages skip admin, feeds and previews.
    if ( is_admin()  is_feed()  is_preview() ) {
        return content
    }

    // Avoid breaking when content is empty
    if ( empty( content ) ) {
        return content
    }

    // Use internal errors to suppress warnings from malformed HTML
    libxml_use_internal_errors( true )

    dom = new DOMDocument()

    // Ensure proper encoding
    loaded = dom->loadHTML( mb_convert_encoding( content, HTML-ENTITIES, UTF-8 ), LIBXML_HTML_NOIMPLIED  LIBXML_HTML_NODEFDTD )
    if ( ! loaded ) {
        libxml_clear_errors()
        return content
    }

    imgs = dom->getElementsByTagName( img )

    // Iterate backwards because NodeList is live
    for ( i = imgs->length - 1 i >= 0 i-- ) {
        img = imgs->item( i )

        // Skip if no src attribute
        src = img->getAttribute( src )
        if ( empty( src ) ) {
            continue
        }

        // If image already inside a 
, skip ancestor = img->parentNode in_figure = false wrap_node = img // node to be wrapped (img or its parent anchor) while ( ancestor ) { if ( ancestor->nodeName === figure ) { in_figure = true break } if ( ancestor->nodeName === a ) { // Prefer wrapping the anchor so link behavior remains intact wrap_node = ancestor } ancestor = ancestor->parentNode } if ( in_figure ) { continue } // Try to find attachment id from URL attachment_id = attachment_url_to_postid( src ) // Prefer the attachment caption (WP stores caption in post_excerpt) caption = if ( attachment_id ) { // wp_get_attachment_caption is available in modern WP versions if ( function_exists( wp_get_attachment_caption ) ) { caption = wp_get_attachment_caption( attachment_id ) } if ( empty( caption ) ) { att_post = get_post( attachment_id ) if ( att_post ! empty( att_post->post_excerpt ) ) { caption = att_post->post_excerpt } } } // Fallback to alt attribute if ( empty( caption ) ) { caption = img->getAttribute( alt ) } // Create a
element figure = dom->createElement( figure ) // Copy alignment classes from the image (if any) img_class = img->getAttribute( class ) figure_classes = array( wp-caption ) // base class if ( img_class ) { // detect alignleft, alignright, aligncenter, alignnone if ( preg_match( /(alignleftalignrightaligncenteralignnone)/, img_class, m ) ) { figure_classes[] = m[1] } // Optionally preserve other classes if you want: uncomment next line // figure_classes[] = img_class } figure->setAttribute( class, implode( , array_unique( figure_classes ) ) ) // Clone the node to wrap (deep clone to include children / attributes) cloned = wrap_node->cloneNode( true ) figure->appendChild( cloned ) // Append figcaption if we have text if ( ! empty( caption ) ) { // Create figcaption element and ensure the text is treated as text figcap = dom->createElement( figcaption ) figcap->setAttribute( class, wp-caption-text ) figcap->appendChild( dom->createTextNode( html_entity_decode( caption, ENT_QUOTES ENT_HTML5, UTF-8 ) ) ) figure->appendChild( figcap ) } // Replace the original node with the new
wrap_node->parentNode->replaceChild( figure, wrap_node ) } // Get the HTML back (without adding html/body) html = dom->saveHTML() libxml_clear_errors() return html } add_filter( the_content, wp_wrap_post_images_with_figures, 20 ) ?gt

Notas sobre el código PHP

CSS para estilizar figure y figcaption

A continuación tienes un CSS de ejemplo para que las figuras y las leyendas se vean bien en la mayoría de temas y sean responsive.

/ Estilos básicos para figure   figcaption /
figure.wp-caption {
    display: block
    margin: 1.25em 0
    line-height: 1.2
    width: auto
}

figure.wp-caption img {
    display: block
    max-width: 100%
    height: auto
    margin: 0 auto
}

/ Alineaciones clásicas que muchos themes usan /
figure.wp-caption.alignleft {
    float: left
    margin-right: 1.25em
    margin-left: 0
    max-width: 50%
}

figure.wp-caption.alignright {
    float: right
    margin-left: 1.25em
    margin-right: 0
    max-width: 50%
}

figure.wp-caption.aligncenter {
    margin-left: auto
    margin-right: auto
    text-align: center
}

/ Figcaption: tipografía y apariencia /
figure.wp-caption .wp-caption-text {
    margin-top: 0.45em
    color: #555
    font-size: 0.95rem
    line-height: 1.3
    background: rgba(0,0,0,0.02)
    padding: 0.35em 0.6em
    border-radius: 3px
}

/ Ajustes para dispositivos pequeños /
@media (max-width: 640px) {
    figure.wp-caption.alignleft,
    figure.wp-caption.alignright {
        float: none
        display: block
        margin-left: auto
        margin-right: auto
        max-width: 100%
    }
}

Alternativas y casos especiales

Gutenberg (Block Editor)

El editor por bloques suele generar ya estructuras ltfigure class=wp-block-imagegt con ltfigcaptiongt. Para evitar conflictos, el script propuesto solo actúa en el contenido final y detecta si la imagen ya está dentro de un ltfiguregt — en ese caso no hace nada. Si necesitas un comportamiento específico para bloques, valora crear un bloque personalizado o aplicar estilos globales a .wp-block-image figcaption.

Galerías

Evitar duplicados y compatibilidad

Si ya tienes plugins o el tema que insertan figuras, evita activar al mismo tiempo dos procesos que hagan exactamente lo mismo. Siempre prueba en un entorno de staging antes de activarlo en producción.

Cómo empaquetarlo como plugin MU (opcional)

Si prefieres que la funcionalidad no dependa del tema, crea un archivo PHP en wp-content/mu-plugins/ por ejemplo mu-figure-captions.php con cabecera mínima. Ejemplo de cabecera (usa en archivo real, sin lt?phpgt duplicado):

lt?php
/
  Plugin Name: MU - Convert Images to Figures with Captions
  Description: Envuelve imágenes del contenido en ltfiguregt y añade ltfigcaptiongt con la caption del attachment o el atributo alt.
  Version: 1.0
  Author: Tu Nombre
 /
// (Pega aquí la función wp_wrap_post_images_with_figures y el add_filter)
?gt

Pruebas recomendadas antes de publicar

  1. Realiza una copia de seguridad completa del sitio.
  2. Prueba en un entorno de desarrollo o staging.
  3. Verifica entradas que contengan: imágenes sueltas, imágenes dentro de enlace, imágenes con srcset, galerías y bloques de Gutenberg.
  4. Comprueba que no se dupliquen captions ni que se introduzcan caracteres HTML inesperados.
  5. Revisa la apariencia en móviles y escritorio.

Conclusión

Convertir las imágenes de tus posts en ltfiguregt con ltfigcaptiongt mejora la semántica, la accesibilidad y te permite controlar el estilo de las leyendas de forma centralizada. La solución presentada usa DOMDocument para manipular el HTML de forma segura, respeta enlaces y clases de alineación, y toma la caption desde la librería de medios cuando existe. Integra el PHP en tu theme o como plugin MU y añade el CSS propuesto para obtener un resultado visual consistente.

Fin del tutorial



Leave a Reply

Your email address will not be published. Required fields are marked *