All the work that a Dynamo template does is done by the commands in the template's Flow. As commands get evaluated during the evaluation process, they each perform their intrinsic function. However, commands do not always perform in the exact same way - most of them have a variety of attributes that are used to configure the command's functionality. Each attribute of a command may be given a value, and this value is often a variable found residing in the variable context. The variable context, a persistent storage for values, therefore ties heavily into the operation of the commands.

In the Template editor you can find the attributes of a command by clicking it and taking a look at the panel on the right. Below you can see what clicking a record command would bring out.

This command's attributes are configuring it to retrieve values of certain fields of a particular Salesforce Opportunity record. With some different attribute values the command could be retrieving some completely different data. The command's documentation, accessed by clicking the question mark at the top-right, describes what each of its attributes does. While the values set for many of the attributes of this command can make sense to a Salesforce user, the recordID attribute's value is a bit more peculiar - and that's because it's using a variable as its value, allowing the logic to vary when specific Opportunity record's data is retrieved. It is through the use of variables that a Dynamo template produces different results based on the main record, the user running it, the current date, and other factors.  

Creating variables

Many commands create variables into the variable context for other commands to use. The aforementioned record command, for example, retrieves data of a Salesforce record and creates a variable with the record data as its value. Variable-creating commands are typically identified by them having an attribute called var, which defines the name of the variable they're creating. Each variable in the variable context needs to have a unique name as the name acts as the key by which other commands can access the variable's value. If a command creates a variable with a name that already exists in the variable context, the command will be overwriting the previously existing value behind that name with the value of its own. Unless overwritten in this way, and not created into a local variable context (described below), a variable and its value will remain in the variable context until the end of the evaluation process.

Besides commands in Steps, input elements in Screen steps also produce variables. Each such element can have the attribute name, which acts exactly like var for commands - it defines the name of the variable that will have the input's value. Every named input element on the screen creates a variable once the user proceeds through the Screen step by pressing a submit button.

Finally, the variable context also contains variables automatically created by the system. One is the variable "param" with the parameter Map as its value, providing access to all the parameters included in the HTTP request sent to Dynamo that initiates the evaluation process. There are also other variables, as documented in System-generated Variables. These variables and their values are available for all evaluation processes by default.  

Variables in attributes

The values in the variable context can affect the behavior of other commands when those commands use these variable values in their attributes. Variable values can be used in any attributes that, in the command's documentation, are marked as being "EL-evaluated". This refers to the fact that the only way to access the variable context's contents is through EL-expressions. When the command itself is evaluated, all these EL-evaluated attributes' values are evaluated as EL-expressions, with the result of the evaluation becoming the attribute's effective, resolved value. An attribute that is not EL-evaluated can only have a static String value that will be the same on all evaluation processes, generally for a good reason.

Below is a basic example of both EL-evaluated and non-EL attribute values in use. The value of the attribute var is just the String "documentPDF", while the document attribute's value is an EL-expression referring to the value of a variable with the name "composedMainContent". In this example's case, the variable's value is most likely a HTML File that the exportPDF command then transforms from HTML to a PDF file. EL-expressions are easily recognized by the "${" and "}" surrounding the expression.

While a static String value can be set as a value for several attributes, this is not always the case. Each attribute only accepts certain types of values, and String is only one of types, although a very common one. Values can come in many other types, such as File, Number, Data Item and Collection. The types of values an attribute accepts are listed in its documentation's "Value type" column. The exportPDF command above, for example, specifically needs a File value for its document attribute. Setting a value of a wrong type for an attribute typically produces an error, and may prevent the command from performing its primary function. Commands that produce values have the type of their produced value mentioned in their documentation, typically in the main command description as well as the description of the var attribute.  

An attribute may also be marked as being required. This means that the attribute has to have a value defined for it, as the value is crucial to the operation of the command. As an example, all commands whose main purpose is to create a variable, the variable-naming var attribute is required to have a value, as otherwise the command wouldn't know what to name the variable it is creating. Leaving a required attribute's value undefined is a severe error as it prevents the command from functioning, and so a command in this situation will produce an error message looking like the one below during the evaluation process. Errors of this kind may also appear even if an attribute's value is defined, as an EL-expression may resolve into a nonexistent value, null.

Commands' local variable contexts

Certain commands, most notably the loop-generating control command forEach, create what is called a local variable context when they are evaluated. The local variable context is a smaller, temporary variable context that is linked to the main variable context as its child context, while the main context will be the local context's parent context. The commands that create one always have other command evaluations happening during their own evaluation, such as evaluations of child commands - for those commands being evaluated under the local context -creating one, the local context will be the active variable context they see. All local variable contexts are fairly short-lived, as they are terminated along with their contents at the end of or during specific points of the context-creating command's evaluation.

The local variable context affects the commands' variable interactions in the following ways:

  • Commands that create variables place them into the local variable context. These variables will be terminated along with the context. This rule is only broken by the set command that can set values for existing variables in the local context's parent contexts.
  • Commands can access variables in both the local context and its parent contexts. However, if both the local context and a parent context have a variable of the same name, commands are only able to access the local context variable of that name.  

Due to the variable-creating behavior, any variable-creating command that isn't set won't have any effect by itself that would last past the local context's termination. If your goal is to specifically create variables in a local context, besides using set it is possible to put these variable values into a Map or a Collection in the main context with the addMapEntry and addItem commands. Commands with effects that do not create variables, such as the various Salesforce operation commands, also work normally regardless of the kind of context they're working under.

As an example, below is a forEach loop that loads files from Salesforce and puts them all into a Collection. The forEach command creates a unique local variable context for each of its loop rounds, to be used by the child commands on that loop round. The local context here starts out with the forEach's loop round variable "fileID" in it, which load then uses to produce the "file" variable, and both of these along with the local context will be gone once addItem finishes and concludes the loop round. However, the addItem there places the "file" variable's value into the "files" Collection, which exists somewhere outside this loop, and so all the values of the "file" variable created in all the rounds of forEach keep existing outside it.

When a local context and any of its parent contexts have a variable of the same name, the parent context variable of that name cannot be accessed by commands operating with the local context - this is referred to as the local context variable masking the parent context variable. To demonstrate this, below is the previous example modified a bit. Now the main context also contains variables "fileID" and "file", but the loop still works in exactly the same way. The load command can only see the "fileID" in the local context, and so is addItem only able to see the local context's "file" - these local context variables are masking the main context variables of the same names. During all the loop rounds, the main context's "fileID" and "file" remain completely unaffected.  

Should a command that creates a local variable context be evaluated under a local variable context, another local variable context will be created. A local variable context will always be linked to the currently active context at the time of its creation, which in this case would be the previously existing local variable context. This creates a hierarchy of three variable contexts - the new local context, the previously existing local context as its parent, and the main context as its parent's parent. This does not change the variable interactions in any specific way from the rules already applying to local contexts.