A problem in FM2 is that when calling a directive (as a macro), either
all parameters are positional (`<@message "Hi" 2 />`), or all
parameters are named (`<@message content="Hi" height=2 />`); you can't
mix the two (`<@message "Hi" height=2 />`). Also you can't use named
parameters for functions/methods, only for directives. Worse, core
directives don't even use named parameters, but some keyword like
`as`, `using`... their syntax is hard coded into the parser, which is
not nice, and will be a problem for the custom dialects feature.
I think that with the exception of a few core directives (see them
later) all directive calls should be like this, if for now (in this
thread) we ignore loop variables:
<#name posPar1 posPar2 namedPar1Name=namedPar1Value namedPar2=namedPar2Value>
where posPar-s are parameters passed by position, and namedPar-s are
named parameters. Positional parameters strictly precede named ones.
Wether a certain parameter has to be passed as positional or named would be
declared by the directive, and at least the default template language
wouldn't allow you to deviate from that.
Among core directives, an example of using positional parameters is `<#if
something>` (as
opposed to `<#if test=something>`). An example of using named
parameters is `<#ftl outputFormat='RTF'>`. So far it's the same as in
FM2. But now we could have both in once call, such as
`<#visit node handlers=myNamespace>` (regular syntax), which was
`<#visit node using myNamespace>` in FM2 (irregular syntax hard coded
into the parser). But I think this will be mostly handy for custom
directives, which tend to have more parameters, often optional ones
too.
We should extend allowing both positional and named parameters for
function-like callables too, rather than keeping that as a privilege
of directives. It would be like `f(1, 2, foo=3, bar=4)`. Of course
plain Java methods just don't have named parameters, but built-ins and
#functions could have. Handy for example for i10n messages resolution:
`message('greet', name=user.name)`. (In general, I believe we should
make directives and functions (aka. methods) less different in FM3.)
There's the usual dilemma of when a parameter should be positional,
and when named. I think that the philosophy for this template language
should be that parameters are always named, except if the directive
name makes the meaning of the parameter obvious. So it's like as if we
start out from HTML/XML philosophy (every parameter is named), but
remove unhelpful verbosity like `<#if test=user.guest>` or
`<#include template="foo.ftl">`. In other cases I vote for the more
verbose named parameters, as it helps understanding the template, and
users generally have less routine with writing templates than Java and
such, and because the IDE support is not so great either (for one,
because it's not static language).
Some very fundamental core directives still would have exceptional
syntax, such as:
- Assignments (#var/#set as planned for FM3). They look as if they
have named parameter syntax first, but in the future we might want to
allow things like `<#set x[i] = 1>` or `<#set ns.var = 1>`.
- #macro and #function: As in pretty much all languages, the syntax for
defining callable things is not the same as the syntax for calling
things.
- `<#list xs as x>`... though maybe it's not exceptional. `x` is just
a loop variable, and I haven't talked about the standardization of
that in this thread. But in FM2 it's like `<@myDirective blah;
loopVar1, loopVarN>`. But `<#list xs; x>` is IMO not very readable.
Maybe we should just allow `as` in place of `;` for custom
directives, optionally.
Along with these, I would like to remove `=` as a comparator operator
(an alias to `==`). It was already a problem in FM2, as it leads to
ambiguities because `=` is also used for named parameters, but if we
allow the above things, then it's a much bigger problem.
I also would like to allow using `-` unescaped in directive and
parameter names, like `<@my.foo-bar data-x=123 />` (This is a frequent
FM2 request, but couldn't be done because of `=`.)
--
Thanks,
Daniel Dekany