Configurable headless CMS for complex content structures.
- Node.js (>= 16.16.0)
- npm (>= 8.11.0)
- PostgreSQL (>= 9.4)
- Node.js & npm: https://nodejs.org/en/download/
- PostgreSQL: https://www.postgresql.org/download/
- Clone this repo
- Run
npm installin the repo directory - Create a database in PostgreSQL
- Application is configured via environment variables contained in a file named
.env. Use the.env.examplefile as a template:cp .env.example .envand enter configuration details. - Initialize database by running
npm run db migrate - To enable demo repository schema configuration copy
tailor.config.js.exampleintotailor.config.js.. For more details about the custom schema configuration please refer to this guide. - Configure asset storage proxy by following the steps in this guide based on your environment.
- You can create admin user by running
npm run add:admin <email> <password> - App branding is configured via values set in a file named
.brandrc.js. Use the.brandrc.js.examplefile as a template:cp .brandrc.js.example .brandrc.jsand enter configuration details (Optional).
- Server:
npm run dev:server - Client (webpack dev server):
npm run dev:client
This project uses a monorepo setup. In order to contribute to packages following commands should be executed:
- Run
npm run packages:setup- initial setup, dependency installation, package linking, etc. This command should be executed only a single time. - Run
npm run packages:build- build all packages. Run this command after altering the package's code. - Run
npm run packages:build --package=<package-name>to build only specified package. For example:npm run packages:build --package=core-components.
- Bundle client by issuing
npm run build npm run start
Repository structure can be altered using tailor configuration file, which must be placed inside the root
directory and named tailor.config.js.
Use the tailor.config.js.example file as a template:
$ cp tailor.config.js.example tailor.config.js
and enter the configuration details. At the current time, it is not possible to override the filename or location of the configuration file.
Content repository structures are defined using the following properties:
An array of Schema objects.
- id
String- Schema identifier. - name
String- Schema display name. - workflowId
String- Workflow identifier. - meta
Array<Metadata>- An array of objects defining repository metadata. - structure
Array<ActivityConfig>- An array of objects which define schema structure. - contentContainers
Array<ContentContainer>- Array of content container configs. - elementMeta
Array<ElementMetaConfig>- An array of objects defining content element metadata.
Configuration for schema structure nodes (activities). Contains the following properties:
- type
String- Const for marking activity type. - rootLevel
Boolean- Used to define first level (root) activity types - subLevels
Array<String>- An array of sub-types. - label
String- Display label. - color
String- Display color in hexadecimal notation. - isTrackedInWorkflow
Boolean- Defines whether the workflow status will be tracked for this activity type. - contentContainers
Array<String>- Array of content container types that define which content containers can be added. - hasExams
Boolean- Activity allows adding exam activities to it. - exams
Object- Configuration for activity exams. - relationships
Array<ActivityRelationship>- Defines what relationships this activity has to other activities. - meta
Array<Metadata>- An array of objects defining activity metadata.
Defines the structure of the activity relationship field.
- type
String- Defines the name of the relationship. The relationship will be published under this value. - label
String- Display label. - placeholder
String- Display label for the select picker. - multiple
Boolean- Defines if the relationship can have multiple associations chosen. True by default. - searchable
Boolean- Defines if the list of activities can be searched. True by default. - allowEmpty
Boolean- Defines if the member list can be empty. True by default. - allowCircularLinks
Boolean- Defines if a member of the relationship instance can set the owner of that instance as a member of its own instance of that relationship. Example, activity X sets activity Y as its prerequisite. IfallowCircualLinksis set to true then activity Y can set activity X as its prerequisite. False by default. - allowInsideLineage
Boolean- Defines if an ancestor or a descendant can be a member of the relationship. False by default. - allowedTypes
Array<String>- Defines activity types that can be associated in a relationship.
Defines the structure of the activity metadata field.
- key
String- Unique key for the field. - type
String- Type of the input component used on the client. - label
String- Display label. - placeholder
String- Input component placeholder. - validate
MetadataValidator- Validator object. - defaultValue
*- Default field value.
Defines validation rules on an activity metadata field.
- rules
Object- Contains the following properties: - max
Number- Maximum character count. - required
Boolean- Defines if the field is required.
An array of ContentContainer objects.
Configuration for content containers. Contains the following properties:
- type
String-const-casedstring for markingContentContainertype. - templateId
String-const-casedstring that defines which customContentContaineris used to display this container. Needs to match thetemplateIdproperty of the desired customContentContainer. If not specified the defaultContentContaineris used to display this container. - label
String- String used for referencingContentContaineron the UI. - multiple
Boolean- Defines if there can be multiple instances of theContentContainerinside a singleActivity. False by default. - types
Array<String>- An array of possible content element types that can exist inside aContentContainer. If not specified all types of elements are allowed. - displayHeading
Boolean- Defines if a heading is displayed on top of theContentContainer. False by default. - layout
Boolean- Defines if elements inside aContentContainerinstance can be placed two in a row. True by default. - config
Object- DefinesContentContainerspecific properties. - required
Boolean- Defines if an instance of theContentContaineris created if non exist. True by default. - publishedAs
String- Defines the name of the file under which the container will be published. Defaults tocontainer. The name of the structure component used is thekebab-casedversion of thetypeproperty. (example: ABC_DEF -> abc-def)
Defines the structure of an content element metadata.
- type
String- Type of content element (example: "IMAGE", "HTML"). - inputs
Array<ElementMeta>- Defines what meta fields content element has. - relationships
Array<ElementRelationship>- Defines what relationship metadata content element has (relationships with content elements from the same or other activities in the repository).
Defines the structure of an content element relationship field.
- key
String- Defines the name of the relationship. The relationship will be published under this value. - label
String- Display label. - placeholder
String- Label for relationship add button and modal title. - multiple
Boolean- Defines if the relationship can have multiple associations chosen. True by default. - allowedTypes
Array<String>- Defines to what type of content elements given content element can have relationship with (example:['VIDEO']).
Defines what meta fields content element has.
- key
String- Unique key for the field. - type
String- Type of the input component used on the client. - label
String- Display label. - description
String- Description of meta field. - options
Array<Object>- Options for certain types of input component. For example, for select component, options would be:"type": "SELECT" "options": [{ "label": "First", "value": "first" }, { "label": "Second", "value": "second" }]
A string template that will be interpolated on the client using two route
params, repositoryId and activityId, into a preview URL for each activity.
Example:
https://my.url.com/#/repository/{repositoryId}/activity/{activityId}/preview
For each schema, workflow can be defined to enable users to track and assign activities which are flagged for tracking. Each workflow is defined by a set of statuses that the activity can have.
Workflows are assigned to schemas through schema's workflowId option in tailor configuration file.
Workflows are configured with the following options in the tailor configuration file:
An array of Workflow objects.
Defines activity statuses for repository workflow. Workflow can be reused across multiple schemas by assigning the same workflow ID to schema's workflowId option.
- id
String- Workflow identifier. - statuses
Array<ActivityStatus>- An array of possible activity statuses. - dueDateWarningThreshold
Object- Defines threshold (in days, weeks or months) relative to activity's due date, after which the warning of upcoming due date is displayed.
- id
String- Activity status identifier. - label
String- Display label. - color
String- Display color. - default
Boolean- Defines that the status is the default, which the activity has when it's created.
Tailor supports creation of custom content elements and custom containers. These extensions can have unique content and structure that the default content elements and containers do not support. The template for creating custom content elements can be found here while the template for creating custom containers can be found here.
- copy (or git clone) extension files in
extensions/content-<elements or containers>/<my-extension-name> - create index.js file in
extensions/content-<elements or containers>directory - in the file from the previous step add
module.exports = ['my-extension-name'];Note that module.exports is an array and you can add as many extensions and just include their folder names in this array to include all of them.
After installation, the extension is ready for use and should be listed in tailor.config.js file.