Contents
Introducción
En WordPress moderno con Gutenberg es muy habitual que los bloques necesiten almacenar información que debe persistir más allá del contenido HTML del bloque. Guardar metadatos de bloques en post_meta permite reutilizar esos valores en plantillas PHP, consultas WP_Query, la API REST y para mantener la lógica del servidor separada del HTML del bloque. Este artículo explica, con ejemplos completos y buenas prácticas, cómo registrar, actualizar y leer meta de bloques en post_meta usando PHP (y el pequeño fragmento de JavaScript necesario en el editor).
Resumen de enfoques
- Registrar la clave de meta en PHP con register_post_meta (o register_meta) y exponerla en REST.
- Declarar el atributo del bloque que utiliza esa meta (ej. en block.json o en el registro del bloque en JS) usando source: meta y meta: mi_meta_key.
- Para bloque dinámico: usar render_callback y leer la meta con get_post_meta.
- Para sincronizar meta desde el contenido del bloque al post_meta en el servidor: usar el hook save_post o parsear bloques en PHP y actualizar con update_post_meta, cuidando autosaves, revisiones y permisos.
1) Registrar la meta en PHP
Antes de intentar leer o escribir meta desde el editor o desde callbacks del servidor, registra la meta para declararle a WordPress tipo, visibilidad en REST y permisos. Ejemplo recomendado:
true, single => true, type => string, sanitize_callback => function( value, post_id, meta_key ) { // Sanitiza según el tipo de dato esperado. return sanitize_text_field( value ) }, auth_callback => function() { // Control de permisos para modificar esta meta (opcional). return current_user_can( edit_posts ) }, ) ) } ) ?>
Notas:
- show_in_rest es esencial si quieres que el editor (Gutenberg) acceda a la meta vía REST/JS.
- single true indica que la meta es un único valor false la convierte en array de valores.
- Provee sanitize_callback y/o auth_callback para seguridad.
2) Declarar atributos del bloque que utilizan meta
Si creas bloques mediante block.json o registro en JS, declara el atributo que obtiene su valor desde meta. Esto hace que Gutenberg lea/escriba automáticamente el valor desde la meta (vía REST) cuando show_in_rest está activado.
Ejemplo en block.json
{ apiVersion: 2, name: miprefix/mi-bloque, title: Mi Bloque, category: widgets, attributes: { miMeta: { type: string, source: meta, meta: mi_meta_bloque } }, editorScript: file:./build/index.js }
Con esto, cuando el editor carga el post, la propiedad miMeta vendrá de la meta mi_meta_bloque y cualquier cambio en el control del editor actualizará esa meta (si el usuario guarda el post).
Ejemplo mínimo en JavaScript (registro del bloque o manejo de atributos)
import { registerBlockType } from @wordpress/blocks import { TextControl } from @wordpress/components import { useBlockProps } from @wordpress/block-editor registerBlockType( miprefix/mi-bloque, { apiVersion: 2, title: Mi Bloque, category: widgets, attributes: { miMeta: { type: string, source: meta, meta: mi_meta_bloque } }, edit: ( { attributes, setAttributes } ) => { const blockProps = useBlockProps() return () }, save: () => { // Si usas source: meta y es un atributo que no debe quedar en el contenido, // normalmente save devuelve null (bloque dynamic) o solo markup necesario. return null }, } )setAttributes( { miMeta: val } ) } />
Importante: source: meta no inyecta datos al HTML del post salvo que lo especifiques en save. Normalmente se prefiere usar bloques dinámicos (render_callback) para mostrar el valor del meta en frontend.
3) Bloque dinámico: render_callback en PHP
Si tu bloque es dinámico puedes usar un callback de render en PHP que lea la meta y genere HTML. Ejemplo:
function( attributes, content, block ) { post_id = get_the_ID() if ( ! post_id ) { return } valor = get_post_meta( post_id, mi_meta_bloque, true ) valor = esc_html( valor ) returnValor meta: {valor}} ) ) ?>
Este método asegura que el HTML mostrado en frontend siempre use la meta almacenada en post_meta.
4) Guardar meta desde PHP analizando los bloques (cuando no confías en sync automática)
Aunque source: meta register_post_meta suele sincronizar, a veces necesitas forzar el guardado (p. ej. valores anidados, migraciones, arreglos de compatibilidad). Una técnica robusta es, en save_post, parsear el contenido para localizar atributos del bloque y actualizar post_meta manualmente.
Ejemplo completo en PHP: parsear bloques y actualizar post_meta
post_content ) found_meta_value = null // Recorrer bloques para encontrar nuestro bloque y su atributo foreach ( blocks as block ) { if ( isset( block[blockName] ) block[blockName] === miprefix/mi-bloque ) { // Atributos del bloque tal y como los declaró el editor (JSON) attrs = isset( block[attrs] ) ? block[attrs] : array() if ( isset( attrs[miMeta] ) ) { found_meta_value = sanitize_text_field( attrs[miMeta] ) break // Si solo hay uno, salir. Ajusta lógica si hay múltiples. } } // Si el bloque es contenedor puede tener innerBlocks recorrer recursivamente si es necesario. if ( ! empty( block[innerBlocks] ) ) { foreach ( block[innerBlocks] as inner ) { if ( isset( inner[blockName] ) inner[blockName] === miprefix/mi-bloque ) { inner_attrs = isset( inner[attrs] ) ? inner[attrs] : array() if ( isset( inner_attrs[miMeta] ) ) { found_meta_value = sanitize_text_field( inner_attrs[miMeta] ) break 2 } } } } } if ( null !== found_meta_value ) { update_post_meta( post_id, mi_meta_bloque, found_meta_value ) } else { // Si quieres limpiar meta cuando no hay bloque, usa delete_post_meta. delete_post_meta( post_id, mi_meta_bloque ) } // Volver a enganchar el hook add_action( save_post, __FUNCTION__, 10, 3 ) }, 10, 3 ) ?>
Consideraciones en este patrón:
- Comprueba wp_is_post_autosave y wp_is_post_revision para no tocar meta en esas operaciones.
- Quita y vuelve a enganchar el hook save_post para evitar bucles si update_post_meta dispara otro save_post por algún motivo.
- Si hay múltiples instancias del bloque, define la política: ¿usar el primero, el último, concatenar valores, almacenar en meta como array (single = false)?
5) Buenas prácticas de seguridad y rendimiento
- Sanitiza siempre: utiliza sanitize_text_field, esc_url_raw, intval, wp_kses_post según el tipo de dato antes de guardar en post_meta.
- Valida permisos: current_user_can( edit_post, post_id ) o un auth_callback en register_post_meta para bloquear peticiones REST sin permiso.
- Evita actualizar meta innecesariamente: comprueba el valor actual con get_post_meta antes de llamar a update_post_meta para reducir escrituras en la base de datos.
- Ten cuidado con autosaves y revisiones: las autosaves no deberían sobreescribir metadatos definitivos a menos que quieras ese comportamiento.
- Indexa meta usada en consultas: si vas a consultar por meta en WP_Query con frecuencia, considera usar claves y formatos que faciliten índices y evalúa rendimiento (post_meta puede crecer rápido).
- Manejo de versiones: si cambias la estructura del atributo, escribe un migrador que convierta meta antigua a nueva.
6) Casos especiales y preguntas frecuentes
¿Qué pasa con revisiones?
Las revisiones tienen sus propias meta si guardas meta en la revisión puede confundir al recuperar datos. Normalmente ignores revisiones (wp_is_post_revision) y guardas meta solo en el post principal. Si quieres que la meta participe en revisiones, tendrás que propagar manualmente el valor a la revisión y restaurarlo al restaurar una revisión.
¿Y si quiero almacenar múltiples valores (arrays)?
Define la meta con single => false o serializa/JSON-encode el array y usa single => true con sanitize_callback adecuado. Si usas REST y quieres arrays, asegúrate de declarar type => array y el schema correcto en register_post_meta.
Compatibilidad con campos personalizados antiguos
Si migras desde custom fields tradicionales, implementa en el proceso de guardado lógica que detecte campos antiguos y los importe a la nueva meta declarada o viceversa.
7) Ejemplo final: flujo completo
- Registrar meta en PHP con register_post_meta (show_in_rest => true).
- Declarar atributo en block.json o en JS con source: meta y meta: mi_meta_bloque.
- En editor, el control lee/escribe automáticamente la meta expuesta por REST.
- Opcionalmente, usar save_post con parse_blocks para sincronizar manualmente, migrar o consolidar valores.
- En frontend, usar render_callback o get_post_meta en plantillas para mostrar/usar la meta.
Recursos útiles
- register_post_meta — Developer Reference
- Block Metadata (block.json) — Block Editor Handbook
- parse_blocks — Developer Reference
Conclusión
Guardar meta de bloques en post_meta con PHP es una práctica poderosa que conecta el editor y el servidor: registrar la meta correctamente, exponerla en REST y definir atributos de bloque con source: meta simplifica la sincronización. Para casos complejos o migraciones, parsear bloques en save_post y actualizar post_meta manualmente es fiable si se aplica con cuidado (chequeos de autosaves/revisiones, sanitización y permisos). Siguiendo las pautas y ejemplos mostrados puedes implementar flujo robusto que funcione bien en el editor, en consultas y en el frontend.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |