How to understand the structure of schemaDir files?

I’m confused about how to structure JSON files that are contained in the schemaDir. For example, in notebook-extension/schema/tracker.json, we see something that looks like this:

"properties": {
    "codeCellConfig": {
      "title": "Code Cell Configuration",
      "description": "The configuration for all code cells.",
      "$ref": "#/definitions/editorConfig",
      "default": {
        "autoClosingBrackets": true
      }
    }
  }

The documentation states, “A plugin’s settings are specified with a JSON schema file.” That makes me think that these files should conform to some schema - I am not sure what it is. However, with regard to JSON references, the RFC states, “Any members other than “$ref” in a JSON Reference object SHALL be ignored.” It is my understanding that commonly these $ref statements are in an object on their own.

I’m confused about how to interpret these files. Can anyone assist with this?

I think that you might be looking at an old (very old?) version of JSON schema RFC.

This is no longer present in the current version. Instead, the resolution of $ref values is described in detail in JSON Schema RFC (2020-12) section 7.7.1.1: JSON Schema: A Media Type for Describing JSON Documents

In short, the $ref works like a set of defaults. For example, looking at the mentioned tracker.json file:

{
  // removed shortcuts and metadata for brevity
  "title": "Notebook",
  "description": "Notebook settings.",
  "definitions": {
    "editorConfig": {
      "properties": {
        "autoClosingBrackets": {
          "type": "boolean"
        },
        "tabSize": {
          "type": "number"
        }
        // other properties follow
      },
      "additionalProperties": false,
      "type": "object"
    }
  },
  "properties": {
    "codeCellConfig": {
      "title": "Code Cell Configuration",
      "description": "The configuration for all code cells.",
      "$ref": "#/definitions/editorConfig",
      "default": {
        "autoClosingBrackets": true,
        "tabSize": 4
      }
    },
    // other properties follow
  },
  "additionalProperties": false,
  "type": "object"
}

codeCellConfig inherits type (object), additionalProperties (false) and properties (presets for autoClosingBrackets, tabSize) from $ref; they do not have defaults set in $ref so the defaults get defined on codeCellConfig level: autoClosingBrackets gets default true, while tabSize default is set to 4. This way different editors can share the same setting types but different defaults.

Does it help?

1 Like

This is working. I discovered that in order to get the setting to render correctly in the Settings panel, I need to set the default in two places:

I must set it here:

"test": {
    "type": "boolean",
     "default": true
}

And, I must set it here:

"default": {
    "test": true
}

Hence, the following approach works without a definition:

{
      "title": "TEST JSON SCHEMA",
      "description": "TEST JSON SCHEMA",
      "properties": {
        "test-property": {
          "title": "TEST",
          "description": "TEST",
          "properties": {
            "test": {
              "type": "boolean",
              "default": true
            }
          },
          "additionalProperties": false,
          "type": "object",
          "default": {
            "test": true
          }
        }
      },
      "additionalProperties": false,
      "type": "object"
    }

If I don’t set the default in both places, the setting will not render correctly in the Settings panel.

This will allow me to easily build up the settings object. Thank you again for the guidance on this.

Thank you.

1 Like

The following pattern seems to work for nested settings. The objects render in the Settings Panel using this approach, but the title and description for level 2 does not render as a comment.

{
  "type": "object",
  "additionalProperties": false,
  "title": "level0",
  "description": "level0",
  "properties": {
    "level1": {
      "type": "object",
      "additionalProperties": false,
      "title": "level1",
      "description": "level1",
      "properties": {
        "level2": {
          "type": "object",
          "additionalProperties": false,
          "title": "level2",
          "description": "level2",
          "properties": {
            "key": {
              "type": "boolean",
              "default": true
            }
          },
          "default": {
            "key": true
          }
        }
      },
      "default": {
        "level2": {}
      }
    }
  },
  "default": {
    "level1": {}
  }
}