These are the built-ins that normally you should not use, but in exceptional situations (debugging, advanced macros) they can be useful. If you need to use these in your normal page templates, you may revisit the data-model so you don't need to use these.
absolute_template_name
Converts a template name to an absolute name, which can be
          safely passed to <#include
          name> or
          <#import name as
          ns> or
          .get_optional_template(name)
          and such in another template, as it won't be
          misinterpreted to be relative to the directory of the template that
          contains the include, import,
          etc. For example, if you are in template
          "dir/here.ftl", then
          "target.ftl" is converted to
          "/dir/target.ftl" (note the initial
          /). If now you pass this value to a template in
          "other-dir/there.ftl", where it's passed to the
          include directive, then it won't be
          misinterpreted as "other-dir/target.ftl", like
          "target.ftl" would have been.
Optionally, you can specify a root based name (a name that's
          either relative to the template root directory, or is absolute) that
          will be used instead of the name of the current template, like
          pathToConver?absolute_template_name(otherTemplateName).
Example of an application (also uses .caller_template_name
          and .get_optional_template):
<#--
  <@smileyInclude name /> behaves like <#include name>, but prints a "(:" before the
  template, or prints "):" instead if the template is missing.
  Note that just like with #include, if name is relative, it's resolved based on the
  directory of the caller template, not of the template that defines this macro. As
  .get_optional_template resolves relative names based on the current template, we
  had to convert the name to an absolute name based on the caller template before
  passing it to it.
-->
<#macro smileyInclude name>
  <#local t = .get_optional_template(
      name?absolute_template_name(.caller_template_name))>
  <#if t.exists>
    (:
    <@t.include />
  <#else>
    ):
  </#if>
</#macro>    api, has_api
These built-ins exists since FreeMarker 2.3.22
value?api
          provides access to the API (usually, the Java API) of
          value, like
          value?api.someJavaMethod()
          or
          value?api.someBeanProperty,
          if the value itself supports exposing its API. This meant to be used
          rarely, when you need to call a Java method of an object, but the
          by-design simplistic view of the value that FreeMarker exposes to
          the templates hides that, and there's no equivalent built-in either.
          For example, when you put a Map into the
          data-model (and you are using the default object wrapper),
          myMap.myMethod() in a template basically
          translates to ((Method)
          myMap.get("myMethod")).invoke(...) in Java, thus you can't
          call myMethod. If, however, you write
          myMap?api.myMethod() instead, that means
          myMap.myMethod() in Java. Similarly,
          myMap?api.myProperty translates to
          myMap.getMyProperty() in Java, instead of to
          myMap.get("myProperty").
You should avoid using api, and
          rely on the capabilities of the FTL types and the related built-ins
          as far as possible. For example, don't use
          users?api.size(), but
          users?size. The variation that uses
          ?api is more verbose, slower, more easily breaks
          when FreeMarker configuration settings are changed, and most
          importantly, more prone to break as the technical details of the
          data-model change. For example, if users is
          changed from a List to an array,
          users?size will keep working, while
          users?api.size() will break.
Avoid calling methods that modify an
          object (especially Map-s and
          Collection-s) or that aren't thread safe from
          other reasons. Templates usually aren't expected to modify the
          objects exposed to them, just to display them. Thus the application
          may passes some objects to multiple (possibly concurrent) template
          processings.
The api built-in is not everywhere
          available, some requirements has to be met:
- 
              
The
api_builtin_enabledconfiguration setting must be set totrue. Its default isfalse(at least as of 2.3.22) for not lowering the security of existing applications. - 
              
The value itself has to support it. We are talking about the value as the template sees it, which is created from the original object (that's coming from the data-model or from a Java method return value) value via object wrapping. Hence, this depends on the
object_wrapperFreeMarker configuration setting, and on the class of the wrapped (the original) object:- 
                  
When the object wrapper is a
DefaultObjectWrapperwith itsincompatibleImprovementsset to 2.3.22 or higher (see how to set it here), FTL values made fromMap-s andList-s support?api. (Actually, what matters is that itsuseAdaptersForContainerproperty is set totrue, but that's the default with saidincompatibleImprovements.) Otherjava.util.Collections(such asSet-s) only support?apiifDefaultObjectWrapper'sforceLegacyNonListCollectionsproperty is set tofalse(the default istruefor better out-of-the-box backward compatibility). - 
                  
When wrapped with pure
BeansWrapper, all values support?api. - 
                  
Custom
TemplateModel-s can support?apiby implementing thefreemarker.template.TemplateModelWithAPISupportinterface. 
 - 
                  
 
Using ?api when it's not allowed in the
          configuration or when the value doesn't support it will abort
          template processing with error.
Whether a value supports ?api can be
          checked like
          value?has_api, which
          returns a boolean value. Note that the result of
          ?has_api isn't influenced by the
          api_builtin_enabled setting.
byte, double, float, int, long, short
Returns a SimpleNumber which contains the
          same value as the original variable, but uses
          java.lang.Type for the
          internal representation of the value. This is useful if a method is
          overloaded, or if a TemplateModel unwrapper has
          problem with automatically choosing the suitable
          java.lang.* type. Note that since version 2.3.9
          the unwrapper has been improved substantially, so you will hardly
          ever need to use these built-ins to convert between numerical types,
          except for resolving ambiguity in overloaded method
          invocation.
The long built-in can also be used with
          date, time and date-time values to get the value as
          java.util.Date.getTime() would return. This is
          useful if you have to call a Java methods that expect a timestamp as
          a long.
eval
This built-in evaluates a string as an FTL
          expression. For example
          "1+2"?eval returns the number 3. (To render a
          template that's stored in a string, use the interpret
          built-in instead.)
Do not use this to evaluate JSON! For that use the eval_json
            built-in instead. While FTL expression language looks
            similar to JSON, not all JSON is valid FTL expression. Also, FTL
            expressions can access variables, and call Java methods on them,
            so if you ?eval strings coming from untrusted
            source, it can become an attack vector.
The evaluated expression sees the same variables (such as
          locals) that are visible at the place of the invocation of
          eval. That is, it behaves similarly as if in
          place of s?eval you
          had the value of
          s there. Except, it
          can't use loop variable
          built-ins that refer to a loop variable that was created
          outside s.
Regarding the configuration settings that affect the parsing
          (like syntax) and evaluation the rules are the same as with the
          interpret
          built-in.
eval_json
This built-in is available since FreeMarker 2.3.31.
This built-in evaluates a string as a JSON
          expression, so that you can extract data from
          inside it. For example, if you receive data in the
          dataJson variable, but it's unfortunately just a
          flat string that contains {"name": "foo", "ids": [11,
          22]}, then you can extract data from it like this:
<#assign data = dataJson?eval_json>
<p>Name: ${data.name}
<p>Ids:
<ul>
  <#list data.ids as id>
    <li>${id}
  </#list>
</ul>    Ideally, you shouldn't need eval_json,
          since the template should receive data already parsed (to
          List-s, Map-s, Java beans,
          etc.). This built-in is there as a workaround, if you can't improve
          the data-model.
The evaluated JSON expression doesn't have to be a JSON object (key-value pairs), it can be any kind of JSON value, like JSON array, JSON number, etc.
The syntax understood by this built-in is a superset of JSON:
- 
              
Java-style comments are supported (
/*...*/and//...) - 
              
BOM (byte order mark) and non-breaking space ("nbsp") are treated as whitespace (in a stricter JSON parser they are errors of occurring around tokens).
 
No other non-JSON extras are implemented, notably, it's
          impossible to refer to variables (unlike in the eval built-in).
          This is important for safety, when receiving JSON from untrusted
          sources.
has_content
It is true if the variable exists (and
          isn't Java null) and is not "empty",
          otherwise it is false. The meaning of
          "empty" depends on the concrete case. This follows
          intuitive common-sense ideas. The following are empty: a string with
          0 length, a markup
          output value with 0 length markup, a sequence or hash with no
          sub variables, a collection which has passed the last element. If
          the value is not of any of these types, then it counts as non-empty
          if it's a number or a date or a boolean (e.g. 0
          and false are not empty), otherwise it counts as
          empty. Note that when your data-model implements multiple template
          model interfaces you may get unexpected results. However, when in
          doubt you can use always use expr!?size > 0 or
          expr!?length > 0 instead of
          expr?has_content.
This buit-in is exceptional in that you can use the
          parentheses trick like with the default value
          operator. That is, you can write both
          product.color?has_content and
          (product.color)?has_content. The first doesn't
          handle the case when product is missing, the last
          does.
interpret
This built-in parses a string as an FTL template, and returns
          an user-defined directive that executes that template, just as if a
          template with that content were include-d
          at that point. Example:
<#assign x=["a", "b", "c"]>
<#assign templateSource = r"<#list x as y>${y}</#list>">
<#-- Note: That r was needed so that the ${y} is not interpreted above -->
<#assign inlineTemplate = templateSource?interpret>
<@inlineTemplate />    The output:
abc
As you can see, inlineTemplate is a
          user-defined directive that, when executed, runs the template whose
          content is the value of templateSource.
The name of the template created by
          interpret is the name of the template that calls
          interpret, plus
          "->anonymous_interpreted". For example, if the
          template that calls the built-in is
          "foo/bar.ftl", then the name of the resulting
          template is
          "foo/bar.ftl->anonymous_interpreted". Thus,
          relative paths inside the interpreted template are relative to this
          path (i.e., the base directory will be "foo"),
          and errors inside the interpreted template will point to this
          generated template name.
For more helpful error messages, you can override the template
          name part after the "->". For example, let's
          say mailTemplateSource comes from the
          mail_template database table, and in the case of
          error, you want the error log to contain the database ID of the
          failing template:
<#assign inlineTemplate = [mailTemplateSource, "mail_templates id=${mailTemplateId}"]?interpret>    As you can see, interpret can be applied on
          a sequence of two items, in which case the first item is the FTL
          string to interpret, and the second items is the template name used
          after the "->".
The configuration settings that affect the interpreted
          template are the same as of the surrounding template, except that
          parser settings specified in the ftl directive
          or was established via tag syntax or naming convention
          auto-detection are instead coming from the
          Configuration object (or naturally, from the
          TemplateConfiguration,
          if there's any). Thus the tag syntax, naming convention, whitespace
          handling, etc. of the interpreted template is independent of that
          established inside the surrounding template. An
          important exception from this rule is that the output format
          and auto-escaping policy is inherited from the lexical context where
          interpret is called from. For example in a
          template that has <#ftl
          output_format="XML"> header (or if you are inside a
          <#output_format
          "XML">...</#output_format>
          block), interpret calls in it will produce
          directives with XML output format.
is_...
These built-ins check the type of a variable, and returns
          true or false depending on the
          type. The list of
          is_...
          built-ins:
| Built-in | Returns true if the value is a ... | 
              
|---|---|
is_string | 
                string | 
is_number | 
                number | 
is_boolean | 
                boolean | 
is_date | 
                Don't use it! Same as is_date_like, use
                that instead. Later may changes meaning to
                date_only. | 
              
is_date_like | 
                date-like, means either date, time or date-time, or date-like with unknown precise type (since FreeMarker 2.3.21) | 
is_date_only | 
                date (no time of the day part) (since FreeMarker 2.3.21) | 
is_time | 
                time (no year-month-day part) (since FreeMarker 2.3.21) | 
is_datetime | 
                date-time (contains both year-month-day and time of the day) | 
is_unknown_date_like | 
                date-like where we don't know if it's a date or a time or a date-time | 
is_method | 
                method | 
is_transform | 
                transform | 
is_macro | 
                macro or function (yes, also for function; a historical glitch) | 
is_hash | 
                hash (including extended hash) | 
is_hash_ex | 
                extended hash (supports ?keys and
                ?values) | 
              
is_sequence | 
                sequence (Historical quirk: Before incompatible_improvements
                2.3.24 it returns true for Java methods as
                they implement the
                [index]
                operator, however, they fail on
                ?size.) | 
              
is_collection | 
                collection (including extended collection) | 
is_collection_ex | 
                extended collection (supports
                ?size) | 
              
is_enumerable | 
                sequence or collection | 
is_indexable | 
                sequence (Historical quirk: it returns
                true for Java methods as they implement the
                [index]
                operator.) | 
              
is_directive | 
                Whatever kind of directive (for example a macro, or
                TemplateDirectiveModel,
                TemplateTransformModel, etc.), or
                function (a historical glitch) | 
              
is_node | 
                node | 
is_markup_output | 
                markup output (a value that won't be auto-escaped) | 
markup_string
This built-in is available since FreeMarker 2.3.24.
Returns the markup stored inside a markup output value
          as string. This is useful if the value has to be passed to a Java
          method for a String parameter, or if we want to
          manipulate the markup directly in the template. Note that the
          resulting string can be converted back to markup output value with
          ?no_esc.
namespace
This built-in returns the namespace (i.e. the "gate" hash to the namespace) associated with a macro or function variable. You can use it with macros and functions only.
new
This is to create a variable of a certain
          TemplateModel implementation.
On the left side of ? you specify a string,
          the full-qualified class name of a TemplateModel
          implementation. The result is a method variable that calls the
          constructor, and returns the new variable.
Example:
<#-- Creates an user-defined directive be calling the parameterless constructor of the class --> <#assign word_wrapp = "com.acmee.freemarker.WordWrapperDirective"?new()> <#-- Creates an user-defined directive be calling the constructor with one numerical argument --> <#assign word_wrapp_narrow = "com.acmee.freemarker.WordWrapperDirective"?new(40)>
For more information about how the constructor parameters are unwrapped and how overloaded constructor is chosen, read: Programmer's Guide/Miscellaneous/Bean wrapper
This built-in can be a security concern because the template
          author can create arbitrary Java objects and then use them, as far
          as they implement TemplateModel. Also the
          template author can trigger static initialization for classes that
          don't even implement TemplateModel. You can
          (since 2.3.17) restrict the classes accessible with this built-in
          using
          Configuration.setNewBuiltinClassResolver(TemplateClassResolver)
          or the new_builtin_class_resolver setting. See
          the Java API docs for more information. If you are allowing
          not-so-much-trusted users to upload templates then you should
          definitely look into this topic.
number_to_date, number_to_time, number_to_datetime
These are used to convert a number (usually a Java
          long) to a date, time or date-time, respectively.
          This does them same as new java.util.Date(long)
          in Java, that is, the number is interpreted as the milliseconds
          passed since the epoch. The number can be anything and of any type
          as far as its value fits into a long. If the
          number isn't a whole number, it will be rounded to whole with
          half-up rule.
Example:
${1305575275540?number_to_datetime}
${1305575275540?number_to_date}
${1305575275540?number_to_time}    The output will be something like this (depending on the current locale and time zone):
May 16, 2011 3:47:55 PM May 16, 2011 3:47:55 PM
sequence
This built-in is used to convert a listable value (one that
          you can iterate through with the list
          directive) to a more capable sequence value. Sequences
          support operations like xs[index] and
          xs?size. Also, the resulting value is listable
          for multiple times, even if the original value was backed by a
          java.util.Iterator (which gives error when you
          try to list it for the 2nd time). This built-in is typically used to
          work around data-model problems, in case you can't fix the
          data-model itself. If you can, always fix the data-model instead
          (give a java.util.List or array to the template
          instead of a more restricted object, like a
          non-List java.util.Collection,
          or a java.util.Iterator).
If the value is already a sequence, then this built-in just
          returns that as is. If the value is not something that the list
          directive could list, then template processing will be
          aborted with error. Otherwise, it usually fetches all the values,
          and stores them into a sequence. Be careful if you can have a huge
          number of items, as all of them will be held in memory on the same
          time. However, in some special cases fetching and/or storing all
          elements is avoided; see about the optimizations
          later.
You should convert a value with sequence
          only once. If you need the resulting sequence at multiple places,
          always assign the result to a variable, because if the value you
          convert is only listable once, converting it for the second time
          will result in error or an empty sequence. Also the conversion is
          somewhat costly for big collections, so it's better to do it only
          once.
Example: Let's say you find that users is
          only listable once (because it's a
          java.util.Iterator), but you need to list it for
          multiple times in the template, and you can't fix the data-model.
          Then you could do this:
<#-- Collect all the users into a sequence: --> <#assign usersSeq = users?sequence> <#list usersSeq as user>...</#list> Again: <#list usersSeq as user>...</#list>
Optimizations
Since version 2.3.29, if the result of the
            sequence built-in is directly the input of to
            the [index]
            or [range]
            operator, or of ?size, or of
            ?first, or a chain of these operations, then
            the elements will not be collected into the memory, and only as
            many elements as strictly necessary will be fetched. For example
            anIterator?sequence[1] will just fetch the
            first 2 items (instead of building a sequence that contains all
            the elements, and then getting the 2nd element from that). Or, if
            you write anIterator?sequence?size, it will
            just skip through all elements to count them, but won't store them
            in memory.
The optimizations will only work within the same chain of
            built-in calls, so for example in <#assign seq =
            anIterator?sequence>${seq[1]} the
            ?sequence step will collect all the elements
            into the memory, as anIterator?sequence and
            seq[1] are separated. On the other hand, the
            optimizations will work in
            anIterator?sequence[10..]?size, as both
            [range] and
            ?size supports it, and they are directly
            chained together.
with_args
This built-in is available since 2.3.30
The goal of this built-in is to add parameters
          dynamically to the call of a directive (like a
          macro), function or method. Dynamically means that parameters are
          added based on a hash value (like {'a': 1, 'b': 2, 'c':
          3} or a Java Map), or a sequence value
          (like [1, 2, 3] or a Java
          List), whose actual content is might only known
          at the moment when the call happens.
For example, we have this macro m:
<#macro m a b c>a=${a}, b=${b}, c=${c}</#macro>    Normally you call it like:
<@m a=1 b=2 c=3 />
Below call does the same, assuming dynArgs
          is the hash {'a': 1, 'b': 2, 'c': 3}:
<@m?with_args(dynArgs) />
a=1, b=1, c=1
Below call also does the same, but combines dynamic arguments
          from dynArgsAB, assumed to be {'a': 1,
          'b': 2}, and argument c specified
          directly:
<@m?with_args(dynArgsAB) c=3 />
a=1, b=1, c=1
To understand why this works, you need to realize that macros,
          custom directives, functions, and methods in FreeMarker are just
          values, just like numbers, strings, etc. <#macro m
          ...> just creates a value
          that's a macro (as opposed to a number, or string, etc.), and then
          assigns it to variable m. Thus,
          m in itself is a valid expression, which
          evaluates to the macro (but it doesn't call the
          macro). <@m ...
          /> evaluates the expression m (and
          you can use arbitrarily complex expressions there too, like
          m?with_args(...)), and
          then calls the resulting macro.
          m?with_args(dynArgs)
          returns a macro that's very similar to the original macro (that's
          stored in m), but its arguments
          default to the values specified in
          dynArgs. So the result
          of m?with_args({'b': 22, 'c': 33}) is similar to
          a modified macro that was created as <#macro
          unspefiedName a b=22 c=33>.
          With an example:
<#assign mWithDefs = m?with_args({'b': 22, 'c': 33})>
<@myWithDefs a=1 c='overridden'/>    a=1, b=22, c=overridden
Above we have created a new macro based on the value of
          m, stored it in variable
          mWithDefs, and then later we called it with
          <@myWithDefs ...
          />.
with_args can also be applied on functions
          (crated with <#function
          ...>) and Java methods
          (usually get from the data-model, like
          myObject.myMethod). But because functions and
          methods can only be called with positional arguments (like
          f(1, 2, 3), and not as
          f(a=1, b=2, c=3)), the argument to
          with_args must be a sequence instead of a hash.
          Other than that, the same tricks work as with macros:
<#function f(a, b, c)><#return "a=${a}, b=${b}, c=${c}"></#function>
<#assign dynArgs=[1, 2, 3]>
${f(1, 2, 3)}
Same as:
${f?with_args(dynArgs)()}
or as:
${f?with_args([1, 2])(3)}
or as:
${f?with_args([1])(2, 3)}
<#assign fWithOneAsFirstArg = f?with_args([1])>
${fWithOneAsFirstArg(2, 3)} <#-- same as f(1, 2, 3) -->    Note the double application of
          (...) above, like in
          f?with_args(dynArgs)().
          That's because
          f?with_args(dynArgs)
          just returns a new function (which is just a value), but doesn't
          call it. So if you want to call that new function immediately (as
          opposed to assigning it to a variable for example), you need the
          second ().
Because macro calls support both named and positional
          arguments, the with_args argument can be a
          sequence for macros as well (though using a hash is usually a better
          practice):
<#macro m a b c>a=${a}, b=${b}, c=${c}</#macro>
<#-- Called with named parameters: -->
<@m a=1 b=2 c=3 />
Same as:
<#-- Called with positional parameters: -->
<@m 1 2 3 />
Same as:
<@m?with_args([1, 2, 3]) />
Same as:
<#-- Sequence with_args with positional c parameter: -->
<@m?with_args([1, 2]) 3 />
Same as:
<#-- Sequence with_args with named c parameter: -->
<@m?with_args([1, 2]) c=3 />    To summarize, depending on the type of the value
          with_args is applied on, the type of argument to
          with_args can be:
- 
              
Function or method: sequence. Note that WRONG
f?with_args(1, 2)is WRONG, the correct form isf?with_args([1, 2]). - 
              
Macro: hash or sequence
 - 
              
Directive (user defined): hash
 
The return type of with_args is the same as
          the type of value it was applied on, like if it's applied on a
          method (like myObj.myMethod?with_args(dynArgs)),
          then it returns a method.
Note that it's not possible to apply
          with_args on built-in directives, like
          <#if ...>,
          <#list ...>,
          etc., because they aren't available as values.
This built-in is often used together with the .args special
          variable. For example:
<#macro m1 a b c>
  m1 does things with ${a}, ${b}, ${c}
</#macro>
<#macro m2 a b c>
  m2 does things with ${a}, ${b}, ${c}
  Delegate to m1:
  <@m1?with_args(.args) />
</#macro>
<@m2 a=1 b=2 c=3 />    m2 does things with 1, 2, 3 Delegate to m1: m1 does things with 1, 2, 3
FreeMarker syntax allows using the name before the
          ?with_args(...) in the
          end-tag, just as if the
          ?with_args(...) wasn't
          there:
<@myMacro?with_args({'a': 1})>...</@myMacro>    Note that as far as the order of arguments is concerned,
          arguments coming from
          with_args(...) are
          added before the arguments specified in the call to the returned
          directive/function/method. In some use cases it's more desirable to
          add them at the end instead, in which case use the with_args_last
          built-in.
with_args_last
This built-in is available since 2.3.30
Same as with_args,
          but if the order of the arguments in resulting final argument list
          may differs (but not the values in it). This only matters if you
          pass parameters by position (typically, when calling functions or
          methods), or when there's catch-all argument.
A typical example with positional arguments is when you want to add the dynamic argument to the end of the parameter list:
<#function f a b c d>
  <#return "a=${a}, b=${b}, c=${c}, d=${d}">
</#function>
<#assign dynamicArgs=[3, 4]>
with_args:
${f?with_args(dynamicArgs)(1, 2)}
with_args_last:
${f?with_args_last(dynamicArgs)(1, 2)}    with_args: a=3, b=4, c=1, d=2 with_args_last: a=1, b=2, c=3, d=4
In the case of name arguments, while the primary mean of
          identifying an argument is the its name, catch-all arguments
          (others... below) still have an order:
<#macro m a b others...>
  a=${a}
  b=${b}
  others:
  <#list others as k, v>
    ${k} = ${v}
  </#list>
</#macro>
<#assign dynamicArgs={'e': 5, 'f': 6}>
with_args:
<@m?with_args(dynamicArgs) a=1 b=2 c=3 d=4 />
with_args_last:
<@m?with_args_last(dynamicArgs) a=1 b=2 c=3 d=4 />    with_args:
  a=1
  b=2
  others:
    e = 5
    f = 6
    c = 3
    d = 4
with_args_last:
  a=1
  b=2
  others:
    c = 3
    d = 4
    e = 5
    f = 6    If you specify a named parameter that are not catch-all, so
          they are declared in the macro tag (as
          a and b below), then
          with_args and with_args_last
          are no different, since the argument order is specified by the macro
          definition, not the macro call:
<#macro m a=0 b=0>
  <#-- We use .args to demonstrate the ordering of a and b: -->
  <#list .args as k, v>
    ${k} = ${v}
  </#list>
</#macro>
<#assign dynamicArgs={'b': 1}>
with_args:
<@m?with_args(dynamicArgs) a=1 />
with_args_last:
<@m?with_args_last(dynamicArgs) a=1 />    with_args:
    a = 1
    b = 1
with_args_last:
    a = 1
    b = 1    If both the macro or directive call, and the
          with_args_last argument specifies named catch-all
          argument with the same name (like b below), then
          the placement of those parameters is decide by the macro/directive
          call:
<#macro m others...>
  <#list others as k, v>
    ${k} = ${v}
  </#list>
</#macro>
<#assign dynamicArgs={'b': 0, 'd': 4}>
with_args:
<@m?with_args(dynamicArgs) a=1 b=2 c=3 />
with_args_last:
<@m?with_args_last(dynamicArgs) a=1 b=2 c=3 />    with_args:
    b = 2
    d = 4
    a = 1
    c = 3
with_args_last:
    a = 1
    b = 2
    c = 3
    d = 4    