TTWeb Basics 2. Content Model Definitions

Models are defined in the _data/_definitions directory in JSON format.

Field Properties

{
  "field_name": {
    "type": <field_type>,
    "label": <label_string>,
    "instructions": <instructions_string>,
    "placeholder": <placeholder_string>,
    "hint": <hint_string>,
    "required": <false | true>,
    "multiple": <false | true>,
    "default_text": <default_select_text_string>,
    "options": <options_array>,
    "fields": <model_definition>,
    "model_name": <model_name_string>,
    "display_field": <model_field_name_string>,
    "localizable": <false | true>,
    "can_create": <false | true>,
  }
}

Underscores (_) in the field name is converted to a space when generated by the CMS (e.g. page_title becomes Page title).

type

Specifies what type of data this field will contain. Type is case insensitive but please use lowercase. See Field Types for a full list of available types

label

The label that will appear in model instance management. If this field isn’t specified, the field name will be passed through the rails humanize method and used.

instructions

Instruction text to be displayed above the UI for the field’s editor.

placeholder

Placeholder text for inputs of type “text” or “string” - shown inside the input.

hint

This tooltip is displayed by the field label in the model instance management screens.

required

(default: false) When true, will create a validation error if the instance form is submitted with this field blank.

multiple

(default: false) When true and the field type is “select”, or “enum” this indicates that multiple selections are allowed and a set of checkboxes will be generated. (TBD) When true and field type is “complex”, it will generate a form for an instance that allows for adding and removing instances of this field. The data submitted in this field for an instance will be an array of hashes.

default_text

Specifies the text for the first (blank) item in a drop down. Used only for “select” types with “multiple” set to false.

options

The options for fields of type “select” or “enum”, structured as an array of strings or a hash of locale-array pairs

Example: [“option1”,”option2”,”option3”] or { “en”: [“option1”,”option2”,”option3”], “es”: [“es-option1”,”es-option2”,”es-option3”]}

localizable

Whether or not this field has separate values for each locale. See Localizing Content Models for more details.

character_limit

When type is “string” or “text”, this allows you to specify the max length of the text that should be provided. It will display the limit along with a running count of characters the user has entered into the field. If the user goes over the limit, the count is displayed in red but does not prevent a user from saving the model instance.

can_create

When type is “model”, this specifies whether you can create a new instance of the referenced model while editing the current model. For example, if you have a posts model with a field post_category with type: model if you specify can_create: true, the user will be able to create new instances of post_category while editing a post.

fields

The field definitions used by “complex” and “nested” types. Structured identically to a model definition. Note: multi-word fields should not include spaces. For example, use: “my_field_name” rather than “my field name”. See the authors example below.

A more complex example

Lets add an author field to the news model we created above. We’ll represent authors with a new model so that we can auto generate pages for their biographies and article listings.

First, lets define the author model:

authors.json

{
  "name": {
    "required": true
  },
  "signature": {
    "instructions": "Author's one line description"
  },
  "bio": {
    "type": "text",
    "required": true,
    "instructions": "Write a short description of this author."
  },
  "image": {
    "type": "image",
    "required": true,
    "instructions": "Select an photo for the author"
  },
  "awards": {
     "type": "nested",
     "multiple": true,
     "fields": {
        "name": {
           "required": true,
        },
        "date": {
           "type": "date"
        }
      }
   }
}

and now we can modify the news model to reference the author model we’ve just created:

news.json

{
  "title": {
    "required": true
  },
  "url_friendly_name": {
    "type": "url_slug"
  },
  "contents": {
    "type": "text",
    "required": true,
    "instructions": "Write the content of your news article."
  },
  "author": {
    "type": "model",
    "model_name": "authors",
    "display_field": "name",
    "multiple": false,
    "default_text": "Pick an Author"
  }
}

When a content editor creates or modifies a news article, they’ll be able to assign a single author instance to the article. It’s important that the referenced model exists before creating the model field in the definition. If the model doesn’t exist and someone attempts to create an instance, the model management form will throw an error.

Field Types

"string"

This is the default field type. It will render a text field in the editor UI.

"text"

Plain text field rendered as textarea tag in the editor UI.

"richtext"

Generates a rich text editor. Note: RTE linking requires URL strings and does not support built in link selection.

"model"

A reference to another model instance. Generates a dropdown or set of checkboxes (depending on whether “multiple” is true). Requires “model_name” to be set to a valid model and “model_display_field” to be set to a valid field name in that model. “model_display_field” will be used as the text representing the instance in the dropdown or checkbox set.

Here’s an abbreviated example for a Blog Post model defintion:

{
  "title": {
    "label": "Post Title",
    "required": true,
    "localizable": true
  },
  "category": {
    "label": "Choose Category",
    "type": "model",
    "display_field": "name",
    "model_name": "post_categories",
    "multiple": false,
    "can_create": true
  },
}

And the related post_categories.json model definition:

{
  "name": {
    "label": "Category Name",
    "required": true,
    "localizable": true
  },
  "url_friendly_name": {
    "type": "url_slug",
    "label": "URL Friendly Name",
    "required": true,
    "localizable": true
  }
}

In this example the “category” field for the blog post specifies “post_categories” as the model name which matches the post_categories.json model definition. And it specifies “name” as the display_field. When the editor for a blog post is rendered, it will show a drop down with each post_category item using the value of the “name” field as the option label in the dropdown. Since can_create is true it will also show an additional “Add New” item in the dropdown. When clicked, this will allow a user to create a new instances of post_categories via a modal form.

When the item is saved, the json data will only contain the ID for the referrenced model. E.g. "post_categories1". When rendering in liquid, the filed will contain the full object. E.g. you can use ``

"url_slug"

Used in the url path when auto-generating pages based on models. Only one field of this type can be used per model definition. When instances are created, uniqueness will be validated. If this field is not specified, auto-generated ids will be used instead. Underscores will not error (even though they shouldn’t be used), but spaces will:

url_slug error

"integer"

If data is not blank, will validate that the entry is an integer

"float"

If data is not blank, will validate that the entry is a number

"date"

If data is not blank, will validate that the entry is a date.

"date_time", "datetime"

If data is not blank, will validate that the entry is a date-time.

"select", "enum"

If data is not blank, will validate that the selections are included in the list of items in the “options” key If “multiple” is false it will generate a dropdown. The “blank” selection for the drop-down will be the value specified by the “default_text” key. If “multiple” is true it will generate a set of checkboxes.

"bool", "boolean"

Will generate a check box. Data in the item json file will be stored as true or false

"nested", "complex"

Will generate a group of form fields according to the “fields” option above. This field’s instance data will be a hash, or, more commonly, an array of hashes (when multiple is set to true).

"location"

This will generate a search-box that uses google places autocomplete. Users can enter addresses, places (like a store or restaurant or monument), or even just city names. Data in the item’s json file will look like:

{
  name: <place name from google place result>,
  address: <formatted_address from google place result>,
  phone: <formatted_phone_number from google place result>,
  place_id: <place_id from google place result>,
  reference: <reference value from google place result>,
  latitude: <geometry/location/lat value from google place result>,
  longitude: <geometry/location/lng value from google place result>,
  google_place: <the entire goolge place result - see link below>,
}

See https://developers.google.com/places/web-service/details for the data available from a google place details result

"color"

This will generate a color picker and store the value as a hex code.

"page"

This will generate a dropdown (either or single or multi-value) that shows all the pages in the site.

This will generate a dropdown (either or single or multi-value) that shows all the galleries in the site.

"order"

This will generate a number input in the field and allow for the model instance list page to be sorted. By default the sorting interface will show the model instance “name” in the list of draggable items (the same values as on primary list page). You can override this with the display_field property. If the display_field is a field of type image, the sorting interface will use image thumbnails for ordering. You can have more than one field of type: order in the list. For example:

{
  "name": {},
  "example_image": { "type": "image" },
  "primary_order": {
    "type": "order"
  },
  "special_order": {
    "type": "order",
    "display_field": "example_image"
  }
}

For that model definition, the model instance list page will show a drop down for “Order By:” with both “Primary Order” and “Special Order” as options. When a user chooses “Primary Order” they will see a sortable list of model instances with the “name” field displayed. If they choose “Special Order”, they’ll see a sortable list of instances with image thumbnails displayed. The main item list page will also show a sorting column for each “type”: “order” field so the user can view the current order for each type of sorting without having to go into the sorting interface.