Documentation
Publish

Anchor link Requirements

Anchor link Setting up

The easiest way to install Publish is using DADI CLI. CLI is a command line application that can be used to create and maintain installations of DADI products.

There are two ways to create a new Publish installation with the CLI: either manually create a new directory for Publish or let CLI handle that for you. DADI CLI accepts an argument for project-name which it uses to create a directory for the installation.

Manual directory creation

$ mkdir my-publish
$ cd my-publish
$ npx dadi-cli publish new

Automatic directory creation

$ npx dadi-cli publish new my-publish
$ cd my-publish

DADI CLI will install the latest version of Publish and copy a set of files to your chosen directory so you can launch Publish immediately.

Installing DADI Publish directly from NPM

All DADI platform microservices are also available from NPM. To add Publish to an existing project as a dependency:

$ cd my-existing-node-app
$ npm install --save @dadi/publish

Anchor link Application anatomy

When CLI finishes creating your Publish installation, the application directory will contain the basic requirements for launching Publish. The following directories and files have been created for you:

my-publish/
  config/              # contains environment-specific configuration files
    config.development.json
  server.js            # the entry point for the application
  package.json

Anchor link Configuration

Publish reads a series of configuration parameters to define its behaviour and to adapt to each environment it runs in. These parameters are defined in JSON files placed inside the config/ directory, named as config.{ENVIRONMENT}.json, where {ENVIRONMENT} is the value of the NODE_ENV environment variable. In practice, this allows you to have different configuration parameters for when Publish is running in development, production and any staging, QA or anything in between, as per the requirements of your development workflow.

Some configuration parameters also have corresponding environment variables, which will override whatever value is set in the configuration file.

The following table shows a list of all the available configuration parameters.

Path Description Environment variable Default Format
apis Connected APIs (see Adding an API) Array
app.name The name of the application DADI Publish (Repo Default) String
app.publisher The name of the organisation the application belongs to DADI String
cdn.publicUrl The host of the URL where the CDN instance can be publicly reached
env The application runtime environment NODE_ENV development String
formats.date.long The specifier to use when displaying dates in long format YYYY/MM/DD HH:mm String
formats.date.short The specifier to use when displaying dates in short format YYYY/MM/DD String
ga.enabled If true, the collection of Google Analytics events is enabled false Boolean
ga.trackingId A Google Analytics tracking ID String
publicUrl.host The hostname of the URL where the Publish instance can be publicly reached URL_HOST String
publicUrl.port The port of the URL where the Publish instance can be publicly reached URL_PORT Number
publicUrl.protocol The protocol of the URL where the Publish instance can be publicly reached URL_PROTOCOL http String
server.host The IP address or interface to bind to 0.0.0.0 String
server.port The port to bind to 3001 Number
server.protocol The protocol the application will use PROTOCOL http String
server.redirectPort Port from which to redirect HTTP connections to HTTPS 0 Number
server.sslPrivateKeyPath The path to a SSL private key SSL_PRIVATE_KEY_PATH String
server.sslCertificatePath The path to a SSL certificate SSL_CERTIFICATE_PATH String
server.sslPassphrase The passphrase of the SSL private key SSL_PRIVATE_KEY_PASSPHRASE String
server.sslIntermediateCertificatePath The path to a SSL intermediate certificate, if any SSL_INTERMEDIATE_CERTIFICATE_PATH String
server.sslIntermediateCertificatePaths The paths to SSL intermediate certificates, overrides sslIntermediateCertificate (singular) SSL_INTERMEDIATE_CERTIFICATE_PATHS Array
server.healthcheck If enabled, Publish continuously checks the connection with the server using the server.healthcheck.frequency setting as the interval between checks "healthcheck": { "enabled": true, "frequency": 15000 }
server.healthcheck.enabled If true, the health check service is enabled true Boolean
server.healthcheck.frequency Interval between health checks, in milliseconds 2000 Number
logging.enabled If true, logging is enabled using the following settings. true Boolean
logging.level Sets the logging level. info String. Must be one of debug, info, warn, error, trace
logging.path The absolute or relative path to the directory for log files. ./log String
logging.filename The name to use for the log file, without extension. publish String
logging.extension The extension to use for the log file. log String
logging.accessLog.enabled If true, HTTP access logging is enabled. The log file name is similar to the setting used for normal logging, with the addition of \"access\". For example publish.access.log. true Boolean
whitelabel Customisation options for displaying a different logo and background images "whitelabel":\{"backgroundImage": "", "logo": "", "poweredBy": true}
whitelabel.backgroundImage The path to a file to use as the background image String
whitelabel.logo The path to a file to use as the logo String
whitelabel.poweredBy If true, displays a "Powered by DADI Publish" section false Boolean

Anchor link Launching the application

After configuring the application, you can start the Publish server by entering its directory and running npm start. You should see in the console a message similar to the one below, confirming that the application is now running and telling you what is the host and port you should use to access it.

✔ Started @dadi/publish
@ http://localhost:3003

  ┌──────────────────────────────────────────┐
  │ DADI Publish - Publisher Name            │
  ┌──────────────┬───────────────────────────┐
  │ Version      │ 2.0.0                     │
  │ Node.js      │ 8.12                      │
  │ Environment  │ development               │
  └──────────────┴───────────────────────────┘


  ℹ Documentation at https://docs.dadi.cloud
  ℹ <CTRL> + C to shut down


   ▓▓▓▓▓  ▓▓▓▓▓▓▓
               ▓▓▓▓
      ▓▓▓▓▓▓▓    ▓▓▓▓
               ▓▓▓▓
          ▓▓▓▓▓▓▓


  © 2018 DADI+ Limited (https://dadi.cloud)
  All rights reserved.

To access the application, open the URL above in your browser.

Anchor link Adding an API

If you access the application without configuring an API, you'll see an error message telling you that your instance of Publish hasn't been configured. To fix that, create a new API if you don't have one already and add its details (host and port) to the apis block of your Publish configuration file.

{
  "apis": [
    {
      "host": "https://api.somedomain.tech",
      "port": 443
    }
  ]
}

After doing so, restart the application and the error message should be gone.

To sign in, you must have a username and password, which you can obtain by creating an API client if you don't have one already. If you do, type the client's ID and secret into the username and password fields to authenticate with Publish.

Anchor link Configuring an API

Anchor link Navigation menu

Publish displays a navigation menu containing the collections returned from the connected API. By default, the navigation items are in the order received from the API.

The configuration file allows a menu property that can be used to customise the navigation menu in two ways:

  1. by modifiying the order of items, and
  2. by creating menu groups to keep related collections together.

The following menu configuration is used to render the navigation menu as shown below. Notice that any collections not specified in the menu configuration are displayed in alphabetical order after the explicitly configured menu items.

"menu": [
  {
    "title": "Content",
    "collections": [
      "pages",
      "team"
    ]
  },
  {
    "title": "Taxonomy",
    "collections": [
      "categories",
      "sub-categories",
      "milestones"
    ]
  }
]

Menu

Anchor link Extending collection settings

Publish has been designed in such a way that it can connect to an existing instance of DADI API and work right out of the box, without requiring any additional configuration. Optionally, it can use a variety of extended field values to enhance the user interface and aid with document operations. These fields are defined in an optional publish object that can be added to the settings block of any collection schema.

The following table shows a list of available properties.

Property Description Example Default
hidden Hides a collection from the navigation menu true false

By default, the navigation menu will display all collections that the user has access to. If you need to hide a specific collection from the menu, add a publish.hidden property to the collection's settings block.

In the below example, the publish block in the collection settings instructs Publish to hide this particular collection from the navigation menu.

{
  "fields": {
    "title": {
      "type": "String"
    }
  },
  "settings": {
    "publish": {
      "hidden": true
    }
  }
}

Anchor link Extending field settings

Similarly to extending collection settings, it's also possible to extend the functionality of individual fields in a collection schema. This can be done by adding an optional publish block to the object that defines a field within the collection schema.

The following table shows a list of available properties.

Property Description Example Default
section The tabbed section this field should be displayed in "Details" "General"
placement The location of the field within the document view, options are "main" and "sidebar" "main" "sidebar"
display.list If true, the field is displayed in the document list view true true
display.edit If true, the field is displayed in the document edit view true true
readonly If true, the field is not editable in the document edit view true false
multiline If true, String fields are rendered with a multiline textarea rather than a text input true false
options Limits the content of the field to a fixed set of values. It's defined as an array of objects containing value and label properties. When used with the String field, a dropdown is rendered [{"value": "uk", "label": "United Kingdom"}] N/A
multiple Defines whether the field allows multiple values. When used with the String field and options is defined, a multi-select dropdown is rendered true false
limit Defines the maximum number of values allowed in the field. Overrides multiple 10 1
subType Defines an optional subType for the field. Image None

In the below example, the publish block for the title field instructs Publish to:

"fields": {
  "title": {
    "type": "String",
    "label": "Title",
    "required": true,
    "publish": {
      "section": "General",
      "placement": "main",
      "display": {
        "list": true,
        "edit": true
      }
    }
  }
}

Anchor link Listing documents

Clicking on a collection on the navigation menu leads to the document list view, where it's possible to browse all the documents within a collection.

A table will display all the documents in the collection, with a column for each field and a row for each document. Clicking on the first field of a row takes users to the edit view, where it's possible to view and edit the corresponding document.

Document list

Anchor link Showing and hiding fields

By default, all fields in the collection (that the user has access to) will be shown in the table, sorted by their order of appearance in the collection schema. When the collection has a large number of fields, this may not be desirable.

For that reason, it's possible to specify which fields are shown in this view by annotating the field settings block. To hide a particular field, set publish.display.list to false in its configuration block.

"fields": {
  "notInteresting": {
    "type": "String",
    "publish": {
      "display": {
        "list": false
      }
    }
  }
}

It's important to note that setting this property to false acts as a blacklist: except for the ones explicitly excluded, all fields will be displayed, even the ones without a display.list property or a publish block.

Conversely, when at least one of the fields has this property set to true, the logic is reversed and the principle of a whitelist applies, meaning that only fields with display.list explicitly set to true will be shown.

Pagination

Publish automatically separates documents into pages and includes controls on the bottom toolbar to navigate between them: you can click on Prev or Next to go to the previous or next page, click on a specific page number or type the page number on the Go to page input.

The number of documents that are shown for each page is determined by API, not Publish. It can configured by changing the count property in the collection settings.

Anchor link Sorting

It's possible to sort documents by any field shown in the table by clicking on the corresponding table header. Once a field has been selected, it's possible to change the sort order (ascending or descending) by clicking on the same header.

Anchor link Bulk actions

Each row shows a checkbox on the leftmost part of the row. This can be used to make a selection of documents and perform actions on them as a group. When a selection is made, the dropdown labelled as With selected on the bottom toolbar will be unlocked, showing all the bulk actions available.

After selecting one, clicking the Apply button confirms the operation.

Anchor link Filtering

Publish offers a selection of filters that makes it possible to search for specific documents in the collection, or define a list of criteria for narrowing down the document set displayed.

The quickest way to add a filter is to use the search bar on the top-left corner of the screen, labelled with Search [collection name]. As you type, a dropdown will allow you to quickly select the field to search in. Only fields of type String will be shown in this view.

Search

To filter by fields of other types, or to add more complex filters including operators like does not equal or a literal match, click the Add filter button on the top-right corner.

The currently applied filters will be shown next to the search bar. Click on an individual filter to edit it, or hit X to remove it.

Anchor link Editing documents

Clicking on a document in the document list view leads to the document edit view, where it's possible to view the full content of a document as well as make changes to it.

Anchor link Showing and hiding fields

By default, all fields in the collection (that the user has access to) will be shown in the editing interface, but it's possible to change this behaviour by annotating the field settings block. To hide a particular field, set publish.display.edit to false in its configuration block.

"fields": {
  "notInteresting": {
    "type": "String",
    "publish": {
      "display": {
        "edit": false
      }
    }
  }
}

It's important to note that setting this property to false acts as a blacklist: except for the ones explicitly excluded, all fields will be displayed, even the ones without a display.edit property or a publish block.

Conversely, when at least one of the fields has this property set to true, the logic is reversed and the principle of a whitelist applies, meaning that only fields with display.edit explicitly set to true will be shown.

Anchor link Organising fields into sections

To avoid a cluttered interface when a collection has a large number of fields and to make fields easier to find, it's possible to group fields into tabbed sections by annotating the field with a section property within the field settings block. Each section will appear as a tab at the top of the document edit view.

The example below places the title field in a section called Details and the isbn field in a section called Meta.

"title": {
  "publish": {
    "section": "Details"
  }
},
"isbn": {
  "publish": {
    "section": "Meta"
  }
}

Section property

If no fields have an assigned section, no tabs will be shown and all fields will be grouped together in a single page. If at least one field has an assigned section, any fields without a section will be placed in a section called Other.

Anchor link Changing field placement

Another level of customisation for the editing interface is the ability to control which part of the editing interface a field appears in. With the placement property within the field settings block, it's possible to place fields in the main column, by setting the property to "main", or in the sidebar, with the value "sidebar".

The main column takes up two thirds of the horizontal space, whilst the sidebar fills up the remaining third.

"title": {
  "publish": {
    "section": "Details",
    "placement": "main"
  }
},
"slug": {
  "publish": {
    "section": "Details",
    "placement": "sidebar"
  }
}

Placement property

When a placement property isn't defined, fields will be placed in the main column.

Anchor link Field labels

Each field is identified by a label placed on the top-left corner of its container. By default, this is populated by the name of the field as it is defined in the collection schema, which is usually not an optimal value since this value was designed as a machine-friendly slug (e.g. it cannot contain spaces or non-alphanumeric characters).

It's possible to customise this name by specifying a label property in the field definition block.

"jobDescription": {
  "type": "String",
  "label": "Job Description"
}

Field label

Anchor link Field comments

In situations where it may not be obvious what the field should contain, or what format the input is expected to be in, it's possible to define a comment that will be displayed on the top-right corner of the field. This can be done by adding a comment property to the field definition block.

"jobDescription": {
  "type": "String",
  "label": "Job Description",
  "comment": "What does the person do?"
}

Field comment

Anchor link Validation

Publish will validate fields as per the validation rules defined in the collection schema. These rules can be as simple as marking a field as required, or specifying a strict pattern that values must comply with, such as an email address.

When a field is failing the validation rules, its background changes to a light red and a message is shown indicating what the error is. If the field is part of a tabbed section, a warning icon will appear next to the tab.

Field validation

The interface will not let users save the document until all validation errors are corrected.

Anchor link Read-only fields

A collection might have fields whose value is generated by a third-party application or even by API itself – for example, a hook that generates a URL-friendly slug from a human-friendly title. In these cases, it's useful to show this field in the editing interface, but not allow editors to change its value.

This is possible with the readonly property in the field settings block.

"slug": {
  "type": "String",
  "publish": {
    "readonly": true
  }
}

Read-only fields

Anchor link Creating documents

To create a new document, select the collection using the navigation menu and click on the Create new button on the top-right corner. You'll be taken to the same editing interface described in Editing documents.

Anchor link Enhanced fields

Publish knows how to render most of the primitive field types supported by DADI API. String fields will be rendered as text inputs, Boolean as checkboxes, etc. Whilst these should be enough to cover most situations, other components are included with the application, offering editors more optimal ways of controlling certain field types.

Anchor link Colour

When a colour is stored as a hexadecimal code in a String field, it's possible to render a colour picker with a palette and hue selectors, as well as a small colour swatch next to the field value.

To enable it, define a subType property with the value of "Color" within the field settings block.

"color": {
  "type": "String",
  "label": "Colour",
  "publish": {
    "subType": "Color"
  }
}

Colour field

Anchor link Images

The recommended way of referencing an image is by using a field of type Media, in which case Publish automatically renders a component that allows users to select any item from the media library, or upload new images using drag and drop or the operating system's file selector.

Image field

For backwards-compatibility, it's also possible to render the same interface when using a Reference field, by providing a subType property with the value of "Media".

"image": {
  "type": "Reference",
  "settings": {
    "collection": "mediaStore"
  },
  "publish": {
    "subType": "Media"
  }
}

Anchor link Rich editor

A String field can declare what format it expects its input to be in (e.g. plain text, HTML, Markdown, etc.), using the format property in the field definition block. For some of these formats (currently limited to Markdown), Publish can offer a rich editor with formatting controls.

"body": {
  "type": "String",
  "label": "Body",
  "format": "markdown"
}

Rich editor

Anchor link Media library

Publish seamlessly integrates with DADI API's support for media files and provides a set of views that allow you view, edit and create new media items.

Anchor link Listing media items

In addition to all configured collections, the navigation menu contains a link to the Media Library. In there, a grid view shows all the available media items. Similarly to the document list view, clicking on an individual item leads to the editing interface and selecting multiple items allows you to perform bulk actions on them.

It's also possible to add new items to the media library straight from this view, by dragging an item onto the drop area at the top of the grid or clicking the Select files to launch the operating system's file explorer.

Media list view

Anchor link Editing media items

Clicking on an individual media item brings up the media editing interface, which has a similar layout to the document editing interface. A preview of the file is shown, if one can be rendered, and some metadata that is automatically added by API is shown on the sidebar, such as the MIME type, file size and URL.

This interface also includes some additional metadata fields that can be edited, such as caption, alt text or copyright information.

Media edit view