Contents
Introducción
Un bloque renderizado en servidor (server-rendered block) en WordPress es un bloque cuyo marcado HTML final se genera en PHP cuando se carga la página o se obtiene el contenido, en lugar de generarlo totalmente en el editor con JavaScript. Esto permite combinar datos dinámicos del servidor, ejecutar lógica compleja, aplicar sanitización estricta y controlar rendimiento (caché) desde PHP. En este artículo se explican con todo detalle los pasos para crear un bloque que utiliza render_callback en PHP, ejemplos completos de código, buenas prácticas de seguridad y rendimiento, y cómo empaquetarlo como plugin.
Requisitos previos
- WordPress 5.0 (recomendado 5.8 para API de bloques moderna).
- Conocimientos básicos de PHP, JavaScript (ESNext), y React/JSX para el editor.
- Acceso al servidor para crear un plugin o los archivos del tema.
- WP_DEBUG activado para depurar (opcional pero recomendado).
Concepto general y flujo
Flujo básico de un bloque con render_callback:
- Se registra el bloque (block.json script del editor y estilos).
- En el editor, el bloque muestra controles y permite editar atributos.
- Los atributos se guardan en el contenido (serialized dentro del comentario del bloque).
- En el front-end (o en REST cuando se solicita), WordPress llama a la función render_callback en PHP, que recibe los atributos y devuelve el HTML final del bloque.
Estructura recomendada del plugin / bloque
Archivo / Carpeta | Descripción |
my-dynamic-block/ | Carpeta raíz del plugin |
my-dynamic-block/block.json | Metadatos del bloque |
my-dynamic-block/src/index.js | Script del editor (JS/React) |
my-dynamic-block/src/editor.css | Estilos para el editor |
my-dynamic-block/src/style.css | Estilos para el front-end |
my-dynamic-block/my-dynamic-block.php | Archivo principal del plugin con register_block_type y render_callback |
Paso 1 — block.json (metadatos)
Ejemplo minimalista de block.json para un bloque que renderiza en servidor. Define atributos y los scripts/estilos que se usan.
{ apiVersion: 2, name: mi-plugin/testimonial-dynamic, title: Testimonial Dinámico, category: widgets, icon: format-quote, description: Un testimonio renderizado en servidor con render_callback., attributes: { quote: { type: string, source: html, selector: .testimonial-quote }, author: { type: string, source: text, selector: .testimonial-author } }, editorScript: file:./build/index.js, editorStyle: file:./build/editor.css, style: file:./build/style.css }
Paso 2 — Script del editor (src/index.js)
En el editor utilizamos componentes de RichText y guardamos atributos. La versión save devuelve null (o no se declara), porque el HTML lo produce PHP en render_callback. Para la mayoría de bloques dinámicos con API v2, save debe devolver null.
import { registerBlockType } from @wordpress/blocks import { RichText, InspectorControls } from @wordpress/block-editor import { PanelBody, TextControl } from @wordpress/components import { __ } from @wordpress/i18n registerBlockType( mi-plugin/testimonial-dynamic, { edit: ( props ) => { const { attributes, setAttributes } = props const { quote = , author = } = attributes return () }, save: () => { // Save en server: devolver null hace que WP use render_callback en PHP return null }, } )setAttributes( { author: value } ) } /> setAttributes( { quote: value } ) } placeholder={ __( Escribe el testimonio..., mi-plugin ) } /> setAttributes( { author: value } ) } placeholder={ __( Autor, mi-plugin ) } />
Paso 3 — Archivo principal del plugin y render_callback (PHP)
Registro del bloque y definición de la función que genera el HTML final. Aquí se muestra un plugin simple que registra el bloque leyendo block.json y pasando la función de render.
mi_testimonial_dynamic_render_callback, ) ) } add_action( init, mi_testimonial_dynamic_register_block ) / Función de renderizado en servidor. @param array attributes Atributos del bloque. @param string content Contenido en bruto (no siempre presente). @return string HTML final del bloque. / function mi_testimonial_dynamic_render_callback( attributes, content ) { // Atributos por defecto defaults = array( quote => , author => , ) atts = wp_parse_args( attributes, defaults ) // Saneamiento de atributos (evitar XSS) quote = isset( atts[quote] ) ? wp_kses_post( atts[quote] ) : author = isset( atts[author] ) ? sanitize_text_field( atts[author] ) : // Si no hay contenido útil, devolver vacío para evitar output innecesario if ( empty( trim( wp_strip_all_tags( quote ) ) ) ) { return } // Construcción del HTML con escapado correcto html = return html }
Notas sobre el registro con register_block_type vs register_block_type_from_metadata
En el ejemplo anterior se usa register_block_type pasando la ruta al block.json, que funciona con las versiones modernas de WordPress y en muchos contextos. También puedes usar register_block_type_from_metadata si quieres comportamientos específicos. Lo esencial es que la función PHP pase la opción render_callback para indicar que el bloque es dinámico y su output lo genera PHP.
Seguridad y saneamiento
- wp_kses_post() o wp_kses() para permitir HTML seguro en atributos que contienen HTML (por ejemplo, quote).
- sanitize_text_field() o esc_html() para datos simples de texto (p. ej. autor).
- Evitar concatenar atributos sin escapar. Usar esc_attr(), esc_url() según corresponda.
- Validar atributos esperados y establecer valores por defecto con wp_parse_args.
Encolado de estilos y scripts
Si utilizas block.json y build con @wordpress/scripts, WordPress registrará y encolará los assets correctamente cuando uses register_block_type con la ruta a block.json. Si no, puedes registrar estilos manualmente en PHP y pasarlos en register_block_type.
function mi_testimonial_register_assets() { dir = plugin_dir_url( __FILE__ ) wp_register_style( mi-testimonial-style, dir . build/style.css, array(), filemtime( plugin_dir_path( __FILE__ ) . build/style.css ) ) wp_register_style( mi-testimonial-editor-style, dir . build/editor.css, array( wp-edit-blocks ), filemtime( plugin_dir_path( __FILE__ ) . build/editor.css ) ) register_block_type( __DIR__ . /block.json, array( render_callback => mi_testimonial_dynamic_render_callback, style => mi-testimonial-style, editor_style => mi-testimonial-editor-style, ) ) } add_action( init, mi_testimonial_register_assets )
Ejemplo avanzado: datos dinámicos del servidor y cache con transients
Si tu bloque consulta datos costosos (p. ej. una API externa o WP_Query complejo), guarda resultados en transients para mejorar rendimiento y evitar cálculo en cada solicitud.
function mi_testimonial_dynamic_render_callback( attributes ) { cache_key = mi_testimonial_html_ . md5( serialize( attributes ) ) cached = get_transient( cache_key ) if ( cached ) { return cached } // Ejemplo: consulta de datos costosa (simulada) quote_html =. wp_kses_post( attributes[quote] ) .author_html = ! empty( attributes[author] ) ? : html = // Guardar en transient por 1 hora set_transient( cache_key, html, HOUR_IN_SECONDS ) return html }
Depuración y pruebas
- Activa WP_DEBUG y WP_DEBUG_LOG para ver errores en el archivo debug.log.
- Usa error_log() en la función PHP para comprobar valores de atributos en tiempo de renderizado (temporalmente).
- Comprueba en el editor que al editar y guardar los atributos se reflejan correctamente en el HTML generado en front.
- Si usas build con @wordpress/scripts, abre la consola del navegador para ver errores de JS en el editor.
Buenas prácticas
- Usa atributos simples y evita guardar HTML complejo en atributos si puedes en su lugar, genera HTML en PHP usando los datos guardados.
- Sanitiza siempre en PHP: editar en el navegador no sustituye el saneamiento del servidor.
- Considera la accesibilidad: roles ARIA, etiquetas semánticas y estructura HTML adecuada.
- Si el bloque es público y presenta datos externos, planifica una estrategia de cache y invalidación (transients, cache de objeto, etc.).
Resumen técnico
Crear un bloque que renderiza en servidor con render_callback implica:
- Definir la metadata del bloque en block.json (atributos, scripts, estilos).
- Crear el script del editor en JavaScript que permita editar atributos y devolver null en save().
- Registrar el bloque en PHP y proporcionar la función render_callback que genere el HTML final.
- Saneamiento en PHP con wp_kses_post, sanitize_text_field, esc_html, esc_url, etc.
- Considerar encolado de assets, rendimiento (cache) y pruebas en entornos con WP_DEBUG.
Recursos útiles
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |