Customizing Content Editor forms
You can customize the Content Editor interface with JSON overrides. This topic shows you how override sections, field sets, and fields.
Form overrides
This section shows how to define static forms, how Jahia applies inheritance to sections, and provides an example of applying section overrides.
Defining static forms in Jahia modules
You can override the static definition of the forms by adding JSON files in the META-INF/jahia-content-editor-forms
folder of your Jahia module, and then in the forms
or fieldsets
subdirectory. The files should have meaningful names and to ensure consistency between your definitions and your overrides. We recommend replacing the colon (:) between the namespace and the content type with an underscore. For example, the override of the qant:myFields
node type should be named qant_myFields.json
.
Here's an example of a JSON static form definition:
{
"nodeType": "qant:myFields",
"priority": 1.0,
"sections": [
{
"name": "layout",
"hide": true
}
]
}
With this definition, when you create or edit a node of the type qant:myFields
, a form without the section named layout displays.
Other examples can be found in our Content Editor test folder.
Fieldsets overrides
In order to keep compatibility with previous versions, It is also possible to use field sets override, when the name of a fieldset is actually a node type name. Field set overrides are JSON files that are stored in the following directory:
/your_module/src/main/resources/META-INF/jahia-content-editor-forms/fieldsets
The JSON file has the following format:
{
"name": "jmix:myType",
"priority": 1.0,
… fieldsets properties
}
However, doing this can lead to complex situations when fieldsets with the same name can appear in multiple sections (which is possible when fields of a same node type are “split” between different sections).
Checking proper registration of static forms
If you want to check if your form or field set definitions are properly deployed, check the Jahia logs for lines that look like this:
2022-12-12 15:43:48,490: INFO [StaticDefinitionsRegistry] - Successfully loaded static fieldSets for name jmix:description from bundle://132.0:0/META-INF/jahia-content-editor-forms/fieldsets/jmix_description_move_section.json 2022-12-12 15:43:48,501: INFO [StaticDefinitionsRegistry] - Successfully loaded static form for name jnt:category from bundle://138.0:0/META-INF/jahia-content-editor-forms/forms/jnt_category.json
Checking form generation
It can be helpful to know how to query a form generation to validate it is generated as expected. This can be done using the GraphQL API directly with the following query:
{
forms {
editForm(
uiLocale: "en"
locale: "en"
uuidOrPath: "/sites/digitall/home/area-main"
) {
sections {
name
displayName
fieldSets {
name
displayName
fields {
name
selectorType
i18n
readOnly
multiple
mandatory
valueConstraints {
displayValue
value {
type
string
}
properties {
name
value
}
}
defaultValues {
type
string
}
}
}
}
}
}
}
This will produce the JSON for the form for the specified node type, resulting from the merging of CND generation and all the associated static field set and form definitions.
How forms are inherited
You can use JSON overrides to redefine any property of the form. It’s possible to override only a single field inside a field set in a single section, without changing the other values.
Jahia gather all applicable forms on the current node - either coming from the CND, from a forms or from a fieldsets file. It takes the forms that can apply on the current primary node type, on the mixin that are added on the current node, and also on the dynamic mixin that can be added on the node.
All forms are sorted by priority and merged.
An override can add new sections / fieldsets / fields, but not remove them. In order to remove a section / fieldset / field , you should set the “hide” property.
Simple form override example
This example shows how to perform section and preview overrides of the jnt:content
content definition and how to disable preview for the qant:myFieldsRequired
content type.
With form overrides, you can define the sections and preview behavior for a nodetype such as jnt:content
.
[qant:myFieldsRequired] > jnt:content, qamix:qaContent, jmix:editorialContent
- sharedSmallText (string) mandatory
- smallText (string) i18n mandatory
First, provide a JSON form definition for jnt:content that:
- Displays sections content and metadata only
- Sets preview to true
The JSON override (added to /your_module/src/main/resources/META-INF/jahia-content-editor-forms/forms/jnt_content.json
) is:
{
"nodeType": "jnt:content",
"priority": 1.0,
"hasPreview": true,
"sections": [
{
"name": "classification",
"hide": true
},
{
"name": "layout",
"hide": true
},
{
"name": "options",
"hide": true
},
{
"name": "seo",
"hide": true
},
{
"name": "listOrdering",
"hide": true
},
{
"name": "visibility",
"hide": true
}
]
}
This creates a global rule and JSON override for jnt:content
that is the default structure for all jnt:content
and every node type that inherits from jnt:content
.
But you would like to disable the preview for the qant:myFieldsRequired
content type. You can override only hasPreview
in a separate JSON override for qant:myFieldsRequired
because, at the end, JSON overrides are merged together.
Here is the additional JSON override (added to /your_module/src/main/resources/META-INF/jahia-content-editor-forms/forms/qant_myFieldsRequired.json
) to override qant:myFieldsRequired
.
{
"nodeType": "qant:myFieldsRequired",
"priority": 2.0,
"hasPreview": false
}
This way, only qant:myFieldsRequired will have preview disabled and all other jnt:content will have the preview enabled.
Label keys
You may have noticed the labelKey
setting for a section. This values contains a resource bundle key that will be looked up based on the format of its value. If it doesn't contain the :
character it will be looked up in the current module (the one where the json file is). If not found, it will fallback on the Jahia global server resource bundle that should not be modified by user. This could however be useful to re-use system keys (such as in the above examples). If you want to specify your own keys in your own module, you must use the following syntax:
basename:key
where the basename will be the name of the resource bundle (the base name of the file that will be located in the src/main/resources/resources
directory in the site template module) and the key will be the key inside the file. Here's an example:
mySiteTemplate:myLabel
will look for the myLabel key inside the src/main/resources/resources/mySiteTemplate_*.properties
file in the site template module. If it cannot be found, it will try to look it up in the main Jahia system resource bundle.
Example of label overrides
{
"nodeType": "cent:contentRetrievalCETest",
"priority": 2.0,
"sections": [
{
"name": "content",
"fieldSets": [
{
"name": "<main>",
"rank": "2.0",
"fields": [
{
"rank": 5.0,
"name": "jcr:title",
"declaringNodeType": "mix:title",
"labelKey": "content-editor-test-module:label.textoverride",
"descriptionKey": "label.information"
}
]
}
]
}
]
}
declaringNodeType
You need to use declaringNodeType
when the field you are declaring is not declared on the primary nodetype.
Field set properties
The following properties define a field set:
- name (string): name of the field set (can be a node type or not - use <main> for using the main fieldset , i.e. primary node type name). Note that the same field set name can be used in different sections
- label / labelKey (string): label or resource bundle key
- description / descriptionKey (string): description or resource bundle key
- requiredPermission: permission required to see the fieldset
- rank (decimal): position of the field set in the form. The default value is 0.0
- hide (boolean): If false, the field set is part of the generated form, but is not displayed
- readOnly (boolean): cannot add/remove associated dynamic mixin, if this field set is a dynamic mixin
- fields (array): Array of fields that compose the field set
Field overrides
The section describes field overrides, lists field properties that you can override, and provides examples of field overrides.
Field override basics
JSON overrides can override existing fields or add new fields. You can define field overrides in the fields section of field set override. The override applies to the node type defined by the name property of the field set.
{
"sections": [
{
"name": "section",
"fieldSets": [
{
"name": "jmix:myType",
"fields": [
{
"name": "fieldName",
"mandatory": false,
...
}
]
}
]
},
Field properties
Here the properties that can be overridden or used to create a field:
-
name: name of the field. To override an existing property, it must match the property name. Mandatory. Field name is unique in the whole form
-
label / labelKey: label or key to resource bundle for the section
-
description / descriptionKey: label or key to resource bundle for the section
-
errorMessage / errorMessageKey: label or key to resource bundle for the errorMessage
-
hide: do not display the field
-
rank: position of the field in the fields
-
requiredType: field type
-
selectorType: Defines the selector type (input) use for the field.
-
i18n: is field internationalized
-
readOnly: If true the field is set as read only.
-
multiple: is field multiple
-
mandatory: If true the field is marked as mandatory.
-
valueConstraints: Array of constraints applied on the field.
-
defaultValues: Array of default values.
Known limitations
- The properties multiple and I18n can not be overridden by JSON definition. As the definition does not allow to have multiple values or internationalized values, there will be an error when you will try to save the data in the JCR.
- The property valueConstraints for choicelists can only be overridden partially. You can remove some existing items, but you can not add new items: the definition does not override the validation logic, and there will be an error when you will try to save the data in the JCR.
Moving fields
Field can be moved by adding it into another section / fields set. Rank will define where the field will appear compared to others.
A field will always appear at most once in a form - the form override that declare a field, which have the highest priority, will define where the field will appear.
The following will move the jcr:title
field in a field set and the system name in another field set, for all nodes of type jnt:page
:
{
"nodeType": "jnt:page",
"priority": 4.0,
"sections": [
{
"name": "content",
"fieldSets": [
{
"name": "title-field-set",
"label": "Title here",
"rank": 0.0,
"fields": [
{
"name": "jcr:title"
}
]
},
{
"name": "new-field-set-2",
"rank": 0.1,
"fields": [
{
"name": "ce:systemName"
}
]
}
]
}, {
"name": "metadata",
"fieldSets": [
{
"name": "name-field-set",
"label": "System name here",
"rank": 0.0,
"fields": [
{
"name": "ce:systemName"
}
]
}
]
}
]
}
Displaying a hidden property
Hidden properties are not displayed by default. However, this behavior can be overridden by using:
"hide": false
Note: If the property is not declared on the primary nodetype, nor inherited, then you need to use declaringNodeType as well, to specify which node type provides the property. E.g.:
"name": "j:invalidLanguages",
"declaringNodeType": "jmix:i18n"
"hide": false