Search Docs
Loading...
Skip to content

Set Editing Constraints

Control what users can edit in templates by setting fine-grained permissions on individual blocks or globally across the scene with the CE.SDK Scope system.

6 mins
estimated time
GitHub

Editing constraints let you lock specific properties of design elements while keeping others editable. Scopes cover movement, resizing, rotation, fill changes, text editing, lifecycle operations, and other editor capabilities. Use them to protect brand templates, guide template adoption, and build form-based workflows where users can personalize only selected fields.

Understanding Scopes#

What Are Scopes?#

A scope is a permission key that controls one editing capability. Each scope represents a distinct action, such as moving blocks ("layer/move"), changing fills ("fill/change"), or editing text content ("text/edit").

Scopes exist at two levels:

  • Block-level scopes: Per-block permissions set with engine.block.setScopeEnabled(...).
  • Global scopes: Scene-wide defaults set with engine.editor.setGlobalScope(...).

Global scope defaults depend on the editor role. Under the default Creator role, global scopes are allowed, so block-level restrictions are not consulted. To make a block-level setting take effect, set the matching global scope to GlobalScope.DEFER, either through your editor role setup or with engine.editor.setGlobalScope(...).

Available Scope Categories#

CE.SDK groups scopes into logical categories. Retrieve the full list at runtime with engine.editor.findAllScopes().

Category Purpose Example Scopes
Text Editing Control text content and formatting text/edit, text/character
Fill & Stroke Manage colors, fills, and strokes fill/change, fill/changeType, stroke/change
Shape Modify shape properties shape/change
Layer Transform Control position and dimensions layer/move, layer/resize, layer/rotate, layer/flip, layer/crop
Layer Appearance Manage visual properties layer/opacity, layer/blendMode, layer/visibility, layer/clipping
Effects & Filters Apply visual effects appearance/adjustments, appearance/filter, appearance/effect, appearance/blur, appearance/shadow
Lifecycle Control deletion and duplication lifecycle/destroy, lifecycle/duplicate
Editor Manage scene-level actions editor/add, editor/select

Scope Configuration#

Global Scope Modes#

Global scopes set the default behavior for all blocks in the scene. They have three modes:

Mode Behavior
GlobalScope.ALLOW Always allow the action, overriding block-level settings
GlobalScope.DENY Always deny the action, overriding block-level settings
GlobalScope.DEFER Use the block-level setting for each block

To make block-level constraints take effect, defer the relevant global scopes to the block level:

// Keep these scopes deferred so the returned scene uses block-level constraints.
engine.editor.setGlobalScope(key = "layer/move", globalScope = GlobalScope.DEFER)
engine.editor.setGlobalScope(key = "layer/resize", globalScope = GlobalScope.DEFER)
engine.editor.setGlobalScope(key = "lifecycle/destroy", globalScope = GlobalScope.DEFER)
engine.editor.setGlobalScope(key = "lifecycle/duplicate", globalScope = GlobalScope.DEFER)

Defer only the scopes that your app controls at the block level. When a block should keep a deferred capability, explicitly enable that scope on the block.

Scope Resolution Priority#

When both global and block-level scopes apply, CE.SDK resolves permissions in this order:

  1. Global GlobalScope.DENY blocks the action.
  2. Global GlobalScope.ALLOW permits the action.
  3. Global GlobalScope.DEFER uses the block-level setting for each block.

Setting Block-Level Constraints#

Locking Position#

Prevent users from moving a block while keeping resizing available:

engine.block.setScopeEnabled(positionLocked, key = "layer/resize", enabled = true)
engine.block.setScopeEnabled(positionLocked, key = "layer/move", enabled = false)

Disabling layer/move locks the block position. Because the full sample also defers resizing and lifecycle scopes, the block can still resize, delete, and duplicate when those block-level scopes remain enabled.

Preventing Deletion#

Protect a block from being deleted or duplicated while keeping transform edits available:

engine.block.setScopeEnabled(deletionLocked, key = "layer/move", enabled = true)
engine.block.setScopeEnabled(deletionLocked, key = "layer/resize", enabled = true)
engine.block.setScopeEnabled(deletionLocked, key = "lifecycle/destroy", enabled = false)
engine.block.setScopeEnabled(deletionLocked, key = "lifecycle/duplicate", enabled = false)

Use this for essential template elements that must remain present. Movement and resizing can remain enabled independently because lifecycle scopes are separate permissions.

Checking Scope State#

Query the block-level setting for any scope:

val moveScopeEnabled = engine.block.isScopeEnabled(positionLocked, key = "layer/move")
Log.i("SetEditingConstraints", "layer/move enabled at block level: $moveScopeEnabled")

engine.block.isScopeEnabled(...) returns only the block-level flag. It does not consider the current global scope mode.

Checking Effective Permissions#

Check the effective permission after global and block-level settings resolve:

val moveAllowed = engine.block.isAllowedByScope(positionLocked, key = "layer/move")
Log.i("SetEditingConstraints", "layer/move allowed: $moveAllowed")

Use engine.block.isAllowedByScope(...) when your app needs to know whether an action is actually permitted.

API Reference#

Method Description
engine.editor.findAllScopes() List all available scope keys
engine.editor.setGlobalScope(key=_, globalScope=_) Set a scope to GlobalScope.ALLOW, GlobalScope.DENY, or GlobalScope.DEFER
engine.editor.getGlobalScope(key=_) Read the global setting for one scope
engine.block.setScopeEnabled(block=_, key=_, enabled=_) Enable or disable a block-level scope
engine.block.isScopeEnabled(block=_, key=_) Check whether a scope is enabled at the block level
engine.block.isAllowedByScope(block=_, key=_) Check the resolved permission after global and block-level settings are evaluated

Troubleshooting#

  • A disabled block scope still appears editable: Check the matching global scope. GlobalScope.ALLOW overrides block-level restrictions, so set that scope to GlobalScope.DEFER when the block setting should decide the result.
  • All blocks lose the same editing capability: Check for GlobalScope.DENY. A denied global scope disables that action for every block, even when individual blocks have the scope enabled.
  • Constraints seem to reset after reloading: Scope settings are stored with the scene. If a reloaded scene behaves differently, verify that your app saved the constrained scene after calling engine.block.setScopeEnabled(...).
  • The editor UI shows unavailable controls: The CE.SDK editor UI reflects denied scopes by disabling or hiding controls depending on the surface. Use engine.block.isAllowedByScope(...) to confirm the resolved permission that the UI should follow.

Next Steps#

  • Text Variables - Define dynamic text elements that can be populated with custom values.
  • Placeholders - Mark editable image, video, or text areas within a locked template layout.
  • Lock the Template - Restrict editing access to specific elements or properties in a template.
  • Create From Scratch - Build reusable design templates programmatically using CE.SDK APIs.