Skip to main content
Home  ›  Blog

Deep Dive: JSON Content-Type Definitions

Just about everything in 2sxc is a content-item (entity). Each item has a content-type, which defines what fields exist. This type-definition can be stored in the DB, but as of 2sxc 9.8 will often also be stored as JSON files in the file-system. Let's learn about these.

JSON Content-Types

In 2sxc 9.8 we introduced a new way to define content-types, as JSON files. The idea is that these JSON files are stored in the file system instead of the DB. This makes it easier to compare changes and to distribute new features (as opposed to installing a content-type in the DB). Here's an example of the @string-dropdown content-type, which tells the EAV-system what fields can be configured for a dropdown field:

Full JSON the UI-Configuration for drop-down fields

{
    "_": {
        "V": 1
    },
    "ContentType": {
        "Id": "@string-dropdown",
        "Name": "@string-dropdown",
        "Scope": "System",
        "Description": "Dropdown string-input configuration",
        "Attributes": [
            {
                "Name": "DropdownValues",
                "Type": "String",
                "IsTitle": true,
                "Metadata": [
                    {
                        "Id": 41667,
                        "Version": 4,
                        "Guid": "5bd40264-ef9e-4eab-b093-b3b620e8ac63",
                        "Type": {
                            "Name": "@All",
                            "Id": "@All"
                        },
                        "Attributes": {
                            "String": {
                                "CustomJavaScript": {
                                    "*": ""
                                },
                                "DefaultValue": {
                                    "*": "Simple Value\nAnother Value\nLeft (will store an l):l\nRight (will store an r):r\nCenter (... c):c\nMiddle:m"
                                },
                                "InputType": {
                                    "*": "string-default"
                                },
                                "Name": {
                                    "*": "Values"
                                },
                                "Notes": {
                                    "*": "<p>Type in the values, one per line and separate keys:values with a \":\". </p>\n<p><strong>Example 1</strong><br />\n(none):\n<br />\nLeft:l\n<br />\nRight:r\n<br />\nTop:t</p>\n<p><strong>Example 2</strong><br />\nMIT License:MIT<br />\nGUN Licnese:GNU<br />\nGPL-3 with mentioning of Author:GPL-3-BY</p>"
                                },
                                "ValidationRegExJavaScript": {
                                    "*": ""
                                }
                            },
                            "Boolean": {
                                "Disabled": {
                                    "*": false
                                },
                                "Required": {
                                    "*": false
                                },
                                "VisibleInEditUI": {
                                    "*": true
                                }
                            }
                        },
                        "Owner": "dnn:userid=1"
                    },
                    {
                        "Id": 41668,
                        "Version": 4,
                        "Guid": "ef9d3d36-afdd-4994-be14-701d42f175c3",
                        "Type": {
                            "Name": "@String",
                            "Id": "@String"
                        },
                        "Attributes": {},
                        "Owner": "dnn:userid=1"
                    },
                    {
                        "Id": 41669,
                        "Version": 4,
                        "Guid": "ad7b7c85-4eee-400e-beda-a30befb455e4",
                        "Type": {
                            "Name": "@string-default",
                            "Id": "@string-default"
                        },
                        "Attributes": {
                            "Number": {
                                "RowCount": {
                                    "*": 12.0
                                }
                            }
                        },
                        "Owner": "dnn:userid=1"
                    }
                ]
            },
            {
                "Name": "EnableTextEntry",
                "Type": "Boolean",
                "IsTitle": false,
                "Metadata": [
                    {
                        "Id": 41679,
                        "Version": 4,
                        "Guid": "148087de-0e4a-4003-9909-ea4c548cfa74",
                        "Type": {
                            "Name": "@All",
                            "Id": "@All"
                        },
                        "Attributes": {
                            "String": {
                                "CustomJavaScript": {
                                    "*": ""
                                },
                                "DefaultValue": {
                                    "*": "false"
                                },
                                "InputType": {
                                    "*": "boolean-default"
                                },
                                "Name": {
                                    "*": "Enable Free Text"
                                },
                                "Notes": {
                                    "*": "<p>Allow users to type other things than are in the drop-down. Two common situations for this: <ul><li>situations where the drop-down will suggest typical values, but others are also possible</li> <li>Situations where you need tokens like [Parameter:Category] which will later be resolved to a real value</li></ul></p>"
                                },
                                "ValidationRegExJavaScript": {
                                    "*": ""
                                }
                            },
                            "Boolean": {
                                "Disabled": {
                                    "*": false
                                },
                                "Required": {
                                    "*": false
                                },
                                "VisibleInEditUI": {
                                    "*": true
                                }
                            }
                        },
                        "Owner": "dnn:userid=1"
                    },
                    {
                        "Id": 41682,
                        "Version": 3,
                        "Guid": "8399706a-0a6c-4f58-b816-04a2272295f3",
                        "Type": {
                            "Name": "@Boolean",
                            "Id": "@Boolean"
                        },
                        "Attributes": {},
                        "Owner": "dnn:userid=1"
                    }
                ]
            }
        ],
        "Metadata": [
            {
                "Id": 41685,
                "Version": 3,
                "Guid": "8b606bc8-ea55-4c5c-a7cb-d886a6a751b1",
                "Type": {
                    "Name": "ContentType",
                    "Id": "ContentType"
                },
                "Attributes": {
                    "String": {
                        "Description": {
                            "*": "standard drop-down with text entries"
                        },
                        "EditInstructions": {
                            "*": "<p>To discover more about the drop-down type, consult the <a href=\"https://github.com/2sic/2sxc/wiki/ui-field-string-dropdown\" target=\"_blank\" rel=\"noopener\">wiki</a>.</p>"
                        },
                        "Label": {
                            "*": "drop-down"
                        },
                        "Notes": {
                            "*": ""
                        }
                    },
                    "Hyperlink": {
                        "Icon": {
                            "*": ""
                        },
                        "Link": {
                            "*": "https://github.com/2sic/2sxc/wiki/ui-field-string-dropdown"
                        }
                    }
                },
                "Owner": "dnn:userid=1",
                "For": {
                    "Target": "ContentType",
                    "String": "@string-dropdown"
                }
            }
        ]
    }
}

JSON Format for Content-Types

The format is currently in version 1, and looks like this:

  • _ this is the header - containing the version, in case we introduce breaking changes in the future
  • ContentType - this is the content-type
    • Id - internal identifier, also known as the "static name" - often a GUID
    • Name - a nicer name, especially when the Id is a GUID
    • Scope - a term which groups types together; mainly for hiding types the user should normally not see 
    • Description - a short description for internal use
    • Attributes [array]
      • [item]
        • Name - the field-name
        • Type - the primary type, like string, number, etc.
        • Description - a short description
        • IsTitle - is this the title field (there must always be one title field)
        • Metadata [array] of content-items with more information about this field
    • Metadata [array] of content-items with more information about the content-type

Specials of the JSON Content-Types

ID is not always a GUID

The ID is usually a GUID, but for special system types it is not. This is mostly historic, as all new content-types will have GUIDs, but old types still exist in the system which have a nice name, but that's not ideal for various use cases. 

Scope is Like a Virtual Group

The Scope is a name - usually System or something like that. It's primarily used to group types together, so that the editor doesn't have to see the ca. 50 types in the background which make the solution work. 

Attributes Have Metadata

Each attribute - let's say a field "Color" has more information which is needed for scenarios like the edit-UI. These items are standard Entity-items and also have the very same format as JSON entities - you can read about that in this blog.

Content Types Have Metadata

Content-types can have a lot of metadata - also mostly for the UI. An example is the help-text which is shown. This too is stored as normal JSON entities. 

Creating JSON Content-Types

As of 2sxc 9.10 you can export any existing content-type as such a JSON-file, in the export-dialog: 

Then you'll need to go into advanced mode (Ctrl+Click anywhere)

...and you now have a text-file containing the JSON Content-Type Definition.

TL;DR

Happy coding...

Daniel


Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 800 DNN projects since 1999. He is also chief architect of 2sxc (see github), an open source module for creating attractive content and DNN Apps.

Read more posts by Daniel Mettler