Creating a Json File
Content types are defined by using a JSON file. This guide shows you how to define a content type using a JSON document.
Preparationsβ
- To be able to create a content type, you need a text editor - ideally with structuring features for the .json format like VS Code, Sublime Text or Notepad++
- To integrate the content type into a workbook, you need the iCL Designer.
- To upload the content type to the iCL Portal website, you need an account with administrator permissions.
JSON Basicsβ
You can start a blank text file and save its data type to .json or edit an existing one and save it as a new .json file.
The JSON format is used to define the fields and features a content type has. Every time you add a new item of that content type, it is stored as a row in a data table, every field being a column of that table.
A content types JSON file defines several properties, some are optional, depending on the intended use or complexity. Further topics will explain the structure and options one by one.
JSON Structureβ
Every content type requires at least some basic parameters.
Some of them are optional and will get added automatically with a standard value after the upload to the iCL Portal like "icon", "version", "builtinTypeId" and "formTemplate"
This shows an easy example of a basic content type with two text and a number field.
{
"$type": "contentType",
"name": "ct_objects",
"displayName": "Content Type Name",
"titleFieldName": "obj_nr",
"titleFieldExpression": "<%obj_nr%> - <%obj_address%>"
"id": "73ee4c51-d99a-4596-9533-2bea4e0c65c5",
"builtinTypeId": 0,
"icon": "",
"version": 1,
"fields": [
{
"$type": "contentType",
"name": "obj_nr",
"displayName": "Object Number",
"isRequired": true
},
{
"$type": "contentType",
"name": "obj_address",
"displayName": "Object Address",
},
{
"$type": "contentType",
"type": "Number",
"name": "obj_floors",
"displayName": "Object Floors",
}
],
"relationships": [],
"formTemplate": {}
}
JSON Sectionsβ
There are different sections within the content type, some of them are optional or will be automatically generated.
In the fields
bracket all existing content type fields will be defined. (Such as name
, address
, price
, serial-number
or whatever you need as a storable value)
Sometimes a content type is related to another one. For example, a content type elevator
might belong to a building
. These relations are defined in the relations
brackets.
The formTemplate
defines the form that is displayed to the user, when adding or editing items of that type. If omitted, a basic template will be generated automatically when uploading the content type to iCL Portal. Sometimes, however, you will want to modify the template. For example, if a dropdown selection is required for a certain field, you can define it in here.
When customizing the formTemplate
, you do not have to define all fields. Just define the one field that you would like to change. When uploading the json file with the incomplete formTemplate
to iCL Portal, it will notice that and fill in the missing fields for you.
Required JSON Attributesβ
These attributes are mandatory to make the content type work.
Property | Parameter | Description |
---|---|---|
"$type": | "contentType" | A property to define the json as a content type. |
"name": | "name_of_the_ct" | The unique name of the content type for the database - all lowercase, no spaces allowed (use _ instead). |
"displayName": | "Content Type Example" | The displayed name of the content type in the iCL Portal - Uppercase and spaces allowed. |
"id": | "12345678-90ab-cdef-1234-567890abcdef" | The unique identifier GUID (a 32 digit code) for the content type. It cannot exist twice on the iCL Portal, so it has to be unique for every content type used. |
"titleFieldName": | "most_unique_field" | When a content type lists all its data records (the so called content items), the titleFieldName defines the title shown for the data record. It uses the name of a field defined in the "fields": [] section and the referenced field has to be set to required. |
"fields": | [] | In the fields brackets, all the fields will be defined for the content type. It must have at least one required text field, which is connected with the titleFieldName parameter. |
The title field is important: Whenever you use a drop-down to select a content item, the iCL system needs to populate that dropdown with some meaningful text that allows the user to identify a particular item. For this, the titleFieldName
is used, which is connected to a text field that needs to be required
.
Another sample is when a related content item has to be shown in a data grid. For example, an elevator
points to its building
, so the data grid of elevator
needs to display something in the "Building" column. This is another use case of the titleField
For each content type's field, a database column is created. By default, that column is not indexed.
If you want to be able to sort and filter by a field, you need to set the isIndexed
property to true
.
This will create an index for that column in the database, which will allow for faster sorting and filtering.
However, use this only where needed, as too many indexes can cause editing/updating items to become very slow.
Without index:
With index:
This behavior can be disabled using the following setting
Optional Content Type Propertiesβ
These properties will get a standard value, if not used, or just be ignored.
Property | Parameter | Description |
---|---|---|
"titleFieldExpression": | "ObjNr.: <%objectnumer%> <%fieldname%>" | To get a more detailed list of entries, you can extend the title of the content item here by creating a more complex combination of text and fields. |
"builtinTypeId": | 0 or 6 | This property sets the type of the content type. 0 is the standard value and adds the "isInspectable" quality to it. With a value of 6 it is defined as a defect content type, which needs a reference to a parent content type with the builtinTypeId 0. |
"icon": | "" | Reserved for future use - please leave empty. |
"version": | 1 | Reserved for future use - please leave empty. |
"relationships": | [] | Define relations to other content types here. If there is no reference to another content type needed, this can be left out. |
"formTemplate": | {} | If no specific dropdown field is required for the iCL Portal, this can be left out. |
Fieldsβ
Within the fields brackets, all the fields of the content type will be defined. If not specified otherwise, a field is a simple text field and may look like this:
{
"$type": "contentField",
"name": "building_address",
"displayName": "Building Address"
}
Field Propertiesβ
The following properties define a content field:
Property | Parameter | Mandatory | Description |
---|---|---|---|
"$type": | "contentField" | x | The $type is always "contentField" . |
"name": | "lowercase_and_underscore" | x | The name has to be unique and consists of lowercase letters. Use _ instead of spaces. |
"displayName": | "This is my Title" | x | The displayName is used as the title of the entry. Uppercase and Space allowed. |
"type": | "Text" | The type (without the $) defines the datatype of the field. If unused, it is set as a text field by default. Other parameters are the following: | |
"Number" | Turns the field into a number field. | ||
"Date" | A Date format to store date values (including time) | ||
"Time" | Allows you to save times (hours:minutes) | ||
"ContentItem" | The field is able to store a reference to another content type. | ||
"FileEntry" | File entry fields are able to store images. | ||
"Plan" | |||
"isRequired": | true or false | By default, fields are not required to have a value - so you only need to set this if you want the field to be mandatory. | |
"isIndexed": | true or false | The default value is set to false . If set to true , users can search and sort - e.g. in the datagrid - using those fields. β Use this sparingly, though, as too many indexes can cause editing/updating items to become very slow. | |
"builtInField": | "ParentContentItemId" | A content type with the "builtinTypeId": 6 requires a parent content type to be defined. The parent content type is the one that the defect belongs to. It is stored in a content field of type ContentItem and needs to specify this property. | |
"ExternalId" | A field with this parameter is considered as the reference field, where every entry has to be unique. | ||
"Status" | The iCL System treats defect content types in a special way: In certain screens, it will allow to sort and filter them by their status. For this to work, however, you need to map a content field of type Number - representing the state of the defect - to the builtInField: Status . |
Relationshipsβ
Relationships are connections to other content types. The parent content type must have "builtinTypeId": 0
.
Every content type with a "builtinTypeId": 6
needs a reference to its 'parent' content type, which is established in two ways: a field of "type": "contentItem"
and a "relationships": {}
section which creates a references to that content item field.
Reference Fieldβ
If you build a relation to another content type in the relationships area, you also need a field with the "type": "ContentItem"
property to store it's reference.
Use a name and title for this field, which makes it clear that it is a reference. Like "obj_id" as name for a stored reference id of a content type called "Object". The _id suffix helps identifying such reference fields, if you stick to that standard.
The field definition may look like this:
{
"$type": "contentField",
"type": "ContentItem",
"name": "obj_id",
"displayName": "Object ID"
}
If the current content type is a defect ("builtinTypeId": 6
) type, you additionally need the "builtinField": "ParentContentItemId"
property for that field:
{
"$type": "contentField",
"type": "ContentItem",
"name": "obj_id",
"displayName": "Object ID"
"builtinField": "ParentContentItemId"
}
You can set this builtinField
parameter in only one ContentItem field.
Relationships Sectionβ
All relations to another content types will be defined in the relationships section, which is structured as follows:
"relationships": [
{
"$type": "contentRelationship",
"name": "obj_ref",
"displayName": "Object Ref",
"foreignKeyField": "obj_id",
"targetContentType": {
"$type": "contentTypeRef",
"id": "21429549-7b35-4cb1-bd6a-ac4f5ea9fbb8",
"version": 1
}
}
]
A reference needs to be defined with a name
and displayName
as every other part of the content type definition.
Beside that, it has to reference to a field of "type:" "ContentItem"
in the "fields": []
section and additionally it has to know the unique id (Guid) of the content type, to which this reference is pointing to. You will find the GUID in the "id":
parameter of that other JSON file.
Property | Parameter | Description |
---|---|---|
"$type": | "contentRelationship" | This never changes. |
"name" | "obj_ref" | The name of this relation object. Best practice: use the name of the field, where the content type will be stored at and attach a _ref to it. |
"displayName" | "Object Ref" | The title of this relationship - since it isn't displayed anywhere, it doesn't matter much. |
"foreinKeyField" | "obj_id" | The name of the field, where the reference will be stored (it has the "type": "ContentItem" property). |
"targetContentType": {} | $type: "contentTypeRef" | This never changes. |
"id:" "12345678-abcd-4321-9876543210ab" | The GUID of the content type, to which the reference is pointing at. | |
"version": 1 | This never changes. |
You can add more than one reference by opening a new {}
section within the "relationships": []
brackets, seperated with a comma like this:
"relationships": [
{
"$type": "contentRelationship",
"name": "obj_ref",
"displayName": "Object Ref",
"foreignKeyField": "obj_id",
"targetContentType": {
"$type": "contentTypeRef",
"id": "12345678-abcd-4321-9876543210ab",
"version": 1
}
},
{
"$type": "contentRelationship",
"name": "items_ref",
"displayName": "Items Ref",
"foreignKeyField": "items_id",
"targetContentType": {
"$type": "contentTypeRef",
"id": "87654321-dcba-4321-ba0123456789",
"version": 1
}
}
]