Skip to main content

Data Modeling

Title, Name, and Description#

By convention shape names should be singular. For example, a shape representing articles should be title "Article". Entering the title "Article" will also fill in the name "article". What's the difference?

  • Title - User-facing identifier for your shape
  • Name - API identifier for your shape (getArticle, createArticle, updateArticle, etc)
  • Description - A user-facing explanation of a shapes's purpose. The description appears in several places in the UI.

Built-in Data Storage#

In TakeShape, data modeling is as open-ended as possible. That said, you create your shapes to fulfill a specific use-case. Your Built-in Data Storage choice describes how you plan to use your shape. There are three possible Built-in Data Storage options:


Not persisted in built-in data storage. Useful to represent data returned from connected services, like SearchResults. Also useful for data structures inside of other shapes, like ProductDetails.


Denotes a single item or singleton in programming terminology. Persist a single instance of this shape. Useful for creating shapes like Navigation or Settings.


Denotes multiple items. This is the default setting. Useful for creating shapes like Products or Posts.


Denotes a shape which is used to organize others. A taxonomy can be used to filter data entries it has relationships with, like Categories or Tags.

Annotating a shape as a "Taxonomy" allows the relationships between data entries to be surfaced to users when filtering in the asset views and entry list views.

Taxonomies appear in the sidebar in their own section under "Multiple' shapes.

A good taxonomy is something you'll use to classify other thing. Tags, Categories, Topics, Subjects, Genres, and even Authors. Right now the way a taxonomy is used in the UI is to help filter lists.

A taxonomy is effectively a multiple shape that we treat slightly differently on the backend. You can switch a multiple shape to a taxonomy and vice-versa at will.

Taxonomies treat their first text field as their “term” field. This is what will be used for auto suggest.


Data modeling is drag and drop:

Simply drag the appropriate widgets from the palette on the left to the form on the right. The underlying data type of each field is inferred from the widgets you choose. 

Best Practices for fields#

  • Put your identifying fields first. Field order is important because it informs how TakeShape generates previews of your data for list views, relationships and taxonomies. Examples of identifying fields are "Title", "Name", "Headline", etc.
  • Make at least one field required.  


Block Canvas#

TakeShape's "rich text" field. See Block Canvas docs for more detail.

Block canvas fields automatically add a corresponding [blockCanvasFieldName]Html field to the API. For example a field named foo will have a corresponding fooHtml field.

  • foo returns raw DraftJS JSON
  • fooHtml - return rendered to HTML

The html field accepts the following parameters to customize the output:


A string that will prefix HTML class names in the output.


A string that will prefix the id attributes of header elements in the output.


An imgix configuration object for the default image size.

query {  home {    fooHtml(imageConfig: {w: 100, h: 100})  }}

Allows you to specify imgix configurations for the default, small, medium, and large images sizes.

query {  home {    fooHtml(images: {default: {w: 100, h: 100}})  }}

Returned image urls will have width and height parameters added to the query string: [...]example.jpg?h=100&w=100.

Single Line Canvas#

A single line rich text field. 


Markdown field with preview that uses the CommonMark flavor of markdown.


A multi-line plain text field.

Single Line#

A single line plain text field.


Similar to a single line text field but with some special features specific to content slugs.

When you create a slug property, you can select a Single Line Text field as a source property. When new content is created, the slug field is automatically filled out based on a slugified version of the text in the source property using the slugg npm package. The slug field content can be unlocked, allowing you to use a custom slug value instead.


A slug cannot set its source to a property in a repeater unless the slug is in the same repeater. This avoids ambiguity about what the slug content should be.


Relationships are a fundamental part of modeling data in TakeShape they allow data items to reference one another. You can think of them as foreign keys in RDBMS or Associations from Rails, but as you'll see TakeShape's relationships are much more powerful. 

Single Relationships#

When creating a relationship the first step is to choose what shape you want to allow in the relationship: 

Unlike traditional foreign keys TakeShape allows you to create relationships that allow references to multiple shapes.

Multiple Relationships#

Multiple relationships can be thought of as an array of single relationships. In addition, relationships can can be ordered. Ordering makes multiple relationships a very powerful tool when building data entries that need to be manually curated.

Reverse Relationships#

When a relationship is created a reverse relationship is automatically added to the related shape. For example if you add a relationship to a Book type that points to the Author type, a reverse relationship property called bookSet will automatically appear on Author.

There are cases where the name of this reverse relationship property becomes ambiguous. For example, a Post type with two relationships authors and editors which both point to the Person type. The automatically generated field postSet is now ambiguous because it will contain both authors and editors. The solution is to specify the "Reverse Name" on each relationship. 

In order to disambiguate these relationships set the "Reverse Name" for authors to "authored" and the "Reverse Name"  for editors to  "edited" 

relatedName not set, so "postSet" used automatically
{  getAuthor(_id: "author_id") {    postSet {      total      results {        title      }    }  }}
Disambiguated by setting relatedName to "edited"
{  getAuthor(_id: "author_id") {    authored {      total      results {        title      }    }    edited {      total      results {        title      }    }  }}


Store several values under single property. A common use for an object is modeling an address:

Shape Object#

An object with properties defined by one of N shapes (ex, 1 dog or 1 cat)

Sample GraphQL query of Shape Object field named "shapeObject"
query {  getDogOrCat {    shapeObject {      ... on Cat {        name        lives      }      ... on Dog {        name        isBestFriend      }    }  }}


An array of N length of one shape (ex, 5 animals [{aninmal}, {aninmal}, {aninmal}, {aninmal}, {animal}])

Shape Array#

An array of N length of N shapes (ex, 2 cats and 3 dogs [{cat}, {dog}, {cat}, {dog}, {dog}])

Sample GraphQL query of Shape Array field named "shapeArray"
query {  getPetStore {    shapeArray {      ... on Cat {        name        lives      }      ... on Dog {        name        isBestFriend      }    }  }}


A color picker which stores the selected color in RGB, HEX, HSV

Sample GraphQL query for a color field named "color"
query {    color {      hex      hsl {        a        h        l        s      }      hsv {        a        h        s        v      }      rgb {        a        b        g        r      }    }}


A Date and time picker.


A Date picker where the time defaults to midnight in your project's selected timezone. See "How TakeShape handles dates" for more detail.


Pick an Asset from your project's Asset Library.

Sample GraphQL query for an field named "photo"
query {    photo {      caption      credit      description      filename      mimeType      path      title    }}


A number field which can be setup to accept integer or floating point numbers.


A single selection dropdown menu.

Radio Buttons#

Single selection radio buttons.

Multiple Choice Checkbox#

A set of checkboxes which

On/Off Checkbox#

A single checkbox boolean


Simple switch boolean.