freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dániel Dékány (Jira) <>
Subject [jira] [Commented] (FREEMARKER-107) Hash expansion to macro arguments (Python **kwargs style)
Date Tue, 15 Oct 2019 20:09:00 GMT


Dániel Dékány commented on FREEMARKER-107:

As I imagine it, {{.args}} will only contain the arguments that were actually passed to the
macro (i.e., you can tell exactly what its content will be, just by looking at the calling
side). Because {{.args}} is for delegating a call to another macro as is (except that with
{{?spreadArgs}} you can do argument value overrides too). Thus, by {{<@m3?spreadArgs(.args)/>}}
you truly "replay" the original invocation of the containing macro (of {{m1}} or {{m2}} in
your example). That also means that *parameter defaults*, and catch-all parameters declared
in the originally invoked macro (of {{m1}} or {{m2}} in your example) has no effect on

On the other hand, some user might will expect that if you declared a macro parameter called
{{foo}}, then  {{foo}} and {{}} always give the same. But they may don't, for
several reasons: {{foo}} might was a catch-all argument (and so it's in "exploded" form in
{{.args}}), {{foo}} might have a default (which is not applied in {{.args}}), and last not
least, inside a function {{.args}} is a sequence (a list), so {{.args.someName}} will never
work there.

I'm hoping we are on the same page here, but you might realize something regarding your use
case when you think through these.

> Hash expansion to macro arguments (Python **kwargs style)
> ---------------------------------------------------------
>                 Key: FREEMARKER-107
>                 URL:
>             Project: Apache Freemarker
>          Issue Type: New Feature
>          Components: engine
>    Affects Versions: 2.3.28
>            Reporter: Pascal Proulx
>            Priority: Major
> Hello,
> We heavily rely on Freemarker macros to build a helper template API, but have had to
make large workarounds for passing contents of hashes as macro arguments, for several years.
(In truth I should have made this ticket much sooner!)
> It would help greatly simplify our work to have hash expansion to macro arguments, like
> {code:java}
> <#macro myMacro arg1 arg2 arg3="value3">...</#macro>
> <#assign myHash = {"arg1":"value1", "arg2":"value2"}>
> <@myMacro **myHash/><#-- the hash contents are passed as parameters, instead
of the hash itself -->
> {code}
> This exists in Python:
> {code:java}
> def test_var_args_call(arg1, arg2, arg3):
>     pass
> kwargs = {"arg3": 3, "arg2": "two"}
> test_var_args_call(1, **kwargs)
> {code}
> Essentially the hash contents fill in any arguments not explicitly specified.
> For the case where arguments are specified in addition to the hash, you may need to decide
on a good syntax, e.g.:
> {code:java}
> <@myMacro arg1="value1" **myHash/>{code}
> This example doesn't have much precedent in freemarker syntax but is fairly understandable.
> Although we don't need it nearly as much, the same could be done with lists and function
> {code:java}
> <#function myFunc arg1 arg2>...</#function>
> <#assign myList = ["val1", "val2"]>
> ${myFunc(*myList)}
> <#assign myList = ["val2"]>
> ${myFunc("val1", *myList)}
> {code}
> Again similar to Python:
> {code:java}
> def test_var_args_call(arg1, arg2, arg3):
>     pass
> args = ("two", 3)
> test_var_args_call(1, *args)
> {code}
> You might want this for consistency, although in practice the hash expansion will be
many times more useful to us.
> If there's a lack a manpower I could try to see what I can do digging into the source,
but wanted to bring this up for discussion first. It doesn't appear hard to implement to dump
a hash into the macro args map, but there is defining the syntax.
> We use Freemarker 2.3.28 at the moment.
> Thank you

This message was sent by Atlassian Jira

View raw message