# Json Extensions

In addition to the default inheritance strategy available throughout Marfeel, several different inheritance and extension strategies are available. This article lists them with examples of inputs and outputs.

# mrf-json CLI tool

Given a definition.json that inherits from parent-definition.json Marfeel provides mrf-json, a CLI tool, that allows developers to output the final json with the inheritance and all operators resolved

mrf-json `pwd`/definition.json > definition.merged.json

# Extension operators

File inheritance can be modulated by operators.

# modify operator

Modifies elements of 0-based arrays or a property of an element of a 0-based array.

Original JSON

{
  "layouts": [
    ["photo", 1, 0],
    "thumb",
    "photo",
    { "name": "photo", "count": 4, "section": "comida" }
  ]
}

Extends

{
  "extends": "default.json",
  "layouts": {
    "modify": {
      "1": "photo2",
      "2": { "simple" : "object" },
      "3.section": "sports"
    }
  }
}

Result

{
  "layouts": [
    ["photo", 1, 0],
    "photo2",
    { "simple" : "object" },
    { "name": "photo", "count": 4, "section": "sports" }
  ],
  "extends": "default.json"
}

# insert operator

Inserts the specified element in a given position of a 0-based array.

Original JSON

{
  "layouts": [
    ["photo", 1, 0],
    "thumb",
    "photo"
  ]
}

Extends

{
  "extends": "default.json",
  "layouts": {
    "insert": {
      "0": ["S1", "S2", "S3"],
      "-1": "At The end"
    }
  }
}

Result

{
  "layouts": [
    ["S1", "S2", "S3"],
    ["photo", 1, 0],
    "thumb",
    "photo",
    "At The end"
    ],
  "extends":"default.json"
}

# insertAll operator

Inserts all the elements of the arrays specified in a given position of a 0-based array.

Original JSON

{
  "layouts": [
    ["photo", 1, 0],
    "thumb",
    "photo"
  ]
}

Extends

{
  "extends":
  "default.json",
  "layouts": {
    "insertAll": {
      "0": ["S1", "S2", "S3"],
      "-1": "At The end"
    }
  }
}

Result

{
  "layouts": [
    "S1",
    "S2",
    "S3",
    ["photo", 1, 0],
    "thumb",
    "photo",
    "At The end"
  ],
  "extends":"default.json"
}

# delete operator

Deletes elements of an array, elements within arrays within an array and even eliminate properties of objects.

Original JSON

{
  "layouts": [
    ["photo", 1, 0],
    "thumb",
    "photo"
  ]
}

Extends

{
  "extends": "default.json",
  "layouts": {
    "delete": [2, 1]
  }
}

Result

{
  "layouts": [
    ["photo", 1, 0]
  ],
  "extends":"default.json"
}

Original JSON

{
  "layouts": [
    ["photo", 1, 0],
    "thumb",
    { "sections": [1, 2, 3] }
  ]
}

Extends

{
  "extends": "default.json",
  "layouts": {
    "delete": {
      "0" : 1,
      "2.sections" : 1,
      "$this" : 1
    }
  }
}

Result

{
  "layouts": [
    ["photo", 0],
    { "sections" : [1, 3] }
  ],
  "extends":"default.json"
}

Original JSON

{
  "layouts": [
    ["photo", 1, 0],
    "thumb",
    { "sections" : [1, 2, 3] }
  ]
}

Extends

{
  "extends": "default.json",
  "layouts": {
    "delete": {
      "2" : "sections"
    }
  }
}

Result

{
  "layouts": [
    ["photo", 1, 0],
    "thumb",
    { }
  ],
  "extends":"default.json"
}

WARNING

The operations on the array are not commutative

Exercise caution when a definition is extended from another tenant. The path values have their root in the current tenant, not in the one being extended.

For example:

"configuration" / "whiteCollarScript" : "index/src/whitecollar/main.js"

Make that the file exists in the tenant you are working on. Otherwise, specify the tenant like:

"configuration" / "whiteCollarScript": "../<someTenant>/index/src/whitecollar/main.js"

# Field Inheritance

Marfeel also provides an inheritance mechanism that allows developers to create inheritance chains in fields by extending them with a parent file.

Use the field __extends to pass the path of a json file containing the information to inherit.

providerA.json:



 





{
  "provider": {
    "__extends": "providerB.json",
    "field1": "value will be overriden",
    "field2": "value will be kept"
  }
}

providerB.json:

{
  "field1":"new value",
  "field3":"provider B field"
}

Merge result:

{
  "provider": {
    "field1":"new value",
    "field2": "value will be kept",
    "field3":"provider B field"
  }
}

This inheritance mechanism makes easier the extraction of common fields and can be used as much as needed. It follows the same rules and logic as the root extends: namely, it supports nested inheritance.

In practice, this means that an analytics provider will intrinsically inherit default configuration from a Marfeel configuration pageview.json

Tenant's analytics.json:











 





{
  "googleanalytics": [
    {
      "vars": {
        "account": "UA-XXXXXX-X"
      },
      "touchVars": {
        "environment": "#{env.device.environment}"
      },
      "triggers": {
        "__extends": "marfeel/index/resources/analytics/triggers/googleanalytics/pageview.json"
      }
    }
  ]
}

Marfeel pageview.json:

{
  "trackTenantPageview": {
    "platforms": [
      "TOUCH"
    ],
    "on": "visible",
    "action": "pageview"
  }
}

Merge result:

{
  "googleanalytics": [
    {
      "vars": {
        "account": "UA-XXXXXX-X"
      },
      "touchVars": {
        "environment": "#{env.device.environment}"
      },
      "triggers": {
        "trackTenantPageview": {
            "platforms": [
              "TOUCH"
            ],
            "on": "visible",
            "action": "pageview"
          }
      }
    }
  ]
}

JSONs are merged according to the following given behavior:

  • When a field exists only in one of the chained files, the field is added to the result file.
  • When a field exists in several files the field is added with the value specified in the latest extension.
  • The merge is recursive and works for any field regardless of how deep the JSON tree is.

For Arrays there are operators that define how their elements should be merged