Work with App Template Framework Rules
The App Template Framework uses a server-side transform engine powered by JSON rules to find and replace tokens in the asset JSON files with values from the template configuration process. The JSON rules are defined in files that describe both how an app gets created by the template and how a source app is converted to a template. The rules you create inform the transformation logic of the framework. They adapt the app assets for each subscriber org and tokenize hard-coded source app values.
There are two types of rules files: template-to-app-rules.json and app-to-template-rules.json. They use the same syntax but serve different purposes.
template-to-app-rules.jsondefines the rules that the template follows when creating an app. Rule examples include:- Skipping objects an org doesn’t use, so they’re excluded from dashboards and data transformations.
- Replacing a chart label with the name of a field name selected in a wizard question.
- Applying customized account filters chosen in the wizard to dashboard assets.
app-to-template-rules.jsonprovides rules for converting an updated source app back to template form. After changing the source app, you update the template object with a PUT call to the App Framework REST API. For example, you can tokenize all asset files every time they are pulled out of the source app. You use app-to-template rules infrequently, because you’re unlikely to update the source app often.
The rules file is referenced from template-info.json:
1"rules" : [
2 { "type" : "appToTemplate", "file" : "app-to-template-rules.json" },
3 { "type" : "templateToApp", "file" : "template-to-app-rules.json" }
4]As a template developer, you create and maintain the template-to-app-rules.json file.
Rules Files Overview
Rules files can contain three sections: rules, constants, and macros.
- Rules: Where you define the rules used by the template for creating the app.
- Constants: Use constants to create shortcuts for longer expressions. Constants are similar to variables but aren’t passed in or declared in the UI. They are referenced in the JSON files via the normal expression language
${Constants.<constantName>}. - Macros: Use rule macros to define repeatable, well-tested rule code units that you can call within the context of
any JSON transformation. Macros simplify the rule definition source and make it easier to maintain.
Structuring and Organizing Rules
The rules section of template-to-app-rules.json defines the rules followed by the template.
This section is made up of three parts:
name: Describes the rule. Use names that are descriptive and assist with future maintenance.actions: Designates a list of operations to perform. Each action specifies a type and a description, and defines
the JSON path to run on and the value to use.
appliesTo: Determines the asset files to apply the rules to. Consists of anameand atype.condition: Optional. Specifies a condition for applying the rule. If the condition resolves totrue, the rule is applied, if it resolves tofalse, the rule isn’t applied.
You can divide rules into multiple files, which the framework executes in the order you list them in template-info.json. Be sure that a rule that runs first doesn’t refer to a constant referenced in a rule that runs later.
Here are a few guidelines to consider when working with multiple rules files:
- One rules file can contain all constants, another all actions.
- Split rules into multiple files when actions grow beyond about 500 lines. For example, divide them into one rules file for dashboards and another for data sources.
- If you have content to be used by many rules, include it in the first rules file to be executed.
Here is a simple rules example, a rule for changing the title text on a dashboard:
1{
2 "name": "Update dashboard title",
3 "appliesTo": [
4 {
5 "type": "dashboard",
6 "name": "DashboardOne"
7 }
8 ],
9 "actions": [
10 {
11 "action": "set",
12 "description": "change the title text of the dashboard",
13 "path": "$.state.widgets.title_text.parameters.text",
14 "value": "${Variables.DashboardTitle}"
15 }
16 ]
17}To make rules more powerful, use functions. See Use Functions in Rules.
Actions in Rules
Actions define the way rules change an app’s JSON files. Valid actions are:
delete: Delete a node in the document.put: Add a node to an object.set: Set the value of an existing node in the document.add: Add an element to an array.eval: Evaluate a specified expression and assign results to a variable.replace: Search and replace a text string globally.
Each action has a path attribute, which is a JsonPath that points to a node in the JSON file. JsonPath is to JSON as XPath is to XML.
If a template is updated to change the assetVersion, it can impact the JsonPath. Always test the rules for app creation after a template update.
Note
Actions can be conditionally applied to a JSON file. Apply a condition to a single action or to a group of actions.
Use Functions in Rules
Functions make rules more powerful. For example, use functions to apply rules iteratively to arrays or to make rules conditional on the content of a string or an array. The framework supports string, array, date, and json functions as well as static math and sfdc_fma functions.
Use the "Rules.CurrentNode" property in conjunction with functions. It contains the last results of the JSON path argument supplied in the action of your rule.
Use the EL Expression Language to invoke custom functions with an expression. Functions can appear in the static text of an EL expression, for example:
1"name" : "my name in lowercase is ${string:toLowerCase(Variables.myName)}",Use functions to determine values at runtime. For example, set a boolean constant from the result of the array:contains() function:
1{
2 "name": "IsItemPresentInArray",
3 "value": "${array:contains(Variables.Items, 'Item1')}"
4 }For function details, see:
Use Constants in Rules
Use constants to create shortcuts for longer expressions and for values that are used more than once.
For example, if you’re creating a template that can work with or without product data, create a constant that stores if the subscriber org is using products.
1"constants": [
2 {
3 "name": "HasProduct",
4 "value": "${Variables.Has_Product == 'Yes'}"
5 }
6]Then, use the constant in a rule to decide whether the dashboard displays product data.
1"rules": [
2 {
3 "name": "Remove Product From Sales Operations Overview",
4 "condition": "${!Constants.HasProduct}",
5 "appliesTo": [
6 {
7 "type": "dashboard",
8 "name": "Sales_Ops_Manager_Overview"
9 }
10 ],
11 "actions": [
12 {
13 "action": "delete",
14 "description": "Delete unused step",
15 "path": "$.state.steps.product_dimension_dropdown"
16 },
17 {
18 "action": "delete",
19 "description": "Delete unused step",
20 "path": "$.state.steps.Segment_Product"
21 }
22 ]
23 }
24]Use Macros in Rules
Use a macro when a single rule executes repeatedly on different JSON node paths. Macros let you define that logic once and reuse it across rules and transformations, so you write and test it a single time. See Macros in Rules for macro syntax and examples.
See Also