Como forzar estructura de contenido con template_lock en PHP en WordPress

Contents

Introducción

En el editor de bloques de WordPress (Gutenberg) existe la posibilidad de forzar una estructura concreta de contenido para tipos de contenido (post types) o para bloques que admiten InnerBlocks. Esta característica se maneja con template y template_lock. Forzar la estructura evita que los editores cambien la disposición de bloques, lo que resulta muy útil para plantillas de contenido corporativo, landing pages, o contenido que debe cumplir un diseño estricto.

¿Qué es template_lock y qué valores tiene?

template_lock es una forma de bloquear la plantilla de bloques que has definido. Puede tomar estos valores:

  • false (por defecto): no hay bloqueo, los usuarios pueden añadir, mover o eliminar bloques libremente.
  • insert: impide insertar nuevos bloques fuera de los ya definidos por la plantilla sin embargo, permite mover y eliminar los bloques existentes.
  • all: bloquea por completo la plantilla: no se pueden añadir, mover ni eliminar los bloques que forman la plantilla.

Cuándo usar cada opción

  • false: contenido libre o cuando quieres que el editor pueda adaptar la estructura.
  • insert: cuando quieres asegurar que sólo existan determinadas zonas predefinidas, pero permites al editor reorganizar o quitar algunas partes dentro de la plantilla.
  • all: cuando la estructura debe ser exactamente la misma en cada entrada (por ejemplo, formularios, fichas técnicas, plantillas legales).

Forzar estructura con register_post_type (ejemplo completo en PHP)

Una de las formas más comunes de forzar la estructura es al registrar un custom post type mediante register_post_type, pasándole la plantilla de bloques y el bloqueo. A continuación un ejemplo práctico para un CPT llamado libro.

 Libros,
        singular_name      => Libro,
    )

    args = array(
        labels             => labels,
        public             => true,
        show_in_rest       => true, // imprescindible para editor de bloques
        supports           => array( title, editor, thumbnail ),
        // Definimos la plantilla de bloques que aparecerá al crear/editar el post:
        template => array(
            // Título principal (heading)
            array( core/heading, array(
                level => 1,
                placeholder => Título del libro
            ) ),
            // Párrafo de introducción
            array( core/paragraph, array(
                placeholder => Introducción o subtítulo...
            ) ),
            // Grupo con imagen a la izquierda y descripción a la derecha (columnas)
            array( core/columns, array(), array(
                array( core/column, array(), array(
                    array( core/image, array() )
                ) ),
                array( core/column, array(), array(
                    array( core/paragraph, array(
                        placeholder => Descripción breve
                    ) )
                ) ),
            ) ),
            // Repetible: bloque de reseña (puede ser un bloque reutilizable o un patrón)
            array( core/paragraph, array(
                placeholder => Reseña o contenido adicional...
            ) ),
        ),
        // Bloqueamos la plantilla: all evita cualquier cambio en la estructura
        template_lock => all,
    )

    register_post_type( libro, args )
}
?>

En ese ejemplo:

  • La opción show_in_rest debe estar en true para que el editor de bloques funcione con ese CPT.
  • La propiedad template es un array de arrays donde cada entrada define un bloque (slug de bloque y atributos).
  • template_lock => all evita que el usuario añada, mueva o elimine bloques fuera de lo definido.

Ejemplo con template_lock = insert (permitir mover/eliminar, evitar insertar)

 array( name => Eventos, singular_name => Evento ),
        public => true,
        show_in_rest => true,
        supports => array( title, editor ),
        template => array(
            array( core/heading, array( level => 2, placeholder => Nombre del evento ) ),
            array( core/paragraph, array( placeholder => Resumen del evento ) ),
            array( core/paragraph, array( placeholder => Lugar / Fecha / Hora ) ),
        ),
        template_lock => insert, // no se pueden insertar nuevos bloques por fuera
    ) )
}
?>

Restricciones adicionales: limitar tipos de bloques permitidos

A veces además de fijar una plantilla quieres restringir qué bloques pueden añadirse (si permites inserciones). Para ello existe el filtro allowed_block_types_all que permite devolver un array con los slugs de bloques permitidos.

post )  editor_context->post->post_type === libro ) {
        // Permitimos sólo párrafos e imágenes (y encabezados)
        return array(
            core/paragraph,
            core/image,
            core/heading
        )
    }
    return allowed_blocks
}
?>

Modificar o aplicar plantillas dinámicamente (filtros)

Si necesitas aplicar o cambiar una plantilla según condiciones (p. ej. rol de usuario, plantilla de página, opciones del tema), puedes usar el filtro register_post_type_args o hooks en el init para modificar los args del CPT.


Bloquear InnerBlocks dentro de un bloque personalizado

Cuando desarrollas bloques personalizados que usan InnerBlocks, la forma más directa de establecer una plantilla y su bloqueo se hace desde el código JavaScript (componente InnerBlocks) o mediante el archivo block.json y el script de edición. En PHP puedes registrar el bloque pero la plantilla y el templateLock de InnerBlocks suelen definirse en el editor en JS. Conceptualmente:

  • En el edit (JS): ltInnerBlocks template=… templateLock=all /gt.
  • Si quieres controlar esto desde el servidor, suele combinarse la definición del bloque en block.json con la configuración del editor (solución mixta PHP JS).

Nota práctica

El bloqueo de plantilla actúa en la interfaz del editor. Usuarios con acceso al editor (o con capacidades avanzadas) podrían manipular el contenido mediante REST API o editar el HTML del bloque si las capacidades lo permiten. Si necesitas una garantía absoluta de estructura, valida y normaliza el contenido en el servidor antes de guardar o al renderizar.

Consideraciones y buenas prácticas

  1. Siempre activar show_in_rest: para que el editor de bloques funcione con un CPT, show_in_rest debe ser true.
  2. Usar placeholders y atributos: añade atributos como placeholder para guiar al editor y mejorar la experiencia.
  3. Pruebas de usabilidad: bloqueos muy estrictos (all) pueden confundir a editores no técnicos documenta la plantilla para el equipo.
  4. Combinar con allowed_block_types_all: cuando quieras permitir alguna inserción controlada, limita los bloques permitidos.
  5. Validación en servidor: para seguridad y control, valida estructura/atributos al guardar (p. ej. en hooks de guardado).

Ejemplo: validación sencilla al guardar (comprobación mínima)

post_content
    if ( strpos( content, core/heading ) === false ) {
        // Opcional: añadir una nota al contenido o registrar error.
        // No hacemos un wp_die en ambientes reales validarías con más rigor.
        add_post_meta( post_ID, _aviso_estructura, Falta el heading principal en la plantilla. )
    }
}
?>

Resumen práctico

  • Usa template en register_post_type para definir la estructura base en el editor de bloques.
  • Controla el grado de bloqueo con template_lock: false, insert o all.
  • Complementa con allowed_block_types_all si necesitas restringir tipos de bloques.
  • Para InnerBlocks en bloques personalizados, define la plantilla / templateLock en el editor (JS) o mediante block.json si aplicable.
  • Valida en servidor si la integridad de la estructura es crítica.


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 *