Using Content Editor from a custom UI

November 14, 2023

Content Editor being the application to edit any content item inside Jahia CMS, it is used in several of our applications like Page Composer or jContent. It is also possible to use Content Editor from your own application, either in a SPA to improve usability in headless, in a custom panel in jContent => additionnal or elsewhere. 

To open Content Editor from a custom application, there are 2 options: 

  1. Using the javascript API (recommended)
  2. Using an URL

For these 2 options, there are 2 main use cases: edit an existing content item or create a new one.

1 - Open Content Editor using the javascript API 

It is possible to open Content Editor using the javascript API, this is the recommended way. It will open Content Editor as a modal, on top of your existing application.

Prerequisites

To access Content Editor API, Jahia application must be running in the browser, (for instance, Jahia application is not available in preview mode).

Jahia application is provided by the following URL:
{domain}/{context}/jahia/
Examples:

http://mySite.com/sampleContext/jahia/content-editor/…
http://mySite.com/jahia/jcontent/…

You can validate that the API is available with the presence of the following object:
window.CE_API

Content Editor 3.x

Edit

window.CE_API.edit(uuid, site, lang, uilang)
 
  • uuid: Identifier of the node you want to edit
  • siteName: Site where the node is present
  • language: the node language you want to edit
  • uiLanguage: language of the UI

Example:

Edit current site node in english

window.CE_API.edit(window.jahiaGWTParameters.siteUuid, window.jahiaGWTParameters.siteKey, 'en', 'en')

Create

window.CE_API.create(uuid, path, site, lang, uilang, nodeTypes, excludedNodeTypes, includeSubTypes, name)

Note that the create function is opening first a content type selector to pick the type of content the user wants to create.
This content type selector is displayed only if more than one type match the nodeTypes/excludedNodeTypes/includeSubTypes combination, see below for a detailed explanation.
  • uuid: Parent uuid of the content to create, this is used by content editor to save the content
  • path: parent path of the content to create, this is used by the type selector, to get the restrictions regarding the location of content to create. 
  • site: The current site
  • lang: The node language
  • uilang: The preferred user lang for ui
  • nodeTypes: Array of one element containaing the node type (example: ['jnt:text']). In case there are multiple types, or the type provided has several subtypes, the Content Type selector will be shown to let the user select the type he wants to create.
  • excludedNodeTypes: Types to exclude from the allowed types to create.
  • includeSubTypes: if false, inherited types from nodetypes provided won't be added as types that can be created. For example, if nodetypes parameter is ['jnt:text'], a type jnt:myCustomText extends jnt:text, by default a content type selector with the two types is displayed. If includeSubTypes is false, inherited types won't be resolved then content editor will be open directly to create a new text content.   
  • name: Name to use for the new content. 

Examples:

Create a new text under the site node:

window.CE_API.create(window.jahiaGWTParameters.siteUuid, '/sites/'+ window.jahiaGWTParameters.siteKey, window.jahiaGWTParameters.siteKey, 'en', 'en', ['jnt:text'])

Create a new content (but not text) under the site node with a specific name:

window.CE_API.create(window.jahiaGWTParameters.siteUuid, '/sites/'+ window.jahiaGWTParameters.siteKey, window.jahiaGWTParameters.siteKey, 'en', 'en', ['jnt:content'], ['jnt:text'], true, 'test content')

Content Editor 4.x

One of the changes with Content Editor 4 API is that now an object is used as a parameter instead of many parameters.
Some new functionalities has been introduced. 
Note that the Content Editor 3.x format is still working.

Edit

Available properties:

  • uuid: Identifier of the node you want to edit
  • site: Site where the node is present
  • lang: the node language you want to edit
  • uilang: language of the UI
  • isFullscreen: if true, content editor is displayed in full screen
  • editCallback: function called after a content is edited, it has an info parameter that contains: {originalNode, updatedNode}
  • onClosedCallback: function called when content editor is close

Examples:

Set an object config to edit the current site node with the UI in french:

const CE_CONFIG={uuid: window.jahiaGWTParameters.siteUuid,
               site: window.jahiaGWTParameters.siteKey,
               lang: 'en',
               uilang: 'fr'};
console.log('open Content Editor');
window.CE_API.edit(CE_CONFIG);

Update the object config to edit the current site node in fullscreen, UI in french, and display a log message when the content is saved. 

CE_CONFIG.isFullscreen = true;
CE_CONFIG.editCallback = (...data) => console.log(`content saved`, data);
console.log('open Content Editor');
window.CE_API.edit(CE_CONFIG);

Create

Note that the create function is opening first a content type selector to pick the type of content the user wants to create.
This content type selector is displayed only if more than one type match the nodeTypes/excludedNodeTypes/includeSubTypes combination, see below for a detailed explanation.

Available properties:

  • uuid: Identifier of the node you want to edit
  • path: Parent path of the content to create, this is used by the type selector, to get the restrictions regarding the location of the content to create. 
  • site: Site where the node is present
  • lang: The node language you want to edit
  • uilang: Language of the UI
  • nodeTypes: Array of one element containaing the node type (example: ['jnt:text']). In case there are multiple types, or the type provided has several subtypes, the Content Type selector will be shown to let the user select the type he wants to create.
  • excludedNodeTypes: Types to exclude from the allowed types to create.
  • includeSubTypes: if false, inherited types from nodetypes provided won't be added as types that can be created. For example, if nodetypes parameter is ['jnt:text'], a type jnt:myCustomText extends jnt:text, by default a content type selector with the two types is displayed. If includeSubTypes is false, inherited types won't be resolved then content editor will be open directly to create a new text content.   
  • isFullscreen: If true, content editor is displayed in full screen
  • createCallback: Function called after a content is edited, it has an info parameter that contains: {newNode}
  • onClosedCallback: function called when content editor is close
  • name: Name to use for the new content. 

Examples

Create a new page (jnt:page) or non internationalized page (jnt:noni18npage) under site node using a config object:

const CE_CREATE_CONFIG = {uuid: window.jahiaGWTParameters.siteUuid,
                          path: '/sites/' + window.jahiaGWTParameters.siteKey,
               site: window.jahiaGWTParameters.siteKey,
               lang: 'en',
               uilang: 'en',
               nodeTypes: ['jnt:page']
};
window.CE_API.create(CE_CREATE_CONFIG);

Update the CE config to open page only:

CE_CREATE_CONFIG.includeSubTypes = false;
window.CE_API.create(CE_CREATE_CONFIG);

Update the CE config to set a specific name for the content:

CE_CREATE_CONFIG.name = 'my-page';
window.CE_API.create(CE_CREATE_CONFIG);

jContent 3.x

One of the changes with jContent 3 API is that now the windows.parent object is used instead of windows object to ease the API usage whether it is used in a template or in a button.
Some new functionalities has been introduced. 
Note that the Content Editor 4.x format is still working. (???)

Edit

Available properties:

  • uuid (or path): Identifier (or Path) of the node you want to edit
  • lang: the node language you want to edit (not mandatory, it will use the current language if it's not passed)
  • isFullscreen: if true, content editor is displayed in full screen
  • editCallback: function called after a content is edited, it has an info parameter that contains: {originalNode, updatedNode}
  • onClosedCallback: function called when content editor is close
  • onExited: function called after content editor is close

The edit API can be called with:

<input type="button" onClick="window.parent.CE_API.edit({path:'/sites/digitall/home/area-main'})">edit</input>

Examples:

Set an object config to edit the current site node with the UI in french:

const CE_CONFIG={uuid: window.jahiaGWTParameters.siteUuid,
               site: window.jahiaGWTParameters.siteKey,
               lang: 'en',
               uilang: 'fr'};
console.log('open Content Editor');
window.parent.CE_API.edit(CE_CONFIG);

Update the object config to edit the current site node in fullscreen, UI in french, and display a log message when the content is saved. 

CE_CONFIG.isFullscreen = true;
CE_CONFIG.editCallback = (...data) => console.log(`content saved`, data);
console.log('open Content Editor');
window.parent.CE_API.edit(CE_CONFIG);

Create

Note that the create function is opening first a content type selector to pick the type of content the user wants to create.
This content type selector is displayed only if more than one type match the nodeTypes/excludedNodeTypes/includeSubTypes combination, see below for a detailed explanation.

Available properties:

  • uuid (or path): Identifier (or Path) of the node you want to create
  • lang: The node language you want to create (not mandatory, it will use the current language if it's not passed)
  • nodeTypes: Array of one element containaing the node type (example: ['jnt:text']). In case there are multiple types, or the type provided has several subtypes, the Content Type selector will be shown to let the user select the type he wants to create.
  • excludedNodeTypes: Types to exclude from the allowed types to create.
  • includeSubTypes: if false, inherited types from nodetypes provided won't be added as types that can be created. For example, if nodetypes parameter is ['jnt:text'], a type jnt:myCustomText extends jnt:text, by default a content type selector with the two types is displayed. If includeSubTypes is false, inherited types won't be resolved then content editor will be open directly to create a new text content.   
  • isFullscreen: If true, content editor is displayed in full screen
  • createCallback: Function called after a content is edited, it has an info parameter that contains: {newNode}
  • onClosedCallback: function called when content editor is close
  • onExited: function called after content editor is close
  • name: Name to use for the new content
  • orderBefore: specify where the node will be added
  • layout: use a completely custom layout
  • dialogProps: props to add to the dialog
  • useConfirmationDialog: true/false, allows to close without confirmation

The create API can be called with:

<input type="button" onClick="window.parent.CE_API.create({path:'/sites/digitall/home/area-main'})">create</input>

Examples

Create a new page (jnt:page) or non internationalized page (jnt:noni18npage) under site node using a config object:

const CE_CREATE_CONFIG = {uuid: window.jahiaGWTParameters.siteUuid,
                          path: '/sites/' + window.jahiaGWTParameters.siteKey,
               site: window.jahiaGWTParameters.siteKey,
               lang: 'en',
               uilang: 'en',
               nodeTypes: ['jnt:page']
};
window.parent.CE_API.create(CE_CREATE_CONFIG);

Update the CE config to open page only:

CE_CREATE_CONFIG.includeSubTypes = false;
window.parent.CE_API.create(CE_CREATE_CONFIG);

Update the CE config to set a specific name for the content:

CE_CREATE_CONFIG.name = 'my-page';
window.parent.CE_API.create(CE_CREATE_CONFIG);

Store shared config in the registry

Note that it's possible (and preferable for complex params like callbacks) to move all these configuration parameters in a dedicated configuration, stored in the registry. For example :

    window.jahia.uiExtender.registry.add('content-editor-config', 'my-config', {
        createCallback: ({path}) => {
            window.jahia.reduxStore.dispatch({type: 'CM_OPEN_PATHS', payload: [path.substring(0, path.lastIndexOf('/'))]});  
            window.jahia.reduxStore.dispatch(window.jahia.uiExtender.registry.get('redux-action', 'jcontentGoto').action({path}));
        }
    });

and then use it with the configName parameter :

    window.parent.CE_API.create({path:'/sites/digitall/home', nodeTypes:['jnt:page'], includeSubTypes:false, configName:'my-config'})

Any parameter (except the one related to nodetype selector, like nodeTypes and includeSubTypes), can be put in a shared config like that.

2 - Open Content Editor using an URL

Use case:

To share a link that will open a content in creation in editor

URL Format

To open Content Editor in the edit mode:

{domain}/{context}/jahia/content-editor/{language}/edit/{uuid}

Example:

http://mySite.com/sampleContext/jahia/content-editor/en/edit/627e7672-fc37-4b25-bfea-1ccb1767f0fe

 

To open Content Editor in the create mode:

{domain}/{context}/jahia/content-editor/{language}/create/{parentUuid}/{nodeType}

Example:

http://mySite.com/sampleContext/jahia/content-editor/en/create/6e85d4f9-7d98-4045-aad7-c4abca9c6664/jnt:text
  • domain: Domain of your site
  • context: Context of of application
  • language: node langague to edit or create
  • uuid: Identifier of the node you want to edit (edit mode)
  • parentUuid: Identifier of the parent node where you want to create a node (create mode)
  • nodeType: Node type of the node you want to create

jContent 3.x

Some new functionalities has been introduced. 
Note that the Content Editor 4.x format is still working.

Edit

Available properties:

  • uuid (or path): Identifier (or Path) of the node you want to edit
  • lang: the node language you want to edit (not mandatory, it will use the current language if it's not passed)
  • isFullscreen: if true, content editor is displayed in full screen
  • editCallback: function called after a content is edited, it has an info parameter that contains: {originalNode, updatedNode}
  • onClosedCallback: function called when content editor is close
  • onExited: function called after content editor is close

The edit API can be called with:

<input type="button" onClick="window.parent.CE_API.edit({path:'/sites/digitall/home/area-main'})">edit</input>

Examples:

Set an object config to edit the current site node with the UI in french:

const CE_CONFIG={uuid: window.jahiaGWTParameters.siteUuid,
               site: window.jahiaGWTParameters.siteKey,
               lang: 'en',
               uilang: 'fr'};
console.log('open Content Editor');
window.CE_API.edit(CE_CONFIG);

Update the object config to edit the current site node in fullscreen, UI in french, and display a log message when the content is saved. 

CE_CONFIG.isFullscreen = true;
CE_CONFIG.editCallback = (...data) => console.log(`content saved`, data);
console.log('open Content Editor');
window.CE_API.edit(CE_CONFIG);

Create

Note that the create function is opening first a content type selector to pick the type of content the user wants to create.
This content type selector is displayed only if more than one type match the nodeTypes/excludedNodeTypes/includeSubTypes combination, see below for a detailed explanation.

Available properties:

  • uuid (or path): Identifier (or Path) of the node you want to create
  • lang: The node language you want to create (not mandatory, it will use the current language if it's not passed)
  • nodeTypes: Array of one element containaing the node type (example: ['jnt:text']). In case there are multiple types, or the type provided has several subtypes, the Content Type selector will be shown to let the user select the type he wants to create.
  • excludedNodeTypes: Types to exclude from the allowed types to create.
  • includeSubTypes: if false, inherited types from nodetypes provided won't be added as types that can be created. For example, if nodetypes parameter is ['jnt:text'], a type jnt:myCustomText extends jnt:text, by default a content type selector with the two types is displayed. If includeSubTypes is false, inherited types won't be resolved then content editor will be open directly to create a new text content.   
  • isFullscreen: If true, content editor is displayed in full screen
  • createCallback: Function called after a content is edited, it has an info parameter that contains: {newNode}
  • onClosedCallback: function called when content editor is close
  • onExited: function called after content editor is close
  • name: Name to use for the new content
  • orderBefore: specify where the node will be added
  • layout: use a completely custom layout
  • dialogProps: props to add to the dialog
  • useConfirmationDialog: true/false, allows to close without confirmation

The create API can be called with:

<input type="button" onClick="window.parent.CE_API.create({path:'/sites/digitall/home/area-main'})">create</input>

Examples

Create a new page (jnt:page) or non internationalized page (jnt:noni18npage) under site node using a config object:

const CE_CREATE_CONFIG = {uuid: window.jahiaGWTParameters.siteUuid,
                          path: '/sites/' + window.jahiaGWTParameters.siteKey,
               site: window.jahiaGWTParameters.siteKey,
               lang: 'en',
               uilang: 'en',
               nodeTypes: ['jnt:page']
};
window.CE_API.create(CE_CREATE_CONFIG);

Update the CE config to open page only:

CE_CREATE_CONFIG.includeSubTypes = false;
window.parent.CE_API.create(CE_CREATE_CONFIG);

Update the CE config to set a specific name for the content:

CE_CREATE_CONFIG.name = 'my-page';
window.CE_API.create(CE_CREATE_CONFIG);

Store shared config in the registry

Note that it's possible (and preferable for complex params like callbacks) to move all these configuration parameters in a dedicated configuration, stored in the registry. For example :

    window.jahia.uiExtender.registry.add('content-editor-config', 'my-config', {
        createCallback: ({path}) => {
            window.jahia.reduxStore.dispatch({type: 'CM_OPEN_PATHS', payload: [path.substring(0, path.lastIndexOf('/'))]});  
            window.jahia.reduxStore.dispatch(window.jahia.uiExtender.registry.get('redux-action', 'jcontentGoto').action({path}));
        }
    });

and then use it with the configName parameter :

    window.CE_API.create({path:'/sites/digitall/home', nodeTypes:['jnt:page'], includeSubTypes:false, configName:'my-config'})

Any parameter (except the one related to nodetype selector, like nodeTypes and includeSubTypes), can be put in a shared config like that.

2 - Open Content Editor using an URL

Use case:

To share a link that will open a content in creation in editor

URL Format

To open Content Editor in the edit mode:

{domain}/{context}/jahia/content-editor/{language}/edit/{uuid}

Example:

http://mySite.com/sampleContext/jahia/content-editor/en/edit/627e7672-fc37-4b25-bfea-1ccb1767f0fe

 

To open Content Editor in the create mode:

{domain}/{context}/jahia/content-editor/{language}/create/{parentUuid}/{nodeType}

Example:

http://mySite.com/sampleContext/jahia/content-editor/en/create/6e85d4f9-7d98-4045-aad7-c4abca9c6664/jnt:text
  • domain: Domain of your site
  • context: Context of of application
  • language: node langague to edit or create
  • uuid: Identifier of the node you want to edit (edit mode)
  • parentUuid: Identifier of the parent node where you want to create a node (create mode)
  • nodeType: Node type of the node you want to create