Skip to main content
Platform:
Language:

How to Manage Scopes

CE.SDK allows you to control which parts of a block can be manipulated. Scopes describe different aspects of a block, e.g. layout or style and can be enabled or disabled for every single block. There's also the option to control a scope globally. When configuring a scope globally you can set an override to always allow or deny a certain type of manipulation for every block. Or you can configure the global scope to defer to the individual block scopes.

Initially, the block-level scopes are all disabled while at the global level all scopes are set to "Allow". This overrides the block-level and allows for any kind of manipulation.

If you want to implement a limited editing mode in your software you can set the desired scopes on the blocks you want the user to manipulate and then restrict the available actions by globally setting the scopes to "Defer". In the same way you can prevent any manipulation of properties covered by a scope by setting the respective global scope to "Deny".

Explore a full code sample of the integration on CodeSandbox or view the code on GitHub

Setup#

This example uses the headless CreativeEngine. See the Setup article for a detailed guide. To get started right away, you can also access the block API within a running CE.SDK instance via cesdk.engine.block. Check out the APIs Overview to see that illustrated in more detail.

Available Scopes#

We currently support the following scopes:

ScopeExplanation
Scope
"design/style"
Explanation
Whether the block's style properties can be changed
Scope
"design/arrange"
Explanation
Whether the block's layout properties can be changed (move, resize, rotate and flip)
Scope
"design/arrange/move"
Explanation
Whether the block's position can be changed (supersedes "design/arrange")
Scope
"design/arrange/resize"
Explanation
Whether the block can be resized (supersedes "design/arrange")
Scope
"design/arrange/rotate"
Explanation
Whether the block's rotation can be changed (supersedes "design/arrange")
Scope
"design/arrange/flip"
Explanation
Whether the block can be flipped (supersedes "design/arrange")
Scope
"content/replace"
Explanation
Whether the block's content can be replaced
Scope
"lifecycle/destroy"
Explanation
Whether the block can be deleted
Scope
"lifecycle/duplicate"
Explanation
Whether the block can be duplicated
Scope
"editor/add"
Explanation
Whether new blocks can be added
Scope
"editor/select"
Explanation
Whether a block can be selected or not

Managing Scopes#

First, we globally defer the 'design/arrange' scope to the block-level using editor.setGlobalScope('design/arrange', 'Defer'). Since all blocks default to having their scopes set to false initially, modifying the layout properties of any block will fail at this point.

ValueExplanation
Value
"Allow"
Explanation
Manipulation of properties covered by the scope is always allowed
Value
"Deny"
Explanation
Manipulation of properties covered by the scope is always denied
Value
"Defer"
Explanation
Permission is deferred to the scope of the individual blocks

We can verify the current state of the global 'design/arrange' scope using editor.getGlobalScope('design/arrange').

Now we can allow the 'design/arrange' scope for a single block by setting it to true using block.setScopeEnabled(block: number, key: string, enabled: boolean).

Again we can verify this change by calling block.isScopeEnabled(block: number, key: string): boolean.

Finally, block.isAllowedByScope(block: number, key: string): boolean will allow us to verify a block's final scope state by taking both the global state as well as block-level state into account.

File:
import CreativeEngine from 'https://cdn.img.ly/packages/imgly/cesdk-engine/1.9.0/index.js';
const config = {
baseURL: 'https://cdn.img.ly/packages/imgly/cesdk-engine/1.9.0/assets'
};
CreativeEngine.init(config).then(async (engine) => {
let scene = await engine.scene.createFromImage('https://img.ly/static/ubq_samples/imgly_logo.jpg');
const image = engine.block.findByType('image')[0];
/* Let the global scope defer to the block-level. */
engine.editor.setGlobalScope('design/arrange', 'Defer');
/* Manipulation of layout properties of any block will fail at this point. */
try {
engine.block.setPositionX(image, 100); // Not allowed
} catch(err) {
console.log(err.message);
}
/* This will return 'Defer'. */
engine.editor.getGlobalScope('design/arrange');
/* Allow the user to control the layout properties of the image block. */
engine.block.setScopeEnabled(image, 'design/arrange', true);
/* Manipulation of layout properties of any block is now allowed. */
try {
engine.block.setPositionX(image, 100); // Allowed
} catch(err) {
console.log(err.message);
}
/* Verify that the 'design/arrange' scope is now enabled for the image block. */
engine.block.isScopeEnabled(image, 'design/arrange');
/* This will return true as well since the global scope is set to 'Defer'. */
engine.block.isAllowedByScope(image, 'design/arrange');
});