Como usar theme.json para estilos y presets desde PHP y JS en WordPress

Este artículo explica en profundidad cómo usar theme.json para definir estilos y presets en WordPress y cómo trabajar con esos valores desde PHP y JavaScript. Verás la estructura de theme.json, ejemplos prácticos, cómo exponer presets al editor y al front-end desde PHP, y cómo consumirlos desde JS para registrar estilos, paletas y variaciones dinámicas. Incluye fragmentos de código listos para copiar y adaptar (los ejemplos están en su propia etiqueta pre tal como pides).

Contents

Resumen rápido: qué hace theme.json

theme.json es el sistema central de WordPress (block editor / Full Site Editing) para declarar presets (paletas de color, tamaños de fuente, espacios, etc.) y estilos globales que afectan tanto al editor de bloques como al front-end. Cuando defines presets en theme.json, WordPress genera variables CSS (custom properties) y configura el editor para usar esas opciones.

Estructura básica de theme.json

Un theme.json moderno (version 2 o superior) tiene dos ramas principales: settings y styles. En settings defines presets y comportamientos en styles defines CSS por defecto usando las variables.

Ejemplo mínimo de theme.json

{
  version: 2,
  settings: {
    color: {
      palette: [
        { slug: primary, color: #0073aa, name: Primary },
        { slug: accent,  color: #ffb900, name: Accent },
        { slug: background, color: #ffffff, name: Background }
      ],
      custom: true
    },
    typography: {
      fontSizes: [
        { slug: small, size: 13px, name: Small },
        { slug: normal, size: 16px, name: Normal },
        { slug: large, size: 32px, name: Large }
      ]
    },
    spacing: {
      blockGap: 1.25rem
    }
  },
  styles: {
    root: {
      color: { text: var(--wp--preset--color--primary) },
      typography: { fontSize: var(--wp--preset--font-size--normal) }
    }
  }
}

Cómo exponer y extender presets desde PHP

Aunque theme.json se carga automáticamente desde la carpeta raíz o desde /config/theme.json, a menudo necesitas manipular o reutilizar esos datos en tiempo de ejecución (por ejemplo, para generar CSS dinámico, registrar soporte clásico o pasar datos al editor JS). El flujo habitual es:

  1. Leer y decodificar el JSON desde PHP.
  2. Generar variables CSS o llamadas a add_theme_support si necesitas compatibilidad con APIs antiguas.
  3. Pasar los presets al script del editor mediante wp_localize_script o wp_add_inline_script para que JS pueda registrar estilos o actualizar ajustes.

Ejemplo: Leer theme.json y generar variables CSS (front-end y editor)


Ejemplo: Registrar editor-color-palette desde PHP usando los datos de theme.json

Para compatibilidad con APIs previas a theme.json (o para code paths que aún leen add_theme_support), puedes reconstruir la paleta y llamar add_theme_support en after_setup_theme.

 p[name] ?? p[slug],
                slug  => p[slug],
                color => p[color],
            )
        }
    }

    if ( ! empty( support_palette ) ) {
        add_theme_support( editor-color-palette, support_palette )
    }
}
?>

Cómo consumir presets desde JS en el editor

En el editor de bloques (Gutenberg) puedes usar los presets para:

  • Registrar variaciones de bloque (block styles) que usan las clases o utilidades de preset.
  • Actualizar la configuración del editor (por ejemplo, la paleta visible) mediante la store core/block-editor o los métodos disponibles en la librería de bloques.

Patrón recomendado para pasar datos de PHP a JS

Encola un script para el editor y pasa los datos (por ejemplo, settings o partes del theme.json) con wp_localize_script o con wp_add_inline_script (como un objeto JS global). Así evitas lecturas de archivos desde JS y mantienes la fuente única de verdad (theme.json).


Ejemplo de JavaScript en el editor que usa MI_TEMA_PRESETS

( function ( wp ) {
    const presets = window.MI_TEMA_PRESETS  {}
    const palette = ( presets.color  presets.color.palette ) ? presets.color.palette : []
    const fontSizes = ( presets.typography  presets.typography.fontSizes ) ? presets.typography.fontSizes : []

    wp.domReady( function () {
        // 1) Registrar block styles por cada color (como ejemplo)
        if ( wp.blocks  wp.blocks.registerBlockStyle ) {
            palette.forEach( function ( color ) {
                if ( color.slug ) {
                    wp.blocks.registerBlockStyle( core/heading, {
                        name: has-   color.slug   -color,
                        label: Color    ( color.name  color.slug )
                    } )
                }
            } )
        }

        // 2) Actualizar la paleta del editor en tiempo de ejecución
        if ( wp.data  wp.data.dispatch ) {
            const colorsForEditor = palette.map( function (c) {
                return { name: c.name  c.slug, slug: c.slug, color: c.color }
            } )

            // core/block-editor store expone updateSettings (nota: comprobar disponibilidad según WP)
            try {
                wp.data.dispatch( core/block-editor ).updateSettings( {
                    colors: colorsForEditor
                } )
            } catch (e) {
                // Fallback: puede que en versiones antiguas la store sea diferente.
                // No lanzar errores visibles en producción.
            }
        }
    } )
} )( window.wp )

Ejemplos de uso práctico

  • Generar utilidades CSS: crear clases .has-primary-background usando la variable –wp–preset–color–primary y añadir esas utilidades automáticamente en el CSS inline generado por PHP.
  • Registrar estilos de bloque automáticos: basándote en la paleta, registrar block styles para heading, button, cover, etc.
  • Sincronizar configuraciones: pasar la misma paleta a un panel de opciones personalizado en el editor para que el usuario vea y seleccione exactamente los presets disponibles.

Buenas prácticas y consideraciones

  1. Sanitizar y validar: cuando leas theme.json con PHP, valida la estructura antes de usarla (existencia de claves, tipos). Evita evaluar contenido sin control.
  2. Cachear lecturas: si tu theme.json es grande o haces muchas lecturas, cachea la decodificación con transients o variables estáticas para no leer archivos en cada request.
  3. Compatibilidad: theme.json se introdujo y evolucionó en versiones recientes de WP. Comprueba la versión mínima del CMS y proporciona fallbacks (por ejemplo add_theme_support) para compatibilidad con instalaciones anteriores.
  4. Variables CSS: usa siempre las variables generadas (–wp–preset–…) en tus estilos para mantener consistencia entre editor y front-end.
  5. Evita duplicidad: no declares presets contradictorios entre theme.json y add_theme_support. Si generas add_theme_support dinámicamente, hazlo a partir del theme.json para mantener una única fuente de verdad.
  6. Seguridad: al exponer datos con wp_localize_script, pasa solo lo necesario (por ejemplo settings[color][palette]) para reducir superficie de datos innecesarios.

Pequeño checklist para implementar en un tema

  1. Crear /config/theme.json con presets y estilos globales.
  2. En PHP leer y validar theme.json en after_setup_theme o en hooks de cola para generar variables CSS y compatibilidad legacy.
  3. Inyectar variables CSS con wp_add_inline_style para front-end y editor.
  4. Pasar presets importantes al editor con wp_localize_script o wp_add_inline_script.
  5. En JS, registrar block styles o actualizar settings con los presets recibidos.
  6. Probar: editor (Gutenberg) y front-end para asegurar coincidencia visual.

Conclusión

theme.json es la fuente central para presets y estilos en el ecosistema moderno de WordPress. Combinar su definición estática con pequeñas capas dinámicas en PHP y JS te permite tener un control total: generar variables CSS para el front-end, registrar compatibilidades antiguas con add_theme_support y enriquecer la experiencia del editor registrando estilos y configuraciones en tiempo de ejecución. Sigue buenas prácticas de validación y cacheo y mantén una única fuente de verdad (tu theme.json) para evitar conflictos.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

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