Custom field types

Learn how custom field types affect the fields' display and indexing


💡 8 min read

Info

Custom fields are an intermediate/advanced topic.


Sometimes you have a need to add fields on a resource beyond the pre-defined ones. These fields will be indexed for later searching.

Guillotina, the application server used by the Onna platform, allows you to add fields of different types to a behavior.

Onna maps these fields as shown below:

DYNAMIC_FIELDS_MAPPING = {"properties":
							{"name": {"type": "keyword"},
							 "date": {"type": "date" },
							 "integer": {"type": "integer" },
							 "float": {"type": "float" },
							 "boolean": {"type": "boolean" },
							 "text": {"type": "text", "analyzer": "lowercase_keyword" },
							 "keyword": {"type": "keyword" }
							}
						}
1
2
3
4
5
6
7
8
9
10

There are 5 types of custom fields. These affect the display and indexing for the fields:

In practice, you'll add a user-defined field that is one of the above types to your account. You can then enable that field on a particular resource, such as a workspace or file. Once the field is enabled, you can populate it.

Account administrators can dynamically add fields to workspaces and files. These custom fields are indexed and can assist in providing additional user controlled search criteria.

Custom fields are set at the account level and then enabled for a particular resource.

# Requirements

Make sure that you're authenticated with your Onna instance.

  • You'll need access to the curl command to follow the examples below.
  • You'll need your access token when you run the curl commands below.

Info

You can get your token from the Inspector tools in Google Chrome, Firefox, Safari.

Inspect XHR calls and look in the header for the bearer token.

Check our Postman article if you need more info about how to lookup your token in Firefox or Chrome.

  • You'll also need to have administrator privileges to the Onna account to add custom fields.
  • Also, make sure you know your account URL, the container name and the account name so that you can populate base_url, container, and account.

# Creation

Custom fields are always created with a PATCH command to the @setAccountFields endpoint.

A sample PATCH command will look like the following:

curl 'https://{base_url}/api/{container}/{account}/@setAccountFields' -X PATCH -H 'authorization: Bearer {token}' -H 'content-type: application/json' -H 'accept: application/json' --data-binary '{"@behaviors":["guillotina.behaviors.dynamic.IDynamicFields"],"guillotina.behaviors.dynamic.IDynamicFields":{"fields":{"op":"update","value":[{"key":"cf-region","value":{"title":"Region","type":"keyword","meta":{"widget":{"fieldType":"keyword","type":"dropdown","title":"Dropdown","hasDescription":false,"hasRange":false},"values":["APAC","EMEA","Global","LATAM","NORAM"]},"description":"workspace.fields.dropdown-default-description","required":true}}]}}}' --compressed
1

The body of the patch is composed of "@behaviors" which will always be:

["guillotina.behaviors.dynamic.IDynamicFields"]` and "guillotina.behaviors.dynamic.IDynamicFields".
1

Info

For more information on the underlying concepts behind this implementation of dynamic fields, please see:

Within guillotina.behaviors.dynamic.IDynamicFields, there is one property for fields. This has the op property with a value of update and the value property that changes based on your field.

The value has a key and value property.

The key is in the format: cf-{fieldname}. This field name must be unique and lower case with no spaces.

In the value, there are the properties: title, type, meta, description, and required.

Title is the display title of the field. Type is keyword, except for the number type which is float For description, this will display with the fields and is a string. For dropdowns, this should be set to "workspace.fields.dropdown-default-description". Required is a boolean.

For the meta property there is the widget property and the values:

  • fieldType is the same value as Type.
  • type for dropdown is dropdown,
  • for text and long text is text,
  • for free tags is badges,
  • for number is number
  • title, is the same as the title above.
  • hasDescription is false for Dropdown, true for the rest
  • has Range is false for all non-number types
  • for Number, with a range there can be a "min" and "max"
  • for Dropdown, there is a values property with a list of string values
{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{
      "op":"update",
      "value":[
        {
          "key":"cf-region",
          "value":{
            "title":"Region",
            "type":"keyword",
            "meta":{
              "widget":{
                "fieldType":"keyword",
                "type":"dropdown",
                "title":"Dropdown",
                "hasDescription":false,
                "hasRange":false
              },
              "values":[
                "APAC",
                "EMEA",
                "Global",
                "LATAM",
                "NORAM"
              ]
            },
            "description":"workspace.fields.dropdown-default-description",
            "required":true
          }
        }
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# Free tags

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{
      "op":"update",
      "value":[
        {
          "key":"cf-freetags",
          "value":{
            "title":"Free Tags",
            "type":"keyword",
            "meta":{
              "widget":{
                "fieldType":"keyword",
                "type":"badges",
                "title":"Free tags",
                "hasDescription":true,
                "hasRange":false
              }
            },
            "description":"Free Tags Description",
            "required":false
          }
        }
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# Text

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{
      "op":"update",
      "value":[
        {
          "key":"cf-exampletextwithoutdescription",
          "value":{
            "title":"Example Text without Description",
            "type":"keyword",
            "meta":{
              "widget":{
                "fieldType":"keyword",
                "type":"text",
                "title":"Text",
                "hasDescription":true,
                "hasRange":false
              }
            },
            "description":"",
            "required":false
          }
        }
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# Long text

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{
      "op":"update",
      "value":[
        {
          "key":"cf-longtext",
          "value":{
            "title":"Long Text",
            "type":"keyword",
            "meta":{
              "widget":{
                "fieldType":"keyword",
                "type":"text",
                "title":"Text",
                "hasDescription":true,
                "hasRange":false
              }
            },
            "description":"",
            "required":false
          }
        }
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# Number

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{
      "op":"update",
      "value":[
        {
          "key":"cf-samplenumber",
          "value":{
            "title":"Sample Number",
            "type":"float",
            "meta":{
              "widget":{
                "fieldType":"float",
                "type":"number",
                "title":"Number",
                "hasDescription":true,
                "hasRange":true
              },
              "min":0,
              "max":1000
            },
            "description":"",
            "required":false
          }
        }
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Custom fields are then associated to a workspace at either the workspace or document level.

To associate a custom field to a workspace use the @setAccountFields endpoint.

In the curl command below, you'll add a dropdown field cf-region with the values "APAC","EMEA","Global","LATAM".

curl 'https://{base_url}/api/rel0/account1/@setAccountFields' -X PATCH -H 'pragma: no-cache' -H 'cache-control: no-cache' -H 'accept: application/json' -H 'sec-fetch-dest: empty' -H 'authorization: Bearer {token}  -H 'content-type: application/json' -H 'sec-fetch-site: same-origin' -H 'sec-fetch-mode: cors'-H 'accept-language: en-US,en;q=0.9' --data-binary '{"@behaviors":["guillotina.behaviors.dynamic.IDynamicFields"],"guillotina.behaviors.dynamic.IDynamicFields":{"fields":{"op":"update","value":[{"key":"cf-region","value":{"title":"Region","type":"keyword","meta":{"widget":{"fieldType":"keyword","type":"dropdown","title":"Dropdown","hasDescription":false,"hasRange":false},"values":["APAC","EMEA","Global","LATAM"]},"description":"workspace.fields.dropdown-default-description","required":false}}]}}}' --compressed
1

Other fields are listed below.

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{
      "cf-region":{
        "title":"Region",
        "description":"workspace.fields.dropdown-default-description",
        "type":"keyword",
        "required":false,
        "meta":{
          "widget":{
            "fieldType":"keyword",
            "type":"dropdown",
            "title":"Dropdown",
            "hasDescription":false,
            "hasRange":false
          },
          "values":[
            "APAC",
            "EMEA",
            "Global",
            "LATAM"
          ],
          "scope":{
            "workspace":true,
            "file":false
          }
        },
        "usage_count":0
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

In addition, the scope field determines whether the field is available at the workspace or file level.

When adding an additional field, all fields must be included, not only the new additions.

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{
      "cf-region":{
        "title":"Region",
        "description":"workspace.fields.dropdown-default-description",
        "type":"keyword",
        "required":false,
        "meta":{
          "widget":{
            "fieldType":"keyword",
            "type":"dropdown",
            "title":"Dropdown",
            "hasDescription":false,
            "hasRange":false
          },
          "values":[
            "APAC",
            "EMEA",
            "Global",
            "LATAM"
          ],
          "scope":{
            "workspace":true,
            "file":false
          },
          "disabled":false
        }
      },
      "cf-longtext":{
        "title":"Long Text",
        "description":"",
        "type":"keyword",
        "required":false,
        "meta":{
          "widget":{
            "fieldType":"keyword",
            "type":"text",
            "title":"Text",
            "hasDescription":true,
            "hasRange":false
          },
          "scope":{
            "workspace":true,
            "file":false
          }
        },
        "usage_count":0
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

When a field that is already on the workspace and is added to the document, the scope is updated.

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{
      "cf-region":{
        "title":"Region",
        "description":"workspace.fields.dropdown-default-description",
        "type":"keyword",
        "required":false,
        "meta":{
          "widget":{
            "fieldType":"keyword",
            "type":"dropdown",
            "title":"Dropdown",
            "hasDescription":false,
            "hasRange":false
          },
          "values":[
            "APAC",
            "EMEA",
            "Global",
            "LATAM"
          ],
          "scope":{
            "workspace":true,
            "file":false
          },
          "disabled":false
        }
      },
      "cf-longtext":{
        "title":"Long Text",
        "description":"",
        "type":"keyword",
        "required":false,
        "meta":{
          "widget":{
            "fieldType":"keyword",
            "type":"text",
            "title":"Text",
            "hasDescription":true,
            "hasRange":false
          },
          "scope":{
            "workspace":true,
            "file":true
          }
        },
        "usage_count":0
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

The existing fields on a workspace are retrieved with a call to:

curl 'https://{base_url}/api/{container}/{account}/workspaces/{workspace_id}?include=guillotina.behaviors.dynamic.IDynamicFields' -H 'pragma: no-cache' -H 'cache-control: no-cache' -H 'accept: application/json' -H 'sec-fetch-dest: empty' -H 'authorization: Bearer {token}' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Safari/537.36' -H 'dnt: 1' -H 'content-type: application/json' -H 'sec-fetch-site: same-origin' -H 'sec-fetch-mode: cors' -H 'accept-language: en-US,en;q=0.9' --compressed
1

The call includes the behavior guillotina.behaviors.dynamic.IDynamicFields and the custom fields will be in that property "guillotina.behaviors.dynamic.IDynamicFields" in the response.

# Editing

Only the description and requirements fields are editable on existing custom fields.

# Deleting

Custom fields can be deleted from the platform, but documents and workspaces with that custom field set will have that custom field remain, though it will not be searchable.

The field may also be removed at the workspace level.

To delete a custom field from the api run the @getAccountFields command and then the PATCH to@setAccountFields` with the body:

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFields"
  ],
  "guillotina.behaviors.dynamic.IDynamicFields":{
    "fields":{

    }
  }
}
1
2
3
4
5
6
7
8
9
10

With all of the fields in the fields property, except for the one you want to remove from the platform.

# Removing a field from a Workspace

Run a PATCH on the workspace to no longer include the field desired within that workspace’s custom fields.

If you are removing all custom fields the body will look like this:

{"@behaviors":["guillotina.behaviors.dynamic.IDynamicFields"],"guillotina.behaviors.dynamic.IDynamicFields":{"fields":{}}}
1

# Adding a custom field value

Run a Patch command on the resource with the key and value to update.

{
  "@behaviors":[
    "guillotina.behaviors.dynamic.IDynamicFieldValues"
  ],
  "guillotina.behaviors.dynamic.IDynamicFieldValues":{
    "values":{
      "op":"update",
      "value":[
        {
          "key":"cf-region",
          "value":"EMEA"
        }
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

The “key” value must be associated with the file or workspace, before adding a value to it.

Last Updated: 11/27/2020, 9:12:36 AM