Tutorial WordPress: Crear un layout de snippets de código con copy y estilo monokai (CSS)

·

·

Introducción

Este tutorial explica, con todo lujo de detalles, cómo crear en WordPress un layout de snippets de código con un botón de copiar y estilo Monokai (CSS). El resultado: bloques de código visualmente atractivos, con resaltado de sintaxis mediante EnlighterJS y un botón para copiar al portapapeles. Incluye el código listo para pegar en functions.php, CSS personalizado, y el JavaScript necesario para la funcionalidad de copiar.

Requisitos previos

Resumen del flujo

  1. Encolar los assets de Enlighter (si no se usa el plugin) y añadir un CSS personalizado con estilo Monokai.
  2. Crear un shortcode que genere el layout del snippet: cabecera con botón Copiar y el bloque
     para el resaltado.
  3. Añadir el JavaScript que realiza la copia al portapapeles y muestra retroalimentación visual.
  4. Personalizar el CSS para lograr el aspecto Monokai y estilos del botón.

1) Encolar assets y registrar shortcode (functions.php)

Insertar en el archivo functions.php del tema hijo este bloque. Explicación: se encolan los ficheros CSS/JS (si no se usa el plugin, aquí es donde enlazarás Enlighter), se registra un script con la funcionalidad de copia y se crea un shortcode [snippet] que imprime la estructura HTML del bloque.

/
  Añadir assets y shortcode para snippets con botón copiar y EnlighterJS
 /
function tema_enlighter_snippets_assets() {
    // Encolar CSS Monokai personalizado
    wp_enqueue_style( snippets-monokai, get_stylesheet_directory_uri() . /css/snippets-monokai.css, array(), 1.0 )

    // Enlighter: si usas el plugin quizá ya carga sus propios assets. Si no, encola aquí los de Enlighter.
    // wp_enqueue_style( enlighter-css, get_stylesheet_directory_uri() . /vendor/enlighter/enlighter.min.css, array(), 1.0 )
    // wp_enqueue_script( enlighter-js, get_stylesheet_directory_uri() . /vendor/enlighter/enlighter.min.js, array(), 1.0, true )

    // Script para el botón copiar
    wp_enqueue_script( snippets-copy, get_stylesheet_directory_uri() . /js/snippets-copy.js, array(), 1.0, true )

    // Localizar datos si hace falta
    wp_localize_script( snippets-copy, SnippetsCopyData, array(
        copiedText => Copiado,
        copyText   => Copiar
    ) )
}
add_action( wp_enqueue_scripts, tema_enlighter_snippets_assets )

/
  Shortcode [snippet language=js title=Ejemplo]...codigo...[/snippet]
 /
function tema_snippet_shortcode( atts, content = null ) {
    atts = shortcode_atts( array(
        language => text,
        title    => ,
        copy     => true,
        id       => snippet- . wp_rand(1000, 9999),
    ), atts, snippet )

    // Escapar atributos básicos
    lang = esc_attr( atts[language] )
    title = esc_html( atts[title] )
    copy = filter_var( atts[copy], FILTER_VALIDATE_BOOLEAN ) ? true : false
    id = esc_attr( atts[id] )

    // Normalizar contenido: no aplicar autop ni otros filtros que rompan el código
    code = trim( content )
    code = htmlspecialchars( code, ENT_QUOTES, UTF-8 )

    // Estructura del snippet: un encabezado con título y botón copiar, y el pre para Enlighter
    ob_start()
    ?>
    
>
>
>

Notas sobre el shortcode

  • Usa [snippet language=php title=Mi ejemplo]...codigo...[/snippet] dentro del editor (texto) o en bloques HTML personalizados.
  • El contenido del snippet se escapa para evitar inyección Enlighter deberá procesar el
     con la clase EnlighterJSRAW.
  • Si usas el editor de bloques, emplea un bloque HTML personalizado para pegar el shortcode con el código crudo, o activa el modo Texto en el editor clásico.

2) JavaScript: funcionalidad de copiar

Este script busca enlaces con la clase .snippet-copy, ubica el

 dentro del wrapper y copia su contenido al portapapeles. También muestra texto temporal Copiado. Guarda este JS en /js/snippets-copy.js o donde encolas en functions.php.

document.addEventListener(click, function (e) {
    var el = e.target
    if (el.matches  el.matches(.snippet-copy)) {
        e.preventDefault()
        var targetId = el.getAttribute(data-target)
        var wrapper = document.getElementById(targetId)
        if (!wrapper) return

        // Buscar el primer pre dentro del wrapper
        var pre = wrapper.querySelector(pre.EnlighterJSRAW)
        if (!pre) return

        // Obtener texto sin etiquetas HTML
        var text = pre.innerText  pre.textContent

        // Copiar: usar navigator.clipboard si está disponible
        if (navigator.clipboard  navigator.clipboard.writeText) {
            navigator.clipboard.writeText(text).then(function () {
                showCopied(el)
            }).catch(function () {
                fallbackCopy(text, el)
            })
        } else {
            fallbackCopy(text, el)
        }
    }
})

// Fallback de copia clásico
function fallbackCopy(text, triggerEl) {
    var textarea = document.createElement(textarea)
    textarea.value = text
    textarea.setAttribute(readonly, )
    textarea.style.position = absolute
    textarea.style.left = -9999px
    document.body.appendChild(textarea)
    textarea.select()
    try {
        document.execCommand(copy)
        showCopied(triggerEl)
    } catch (err) {
        // No mostrar error en producción opcionalmente informar
    }
    document.body.removeChild(textarea)
}

// Mostrar estado Copiado temporalmente
function showCopied(el) {
    var original = el.textContent
    el.textContent = (typeof SnippetsCopyData !== undefined  SnippetsCopyData.copiedText) ? SnippetsCopyData.copiedText : Copiado
    el.classList.add(copied)
    setTimeout(function () {
        el.textContent = (typeof SnippetsCopyData !== undefined  SnippetsCopyData.copyText) ? SnippetsCopyData.copyText : original
        el.classList.remove(copied)
    }, 1500)
}

3) CSS: estilo Monokai y diseño del layout

Este CSS aplica la paleta Monokai al bloque de código y da estilo al encabezado y al botón copiar. Guarda este CSS en /css/snippets-monokai.css.

/ snippets-monokai.css - Estilos principales /
.snippet-wrapper {
    margin: 1.2em 0
    border-radius: 6px
    overflow: hidden
    box-shadow: 0 2px 6px rgba(0,0,0,0.2)
    font-family: Fira Code, Source Code Pro, Consolas, monospace
}

/ Header superior opcional /
.snippet-header {
    display: flex
    justify-content: space-between
    align-items: center
    background: #272822 / oscuro base Monokai /
    color: #f8f8f2
    padding: 0.45em 0.6em
    font-size: 0.95em
    border-bottom: 1px solid rgba(255,255,255,0.03)
}
.snippet-title {
    font-weight: 600
}

/ Botón copiar como enlace /
.snippet-copy {
    display: inline-block
    text-decoration: none
    background: linear-gradient(#66d9ef, #4fb0c8)
    color: #272822
    padding: 0.28em 0.6em
    border-radius: 4px
    font-size: 0.85em
    font-weight: 700
    margin-left: 0.5em
}
.snippet-copy.copied {
    background: linear-gradient(#a6e22e, #8bc31a)
    color: #272822
}

/ Pre y monokai colors -- puedes ajustar según el motor de Enlighter /
pre.EnlighterJSRAW {
    margin: 0
    padding: 1em
    background: #272822
    color: #f8f8f2
    overflow: auto
    font-size: 0.95em
    line-height: 1.5
}

/ Ejemplo de tokens, algunos plugins aplican sus propias clases /
.EnlighterJSRAW .enlighter-keyword { color: #f92672 }   / rosa /
.EnlighterJSRAW .enlighter-string  { color: #e6db74 }   / amarillo /
.EnlighterJSRAW .enlighter-comment { color: #75715e font-style: italic } / comentario /
.EnlighterJSRAW .enlighter-number  { color: #ae81ff }   / morado /
/ Continúa ajustando según tus necesidades /

4) Ejemplos de uso en entradas o páginas

Ejemplo básico mostrando HTML con el shortcode. En el editor pega esto en modo texto/HTML.

[snippet language=html title=Ejemplo HTML]

  
    
    Ejemplo
  
  
    

Hola mundo

[/snippet]

Ejemplo mostrando PHP (usa en archivos o en el editor en modo texto):

[snippet language=php title=Funciones PHP][/snippet]

5) Integración con EnlighterJS

Si estás usando el plugin Enlighter, normalmente detectará y procesará automáticamente las etiquetas ltpre class=EnlighterJSRAW data-enlighter-language=...gt. Si no se aplica el resaltado, asegúrate de:

  • Que el plugin esté activo o que hayas incluido sus ficheros .css/.js.
  • Que la clase y el atributo data-enlighter-language se respeten exactamente.
  • Que no se filtre o modifique el contenido del pre por otros plugins (desactiva temporalmente cortesía de pruebas).

6) Consejos de robustez y seguridad

  • Escapa siempre el contenido para evitar inyección de HTML/JS: en el ejemplo se usa htmlspecialchars antes de devolver el pre.
  • Si aceptas snippets de usuarios, considera sanitizar y limitar la longitud para evitar abusos.
  • Si el sitio soporta AMP u otros sistemas que limitan scripts, adapta la funcionalidad de copiar a ese contexto o deja la opción sin script.

7) Personalizaciones avanzadas

  • Puedes añadir un selector de tema para cambiar entre Monokai y otros temas. Solo cambia las clases del wrapper y carga otro CSS.
  • Añadir números de línea: Enlighter y otros resaltadores ofrecen opciones para numeración. Activa la opción del plugin o añade la clase correspondiente al pre.
  • Soporte para múltiples botones (copiar, abrir en JSFiddle, descargar .txt): añade más enlaces en la cabecera y funciones JS que preparen el contenido.

8) Solución de problemas comunes

  1. El resaltado no se aplica: confirma que Enlighter está cargado y no hay conflictos de nombres en las clases.
  2. El botón no copia: revisa que el archivo snippets-copy.js esté encolado y que no haya CSP que bloquee navigator.clipboard.
  3. El código aparece con entidades HTML (lt, gt): eso es correcto y necesario para mostrar código. Enlighter usa el contenido textual del pre para resaltar.

Ejemplo final completo (réplica rápida)

Resumen mínimo de qué pegar: functions.php snippets-copy.js snippets-monokai.css usar el shortcode en tus entradas. Con esto obtendrás un layout de snippets con botón copiar y aspecto Monokai listo para producción.

Fuentes y referencias



Leave a Reply

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