A webapp UI which allows browsing/editing the json content served by the acms-api service.
Copy config.json.template into /public/config.json and change values accordingly. config.jsonis served by webpack dev server or provided in a production environment.
acmsAssetsUri: Fully qualified URI to a WebDav enabled server, acms-assets.
acmsApiUri: Fully qualified URI to the acms-api service.
acmsConfigPath: Relative directory path inside the acms-config to the ACMS UI configuration JSON file (usually acmsConfig, see below).
Create a configuration file (e.g. acmsConfig.json) inside the acms-config repo:
The user management is not safe and only meant to provide convenience views on the content. Its possible to filter fields and children by path (see users/permissions) to filter internal data.
This application uses Redux Toolkit. For the best debugging experience, install the Redux DevTools Chrome Extension. It allows you to inspect the state, replay actions, and trace changes without needing redux-logger.
Template files specify the structure of the content data while the actual values are located in the content directory. Every template entity can have children which themself are structured by a template. Nested templates within the templates directory are referenced via local path. E.g.:
/templates/template1.json // => `template1`
/templates/template2.json // => `template2`
/templates/template3/index.json // => `template3`
/templates/template3/template4.json // => `template3/template4`
{
"fields": [
// optional list of fields
{
"id": "title", // unique id within the whole template
"name": "Main Title", // optional display name shown in the ACMS UI, default startCase(id)
"type": "string", // field type see below
"maxLength": 8, // optional type specific properties
"localization": ["en", "ar"], // optional localization
"preview": "https://previewer.de/?fieldValue=${value}", // optional preview link
},
{
"id": "enabled",
"name": "Page Enabled",
"type": "boolean",
},
{
"id": "numLoops",
"name": "Number of Loops performed",
"type": "number",
"integer": true,
},
],
"fixedChildren": [
// optional list of fixed/named children
{
"id": "frontScreen", // unique id within the whole template
"name": "Front of the Entry", // optional display name shown in the ACMS UI, default startCase(id)
"template": "location", // template id/path
},
{
"id": "backScreen",
"name": "Back of the Entry",
"template": "location",
},
],
"children": [
// optional list of of allowed templates for the children
"template1",
"template2",
],
"enabledField": "enabled", // optional field reference defining if the instance is shown enabled or disabled in its parent children list
"subtitleField": "title", // optional field reference defining a subtitle shown in its parent children list
}The following field types are supported:
An uploadable asset which is stored on the asset server with a unique (hashed) filename.
Example:
{
"id": "bachelorThesis",
"name": "Bachelor Thesis",
"type": "file",
"allowedMimeTypes": ["application/pdf"], // optional list of allowed mime types
}An uploadable asset which is stored on the asset server with a unique (hashed) filename
allowedMimeTypes: optional list of allowed mime types, default:["image/*"]width: optional width of the imageminWidth: optional minimum width of the imagemaxWidth: optional maximum width of the imageheight: optional height of the imageminHeight: optional minimum height of the imagemaxHeight: optional maximum height of the imageaspectRatio: optional aspect ratio of the image
Example:
{
"id": "coverImage",
"name": "Front Cover Image",
"type": "image",
"allowedMimeTypes": ["image/jpeg", "image/png"],
"width": 1920,
"minWidth": 800,
"maxWidth": 2200,
"height": 1080,
"minHeight": 800,
"maxHeight": 1600,
"aspectRatio": "16:9",
}A string type with the following otional properties:
multiline: Defines wether the string can have multiple lines, default:falsemaxLength: Defines the maximum number of characters, default:Infinity
Example:
{
"id": "label",
"name": "Start Label",
"type": "string",
"maxLength": 32,
"multiline": true,
}A number type with the following optional properties:
min: The minimum value, default-Infinitymax: The maximum value, defaultInfinityinteger: Defines wether the number is an integer, default:false
Example:
{
"id": "numLoops",
"name": "Number of loops",
"type": "number",
"min": 0,
"max": 100,
}A geolocation type with values for lat (Latitude) and long (Longitude).
min: The minimum value, defaultlat: -90,long: -180max: The maximum value, defaultlat: 90,long: 180
Example:
{
"id": "location",
"type": "geolocation",
}A boolean either being true or false.
Example:
{
"id": "active",
"name": "Active State",
"type": "boolean",
}A list of selectable values.
Example:
{
"id": "myEnum",
"name": "My Enum Type",
"type": "enum",
"values": [
{
"value": "value1",
"name": "First Value",
},
{
"value": [2, 3, 4],
"name": "Second Value",
},
{
"value": {
"thirdValue": "thirdValue",
},
"name": "Third Value",
},
{
"value": true,
"name": "Fourth Value",
},
{
"value": "no name",
},
],
}Note: As shown in the last entry of the values array, the name property is not required. The displayed name will then be generated based on the type of value.
It is possible to hide/show fields in the CMS frontend depending on sibling fields value. A typical case is an enum field which specifies a layout type (e.g. videoCover/imageCover). Based on the field value you want to either show an image or video field. This can be achieved with the following GETand EQUALS operators:
{
"id": "layoutType",
"type": "enum",
"values": ["videoCover", "imageCover"]
},
{
"id": "coverVideo",
"type": "video",
"condition": [ "EQUALS", [ "GET", "layoutType" ], "videoCover" ]
},
{
"id": "coverImage",
"type": "image",
"condition": [ "EQUALS", [ "GET", "layoutType" ], "imageCover" ]
}If several values should be considered you can use the IN and LIST operator:
{
"id": "coverVideo",
"type": "string",
"condition": ["IN", ["GET", "layoutType"], ["LIST", "videoCover", "imageCover"]],
}
{ "title": "ACMS", // title shown in the header, default: null "logoImageUri": "https://assets/logo.jpg", // logo shown in the header, default: null "contentPath": "content", // root directory containing the content data, default: "content" "templatesPath": "templates", // root directory containing the (nested) template files, default: "templates" "childrenLabel": "Children", // label shown above the children, default: "Children" "fieldsLabel": "Fields", // label shown above the fields, default: "Fields" "saveLabel": "Save", // label of the save button, default: "Save" "textDirection": "ltr", // optional text direction for non localized text, default: "ltr", see https://developer.mozilla.org/de/docs/Web/CSS/ "languages": [ // optional language configuration { "id": "en", // unique language id (e.g. "en"), see language subtag registry: https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry "name": "English", // language name, default: id "textDirection": "ltr", // direction of the text, default: "ltr", see https://developer.mozilla.org/de/docs/Web/CSS/direction }, ], "users": [ // list of users, default: shown here { "id": "admin", // unique user id "name": "Admin", // user name, default: id "permissions": { // permission settings, default: shown here "include": [ "**", // list of glob patterns defining which fields to include, default: shown here ], "exclude": [], // list of glob patterns defining which fields to exclude, default: shown here }, }, ], "customTypes": { // a collection of custom types with preconfigured properties, the custom type id can be used in templates "myCustomString": { "type": "string", "maxLength": 123, "multiline": true, }, }, }