# Design Object Templates
## Overview
The `design-object-templates` directory contains all of the recipe and template files used by the Object Template Framework to create design objects.

This module contains several types of files.
1. **Registry files** are used to map Template Recipe IDs to the Initial Template Recipe files used to generate the design object metadata objects needed for object generation.
1. **Initial Template Recipe files** of type "ftl" are used to generate JSON text output containing design object metadata. More specifically, user actions relying on object template generation are defined as Template Recipe JSON files in the `registry` directory, which designate the Initial Template Recipe JSON file to store the generation metadata.
1. **Object Template files** of type "ftlx" are utilized by the framework to produce XML text output. Object template files take the configurations set by the Forward Flow wizard to produce a ZIP of the object XML files for successfully importing into Appian Designer.

Thus, when adding a new configuration of unsupported design objects to generate or update, we must:
1. Create a Template Recipe JSON file in the `registry` directory to register the configuration's name and Initial Template Recipe location to store the generation metadata
1. Create an Initial Template Recipe JSON file to define design object metadata objects and designate the Object Template file to be processed
1. Create an Object Template file to define the desired XML text output of the object template generation action

For more high-level understanding of how the Object Template Framework works, visit the [Object Template Framework Stratus Docs](https://docs.appian-stratus.io/tech-docs/design-objects/ot-framework/).

## Freemarker Development Practices
Some general notes:
* Changes made to Freemarker templates hot deploy
* Freemarker captures whitespace in directives, so ensure that the generated SAIL (visible to end-users) is properly formatted

For more information on how to develop Freemarker templates, visit Apache's [official Freemarker documentation](https://freemarker.apache.org/docs/ref.html). Below, we list some general guidelines we abide by when developing FTL and FTLX files:

### Import Statements
#### Explicitly import required template files

Import statements (written as `<#import path as hash>`) are used to access the macros, functions, and other variables of another template specified by the `path` variable. They do this by creating and populating a namespace with the variables of the imported template, and then assigning the namespace to the specified variable, `hash`, to make the variables accessible. Thus, import statements only get compiled once (the first time the namespace is populated and labeled), so even without explicit import statements, sub-files can access the imported variables of a parent file. However, we maintain the need to not make any assumptions and make explicit import statements to maintain clarity and readability.

### Sail Function Calls
#### Explicitly call Sail functions by the system rule uuid like `#"SYSTEM_SYSRULE_sailFunction"`

In design mode, Sail functions are represented in display form (aka `a!sailFunction`) but the version of the rule specified by the display form depends on the Appian version. For example, `SYSTEM_SYSRULES_gridField_v2` could be represented by the display form, `a!gridField()`, in one version of Appian. But in a later Appian version, `a!gridField()` could actually represent `SYSTEM_SYSRULES_gridField_v3`! Thus, to ensure forward compatibility, it is imperative to explicitly use the system rule uuid in template files, to ensure correct sail function calls.

### Macros
* Precede every macro definition with a comment describing the macro's purpose
* Include an empty line before and after every macro definition to clearly distinguish the end of one macro definition and the start of another
* When a macro is called with several long parameters, indent the macro call such that each parameter is on its own line for readability

### Consistent Indentation
* Nested contents of tags should be indented (2 spaces)
```
<#if eventHistoryList?has_content>
  <#assign eventHistoryLabel="Event History" />
  <@sectionLayout label=eventHistoryLabel contents=[eventHistoryList] />
</#if>
```

* For multi-line tags, the lines following the tag should be double-indented (4 spaces)
```
<@sectionLayout
    label="Contacts"
    labelSize="MEDIUM"
    labelColor="STANDARD"
    marginBelow="MORE"
    contents=[contactsList] />
```

### Other
* For freemarker string, default to using single quotes `'`. Double quotes `"` are also allowed in freemarker, but double quotes are common in SAIL. To avoid needing to escape them, single quotes are clearer.
* Util files with reusable macros, functions, and variables should be put in the `utils` directory
* If there is an extra new line at the end of a SAIL expression, use `<#rt>` to trim the new line
```
<#macro defaultValue value>
a!defaultValue(
  ${value},
  "–"
)<#rt>
</#macro>
```
