References

References provide a way for you to link two definitions together so as to reuse one of the definitions in the other. It gives you a way to centrally define something and then have that something's schema get reused in other definitions in your content model.

For example, suppose you have an my:author definition that looks like this:

{
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string",
            "title": "First Name"
        },
        "lastName": {
            "type": "string",
            "title": "Last Name"
        }
    }
}

So far, pretty straight forward, nothing terribly exciting.

Now imagine that we have a my:article type in which we want to store author information. One way we could do it is like this:

{
    "type": "object",
    "properties": {
        "title": {
            "type": "string",
            "title": "Title"
        },
        "body": {
            "type": "string",
            "title": "Body"
        },
        "author": {
            "type": "object",
            "properties": {
                "firstName": {
                    "type": "string",
                    "title": "First Name"
                },
                "lastName": {
                    "type": "string",
                    "title": "Last Name"
                }
            }
        }
    }
}

Certainly this works but Cloud CMS gives us a better way to do it using the $ref operator.

We can write the same schema like this:

{
    "type": "object",
    "properties": {
        "title": {
            "type": "string",
            "title": "Title"
        },
        "body": {
            "type": "string",
            "title": "Body"
        },
        "author": {
            "$ref": "qname://my/author"
        }
    }
}

The $ref operator gives us a way to tell JSON Schema to load an object literal's value from some other place. The qname:// prefix on the $ref tells Cloud CMS that you wish to load another definition from the current branch. The specific structure is:

qname://{namespace}/{localName}

Where namespace and localName are the components of your definition's QName - i.e. my:author

Reference Loaders

Cloud CMS references support three types of loaders:

  • qname is used to load other definitions on the current branch.
  • http or https are used to load schemas from remote endpoints.

For qname loaders, you should use this syntax:

qname://{namespace}/{localName}`

For http or https, the value should be a URL to a valid JSON schema:

http://{server}/{path}
https://{server}/{path}

Inline Properties

The $ref property furthermore lets you point to inline schemas within either the current schema or the loaded schema. Inline schemas within the current definition let you reuse a block of schema in various places. Inline schemas from a loaded schema let you reuse that in the same way.

Inline Properties within the same schema

Inline properties within the same schema take the form #/a/b/c where a/b/c is a path to a nested sub-property within the current schema.

Here is an example where we general the author information as a person block under definitions. We then reference that block for author.

{
    "type": "object",
    "properties": {
        "title": {
            "type": "string",
            "title": "Title"
        },
        "body": {
            "type": "string",
            "title": "Body"
        },
        "author": {
            "$ref": "#/definitions/person"
        }
    },
    "definitions": {
        "person": {
            "type": "object",
            "properties": {
                "firstName": {
                    "type": "string",
                    "title": "First Name"
                },
                "lastName": {
                    "type": "string",
                    "title": "Last Name"
                }
            }
        }
    }
}

Inline Properties using a loaded schema

You can reference nested properties within loaded schemas using the $ref feature as well. Nested properties are simply appended after the loader value.

Suppose we wanted to load the subobject definitions/person from the loaded schema. We can do so like this:

qname://{namespace}/{localName}#/definitions/person
http://{server}/{path}#/definitions/person
https://{server]/{path}#/definitions/person

Validation

Cloud CMS provides server-side validation which includes resolution of all $ref elements. The aggregated schema is validated all at once prior to saving the node to the branch.

Cloud CMS also provides automatic form generation using JSON Schema that respects and validates for these $ref structures. You can use them at will and Cloud CMS will respect them both client-side and server-side.