Discussion:
[Freemarker-devel] Any idea when optional macro arghuments (or optional variable definition) will be implemented ?
Cameron Braid
2003-11-12 13:18:07 UTC
Permalink
A little while ago someone mentioned that optional macro parameters is
on the todo list.

I was wondering when this may come about, as I think it will be a great
addition to allow for much more complex macro librares to be built.

Especially when trying to use macros in place of html elements, where
lots of things are optional.

The proposed syntax was something like

<#macro theMacroName paramName? > ... </#macro>

the ? after the parameter name making it optional. Am I correct in
saying that since it is optional, if a undefined variable is passed to
the macro call, it will be allowed :

<@theMacroName undefinedVariable/>

currently this works if the macro is defined with a default value for
the parameter as in

<#macro theMacroName paramName=""> ... </#macro>

I would also like to know if this optional syntax can be applied to the
<#assign>, <#local>, <#global> or anywhere that builtins can be used.. ie

currently <$assign thingy = undefinedValue/> gives an invalid reference
exception. I would like to be able to do

<$assign thingy = model.expression? /> which should succeed with thingy
being undefined if model.expression is undefined

This allows for coding things like

<#assign colour = model.defaultColour?/>
...lotsa code here...
<#if colour?exists>
....
</#if>
...lotsa code here...
<#if colour?exists>
....
</#if>

Whereas without it you would have to write either :

<#if model.defaultColour?exists>
<#assign colour = model.defaultColour/>
</#if>

which isn't all that bad since freemarker doesn't scope variables like
java :)

I guess that another way to do the 'allow null reference' is
paramName?default(undefined)
though this introduces a new keyword, and is quite verbose.

<#macro name param?default(undefined) > ... </#macro>

Keen to know your thoughts,

Cameron
--
Any damn fool can write code that a computer can understand...
The trick is to write code that humans can understand.
[Martin Fowler http://www.martinfowler.com/distributedComputing/refactoring.pdf]
Daniel Dekany
2003-11-12 14:13:08 UTC
Permalink
Post by Cameron Braid
A little while ago someone mentioned that optional macro parameters is
on the todo list.
I was wondering when this may come about, as I think it will be a great
addition to allow for much more complex macro librares to be built.
Especially when trying to use macros in place of html elements, where
lots of things are optional.
The proposed syntax was something like
<#macro theMacroName paramName? > ... </#macro>
the ? after the parameter name making it optional. Am I correct in
saying that since it is optional, if a undefined variable is passed to
currently this works if the macro is defined with a default value for
the parameter as in
This is a FreeMarker bug (with the parameters with optional values). The
above macro invocation should throw exception, before calling the macro,
since expression undefinedVariable can't be evaluated.
Post by Cameron Braid
<#macro theMacroName paramName=""> ... </#macro>
I would also like to know if this optional syntax can be applied to the
<#assign>, <#local>, <#global> or anywhere that builtins can be used.. ie
currently <$assign thingy = undefinedValue/> gives an invalid reference
exception. I would like to be able to do
<$assign thingy = model.expression? /> which should succeed with thingy
being undefined if model.expression is undefined
I don't think that such tricks should be allowed. It's an error prone
practice to play with the existence of variables, because the reason of
the non-existence of a variable can be easily a typo. Since, you don't
have to declare variables in FTL... you see, the mistake will not be
apparent, it will not cause error, just generates bad output silently. a
But yes, there are situations when you want to deal with variable
existence, but those situations should be rare, and you should solve
them with buit-ins as ?default("...") or ?exists.
Post by Cameron Braid
This allows for coding things like
<#assign colour = model.defaultColour?/>
...lotsa code here...
<#if colour?exists>
....
</#if>
...lotsa code here...
<#if colour?exists>
....
</#if>
<#if model.defaultColour?exists>
<#assign colour = model.defaultColour/>
</#if>
I see, but I think that <#assign colour = model.defaultColour?/>:

a) It's too tricky... we try to keep FTL *simple*. It's not Perl, where
authors add new hyper-terse syntax for everything, and then try to
understand the code of other people, or even yours, after 2 months... :)
People could be able a learn an MVC template language in a single
afternoon.

b) Encourages the usage of exists vs non-exists logic in templates,
which is a bad practice.

c) BTW, there is little problem, that "?" syntactically to similar to
built-in invocations.
Post by Cameron Braid
which isn't all that bad since freemarker doesn't scope variables like
java :)
I guess that another way to do the 'allow null reference' is
paramName?default(undefined)
though this introduces a new keyword, and is quite verbose.
<#macro name param?default(undefined) > ... </#macro>
Keen to know your thoughts,
Cameron
--
Best regards,
Daniel Dekany
Cameron Braid
2003-11-12 14:53:24 UTC
Permalink
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
Ok.. how do I get around this one :<br>
<br>
I have a macro that has two params that need to be optional, and I need
to source their value from my model.<br>
<br>
&lt;#macro highlight size=12 colour='red' &gt;...&lt;/#macro&gt;<br>
<br>
&lt;#list items as item&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;@hilight size=item.size
colour=item.colour&gt;${item.content}&lt;/@hilight&gt;<br>
&lt;/#list&gt;<br>
<br>
This doesn't work if some items don't have a size and a colour.<br>
<br>
I could use this calling syntax :<br>
&lt;@hilight size=item.size?default(12)
colour=item.colour?default('red') &gt;${item.content}&lt;/@hilight&gt;<br>
<br>
BUT this means that the caller needs to specify the defaults, which
defies the whole point of having defaults.<br>
<br>
I would think that a macro definition like this &lt;#macro print
message&gt;${message?default("")}&lt;/#macro&gt; just mean that you
need to specify the message parameter, not necessarily give it a
value. <br>
<br>
I would think that in most cases nulls should be passed on ignorantly
until they are either output or acted apon.&nbsp; ie ${undefined} should
fail&nbsp; &lt;@print message=undefined&gt;&nbsp; should succeed depending on how
the print macro handles the message argument.<br>
<br>
whereas &lt;@print/&gt; should fail because message isn't specifid.<br>
<br>
There is no way to support this type of functionality currently, as
each time a null value is incountered it MUST be converter to a value,
or the expression needs to be re-written with an ?exists check each
time.<br>
<br>
I believe that you either need to modify the null handling, or
implement nullable arguments to macros and functions.<br>
<br>
I still think it is a hack to have to repeat an expression to avoid
giving a default :<br> <pre wrap="">&lt;#if model.someComplexExpression(item).defaultColour?exists&gt; &lt;@doSomething model.someComplexExpression(item).defaultColour/&gt; &lt;/#if&gt;
...lotsa code here...
&lt;#if model.someComplexExpression(item).defaultColour?exists&gt; &lt;@doSomething model.someComplexExpression(item).defaultColour/&gt; &lt;/#if&gt;
...lotsa code here...
&lt;#if model.someComplexExpression(item).defaultColour?exists&gt; &lt;@doSomething model.someComplexExpression(item).defaultColour/&gt; &lt;/#if&gt;

should be able to be written as</pre> <pre wrap="">&lt;#assign colour = model.someComplexExpression(item).defaultColour/&gt;
&lt;#if colour?exists&gt; &lt;@doSomething colour/&gt; &lt;/#if&gt;
...lotsa code here...
&lt;#if colour?exists&gt; &lt;@doSomething colour/&gt; &lt;/#if&gt;
...lotsa code here...
&lt;#if colour?exists&gt; &lt;@doSomething colour/&gt; &lt;/#if&gt;
</pre>
<br>
Daniel Dekany wrote:<br>
<blockquote type="cite"
cite="mid72-***@freemail.hu">
<pre wrap="">Wednesday, November 12, 2003, 4:14:08 PM, Cameron Braid wrote:

</pre>
<blockquote type="cite">
<pre wrap="">A little while ago someone mentioned that optional macro parameters is
on the todo list.

I was wondering when this may come about, as I think it will be a great
addition to allow for much more complex macro librares to be built.

Especially when trying to use macros in place of html elements, where
lots of things are optional.

The proposed syntax was something like

&lt;#macro theMacroName paramName? &gt; ... &lt;/#macro&gt;

the ? after the parameter name making it optional. Am I correct in
saying that since it is optional, if a undefined variable is passed to
the macro call, it will be allowed :

&lt;@theMacroName undefinedVariable/&gt;

currently this works if the macro is defined with a default value for
the parameter as in
</pre>
</blockquote>
<pre wrap=""><!---->
This is a FreeMarker bug (with the parameters with optional values). The
above macro invocation should throw exception, before calling the macro,
since expression undefinedVariable can't be evaluated. </pre> <blockquote type="cite"> <pre wrap="">&lt;#macro theMacroName paramName=""&gt; ... &lt;/#macro&gt;

I would also like to know if this optional syntax can be applied to the
&lt;#assign&gt;, &lt;#local&gt;, &lt;#global&gt; or anywhere that builtins can be used.. ie

currently &lt;$assign thingy = undefinedValue/&gt; gives an invalid reference
exception. I would like to be able to do

&lt;$assign thingy = model.expression? /&gt; which should succeed with thingy
being undefined if model.expression is undefined
</pre>
</blockquote>
<pre wrap=""><!---->
I don't think that such tricks should be allowed. It's an error prone
practice to play with the existence of variables, because the reason of
the non-existence of a variable can be easily a typo. Since, you don't
have to declare variables in FTL... you see, the mistake will not be
apparent, it will not cause error, just generates bad output silently. a
But yes, there are situations when you want to deal with variable
existence, but those situations should be rare, and you should solve
them with buit-ins as ?default("...") or ?exists.

</pre>
<blockquote type="cite">
<pre wrap="">This allows for coding things like

&lt;#assign colour = model.defaultColour?/&gt;
...lotsa code here...
&lt;#if colour?exists&gt;
....
&lt;/#if&gt;
...lotsa code here...
&lt;#if colour?exists&gt;
....
&lt;/#if&gt;

Whereas without it you would have to write either :

&lt;#if model.defaultColour?exists&gt;
&lt;#assign colour = model.defaultColour/&gt;
&lt;/#if&gt;
</pre>
</blockquote>
<pre wrap=""><!---->
I see, but I think that &lt;#assign colour = model.defaultColour?/&gt;:

a) It's too tricky... we try to keep FTL *simple*. It's not Perl, where
authors add new hyper-terse syntax for everything, and then try to
understand the code of other people, or even yours, after 2 months... :)
People could be able a learn an MVC template language in a single
afternoon.

b) Encourages the usage of exists vs non-exists logic in templates,
which is a bad practice.

c) BTW, there is little problem, that "?" syntactically to similar to
built-in invocations.

</pre>
<blockquote type="cite">
<pre wrap="">which isn't all that bad since freemarker doesn't scope variables like
java :)

I guess that another way to do the 'allow null reference' is
paramName?default(undefined)
though this introduces a new keyword, and is quite verbose.

&lt;#macro name param?default(undefined) &gt; ... &lt;/#macro&gt;

Keen to know your thoughts,

Cameron
</pre>
</blockquote>
<pre wrap=""><!---->
</pre>
</blockquote>
<br>
<br>
<pre cols="72" class="moz-signature">--
Any damn fool can write code that a computer can understand...
The trick is to write code that humans can understand.
[Martin Fowler <a class="moz-txt-link-freetext" href="http://www.martinfowler.com/distributedComputing/refactoring.pdf">http://www.martinfowler.com/distributedComputing/refactoring.pdf</a>]</pre>
</body>
</html>
Daniel Dekany
2003-11-12 21:07:09 UTC
Permalink
Post by Cameron Braid
I have a macro that has two params that need to be optional, and I need
to source their value from my model.
<#macro highlight size=12 colour='red' >...</#macro>
<#list items as item>
</#list>
This doesn't work if some items don't have a size and a colour.
BUT this means that the caller needs to specify the defaults, which
defies the whole point of having defaults.
[snip]

I see, but normally, if the item has no size, then you don't pass size
parameter at all. It's something like <img src="foo"> vs. <img src="foo"
alt="A Foo">; the first img has no "alt"... Of course, I see that in
the case of listing it is not possible, but then some different approach
should be used. Say, you should pass the whole item as parameter, and
then @highlight macro will find out if how to highlight that. Allowing
invalid expressions to evaluate, and then pass the result (which is
"non-existence"?) as parameter value, is IMO not a natural logic at all.
I really wouldn't want people to understand this. Simply, if an
expression is invalid, then it should throw exception, and it does not
mater where the expression is used.

Also, it would be error-prone. Consider if with @img parameter alt is
optional, and then accidentally you write <@img alt=descirption> (note
the typo: desc*ir*ption), then it would be silently accepted. So this
feature would hide mistakes.

So I think that you should rather find an approaches where you don't
need strange features like the proposed.
--
Best regards,
Daniel Dekany
Cameron Braid
2003-11-13 00:39:30 UTC
Permalink
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html;charset=windows-1250">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
Thanks for taking the time to discuss this issue.<br>
<br>
I guess I would just like the ability to allow undefined variables to
be passed, even if they need to use a builtin to say 'allow undefined'<br>
<br>
This way it woule become an optional part of the language, that can be
used in certain circumstances :<br>
<br>
I think a new builtin ?nullable would solve the problem.<br> <br> <pre wrap="">&lt;#list items as item&gt; <!---->    &lt;@hilight size=item.size?nullable colour=item.colour?nullable&gt;${item.content}&lt;/@hilight&gt;
&lt;/#list&gt;</pre>
or <br>
<br>
&lt;#assign thing = model.data?nullable /&gt;<br>
<br>
allowing thing to become 'undefined' and in the case of the hilight
macro, size and colour are specified, but may be null.<br>
<br>
It just really frustrates me when I want to develop macro libraries
that when I use them I run into limitations of the language ;)<br>
<br>
Your workaround for the hilight macro is to pass the item as a paramter
and have it check for .size and .colour itself.  the problem is that
often a mapping is required because of different model structure, not
all items will have .size and .colour, therefore the mapping is
specified when the macro is called.  The only other soloution is to
call a java method that returns a javabean (or hashModel) containing
the mapped instance - which is a worse hack.<br>
<br>
I also don't want to have to use the "illegal marker value" when
calling these macros to allow for undefined values, in the list example
&lt;@hilight size=item.size?default("XXXX")
colour=item.colour?default("XXXX") /&gt;  which is pretty dodgy.<br>
<br>
In your example with &lt;@img alt=descirption&gt; I would expect it to
error, though if you were able to do &lt;@img
alt=descirption?nullable&gt; it would be your own stupid fault if you
missed it.<br>
<br>
I know that I am probably bashing my head against the wall.. but this
is the only part of the freemarker language that annoys me.<br>
<br>
Thanks.<br>
<br>
Cameron<br>
<br>
<br>
Daniel Dekany wrote:<br>
<blockquote type="cite" cite="***@freemail.hu">
<pre wrap="">Wednesday, November 12, 2003, 5:49:26 PM, Cameron Braid wrote:

</pre>
<blockquote type="cite">
<pre wrap=""> Ok.. how do I get around this one :

I have a macro that has two params that need to be optional, and I need
to source their value from my model.

&lt;#macro highlight size=12 colour='red' &gt;...&lt;/#macro&gt;

&lt;#list items as item&gt;
??? &lt;@hilight size=item.size </pre> </blockquote> <pre wrap=""><!---->colour=item.colour&gt;&gt;${item.content}&lt;/@hilight&gt; </pre> <blockquote type="cite"> <pre wrap="">&lt;/#list&gt;

This doesn't work if some items don't have a size and a colour.

I could use this calling syntax :
&lt;@hilight size=item.size?default(12)
colour=item.colour?default('red') &gt;${item.content}&lt;/@hilight&gt;

BUT this means that the caller needs to specify the defaults, which
defies the whole point of having defaults.
</pre>
</blockquote>
<pre wrap=""><!---->[snip]

I see, but normally, if the item has no size, then you don't pass size
parameter at all. It's something like &lt;img src="foo"&gt; vs. &lt;img src="foo"
alt="A Foo"&gt;; the first img has no "alt"... Of course, I see that in
the case of listing it is not possible, but then some different approach
should be used. Say, you should pass the whole item as parameter, and
then @highlight macro will find out if how to highlight that. Allowing
invalid expressions to evaluate, and then pass the result (which is
"non-existence"?) as parameter value, is IMO not a natural logic at all.
I really wouldn't want people to understand this. Simply, if an
expression is invalid, then it should throw exception, and it does not
mater where the expression is used.

Also, it would be error-prone. Consider if with @img parameter alt is
optional, and then accidentally you write &lt;@img alt=descirption&gt; (note
the typo: desc*ir*ption), then it would be silently accepted. So this
feature would hide mistakes.

So I think that you should rather find an approaches where you don't
need strange features like the proposed.

</pre>
</blockquote>
<br>
<br>
<pre cols="72" class="moz-signature">--
Any damn fool can write code that a computer can understand...
The trick is to write code that humans can understand.
[Martin Fowler <a class="moz-txt-link-freetext" href="http://www.martinfowler.com/distributedComputing/refactoring.pdf">http://www.martinfowler.com/distributedComputing/refactoring.pdf</a>]</pre>
</body>
</html>
Daniel Dekany
2003-11-13 08:00:07 UTC
Permalink
Post by Cameron Braid
Thanks for taking the time to discuss this issue.
I guess I would just like the ability to allow undefined variables to
be passed, even if they need to use a builtin to say 'allow undefined'
This way it woule become an optional part of the language, that can be
I think a new builtin ?nullable would solve the problem.
</#list>
or
<#assign thing = model.data?nullable />
allowing thing to become 'undefined' and in the case of the hilight
macro, size and colour are specified, but may be null.
There was a design decision earlier, that FTL does not support the idea
of null. It is obviously a limitation. Serious programming languages as
Java, C etc all support null for good reasons. But FTL meant to be just
a template language, not a programming language (however it has high
programming capabilities compared to other template languages I have
seen). We have believed that for non-programmers "null" is hard to
understand, hard to handle. (Even for programmers actually... think
about that that how much percentage of runtime errors is
null-pointer-exception in C and Java programmes. :))
Post by Cameron Braid
It just really frustrates me when I want to develop macro libraries
that when I use them I run into limitations of the language ;)
It's a situation when you don't know which of my finger to bite... There
was a design decision, that we don't hide undefined variables, so that
the evaluation of undef. var. stops rendering loudly with error message.
Some other languages choose the other approach (let me call that the
"loose approach"), where undefined variables do not cause error, but
silently evaluate to empty string (or something like that). In those
languages, the situation you mention automatically works, since:

<@highlight color=noSuchVar />

is the same as

<@highlight color="" />

which is, from the POV of the execution macro definition body is the
same as:

<@highlight />

because then the local var. corresponds the omitted parameter will be
also undefined var., which evaluates to "":

<#macro highlight color>
<#if color == "">
No color is given.
</#if>
...
</#macro>

The loose approach has pros and cons... the pro is that often you can
describe things tersely, and more simply (as in your case with
<@highlight>), but it has the con that it potentially hides typo
mistakes and data model building and programmer/HTML-designer contract
mistakes (when a vars is missing that should be there). I think that the
strict approach is the better consensus, usually. If I'm right or bad in
this regard, that can be debated endlessly, as I can't show any
statistics that objectively proves my statement...

What you have originally recommend as optional param. mechanism, is
basically that FTL should switch to loose approach temporarily for some
macro parameters, if the macro *definition* (as opposed to the macro
invocation) desires so... wouldn't that be highly confusing?
<@foo x=noSuchVar /> is bad but <@bar x=noSuchVar /> is OK, because the
definition bar specifies so?

Your second recommendation (?nullable) is much more acceptable for me,
as with that you state cleanly, and just on the spot that "This var may
will not be there.". However, it introduces the idea of null (or
whatever we call it) in FTL, which is a major complication for people
who is not already familiar with heavy weight programming languages. You
see, null value is a rather abstract idea, even if it seems obvious for
programmers. And it has consequences that are not even clean for
programmers... e.g. if variable foo exist in the data model and it
stores value null, then foo?exists is true or false?

So maybe the best would be a third solution, that says that "if there is
and undef. var. error at the right side of the =, then ignore the
assignment", syntactically something like:

<#assign foo ?= maybeUndefined>
<@highlight color?=item.color size?=item.size />

but I also see this as too much complication of FTL... something that
brings more confusion than benefit at the end. I'm not sure, though...
--
Best regards,
Daniel Dekany
Chris Nokleberg
2003-11-12 21:21:06 UTC
Permalink
Post by Cameron Braid
A little while ago someone mentioned that optional macro parameters is
on the todo list.
I proposed it and FWIW I still think it is a good idea. It's not
something most users would/should use, but as an implementor of powerful
macro libraries it is sometimes unavoidable. I think the previous
threads hashed out all the arguments for and against pretty well,
though, and to be honest I don't have the time to implement this right
now so I will save my energy for when I have a patch in hand.

You may be interested in the "catch-all" macro argument (last arg +
"..."), which puts all unknown parameters into a hash. You could then
see if the hash contained the optional keys. Of course, we still don't
have a ?contains built-in either :-(

<#macro img src rest...>

Chris
Daniel Dekany
2003-11-12 22:21:06 UTC
Permalink
Post by Chris Nokleberg
Post by Cameron Braid
A little while ago someone mentioned that optional macro parameters is
on the todo list.
I proposed it and FWIW I still think it is a good idea. It's not
something most users would/should use, but as an implementor of powerful
macro libraries it is sometimes unavoidable. I think the previous
threads hashed out all the arguments for and against pretty well,
[snip]

I think that the discussion was not about *that* optional parameter
feature that you have recommended. As far as I remember at least, you
recommendation was that if the optional parameter is omitted when you
invoke the macro, then the corresponding local variable will be
undefined in the macro definition body. And here, the "optional
parameter is not present" means that you didn't specified the parameter
at all, and not that the expression that specifies its value in the
macro call, evaluates to "undefined variable". Right?
--
Best regards,
Daniel Dekany
Chris Nokleberg
2003-11-12 22:51:06 UTC
Permalink
Post by Daniel Dekany
I think that the discussion was not about *that* optional parameter
feature that you have recommended. As far as I remember at least, you
recommendation was that if the optional parameter is omitted when you
invoke the macro, then the corresponding local variable will be
undefined in the macro definition body. And here, the "optional
parameter is not present" means that you didn't specified the parameter
at all, and not that the expression that specifies its value in the
macro call, evaluates to "undefined variable". Right?
Uhh....sure? :-)

How about I'll tell you what I want, and you can tell me if we are
talking about the same thing. I would like to write:

<#macro test foo?>
<#if foo?exists>
FOO IS ${foo}
<#else>
UNDEFINED!
</#if>
</#macro>

<@test/> prints "UNDEFINED!"
<@test foo=3/> prints "FOO IS 3!"


The workaround I use now is to have a "illegal" marker
value, e.g.

<#macro test foo="XXXXXXX">
<#if != "XXXXXXX">
FOO IS ${foo}
<#else>
UNDEFINED!
</#if>
</#macro>

I feel this is unnecessarily ugly and error-prone.

Chris
Daniel Dekany
2003-11-12 23:19:22 UTC
Permalink
Post by Chris Nokleberg
Post by Daniel Dekany
I think that the discussion was not about *that* optional parameter
feature that you have recommended. As far as I remember at least, you
recommendation was that if the optional parameter is omitted when you
invoke the macro, then the corresponding local variable will be
undefined in the macro definition body. And here, the "optional
parameter is not present" means that you didn't specified the parameter
at all, and not that the expression that specifies its value in the
macro call, evaluates to "undefined variable". Right?
Uhh....sure? :-)
How about I'll tell you what I want, and you can tell me if we are
[snip]

According the snipped example, we mean the same thing with "optional
parameters".
--
Best regards,
Daniel Dekany
Daniel Sheppard
2003-11-13 02:51:06 UTC
Permalink
Post by Cameron Braid
<#list items as item>
</#list>
or
<#assign thing = model.data?nullable />
What's wrong with:

<#list items as item>
<@hilight size=item.size?if_exists
colour=item.colour?if_exists>${item.content}</@hilight>
</#list>

<#macro hilight size colour>
<#if !size?has_content><#assign size="large"></#if>
<#if !colour?has_content><#assign colour="red"></#if>
<span style="font-size: ${size}; color: ${colour}"><#nested></span>
</#macro>

I take it the above situation is somewhat similar to what you're after,
but what you'd really like is to be able to write your macro as:

<#macro hilight size="large" colour="red">
<span style="font-size: ${size}; color: ${colour}"><#nested></span>
</#macro>

And still have the same behaviour.

Ie. the real change you're after is that the object returned from
"?if_exists" be treated as a special case by the #macro directive? (And
probably also by the ?exists builtin).

Daniel Sheppard
http://freeroller.net/page/soxbox
#####################################################################################
This email has been scanned by MailMarshal, an email content filter.
#####################################################################################
Attila Szegedi
2003-11-13 08:46:03 UTC
Permalink
When I need "implied" parameters, I usually default them to a value they
can't be otherwise legally assigned, and check for it. It helps to use a
type you normally don't expect (i.e. use an empty sequence as a default for
a numeric parameter). I.e.:

<#macro foo num=[]>
<#if num?isSequence>num is undefined<#else>num = ${num}</#if>
</#macro>

Then invoking
<@foo> will print "num is undefined" and invoking
<@foo num=1/> will print "1"

Naturally, I'm aware this is a kludge.
Of course, it is the best when you can just avoid the whole issue and have
sensible defaults for your parameters.

Attila.

----- Original Message -----
From: "Cameron Braid" <***@datacodex.net>
To: <freemarker-***@lists.sourceforge.net>
Sent: Wednesday, November 12, 2003 4:14 PM
Subject: [Freemarker-devel] Any idea when optional macro arghuments (or
optional variable definition) will be implemented ?
Post by Cameron Braid
A little while ago someone mentioned that optional macro parameters is
on the todo list.
I was wondering when this may come about, as I think it will be a great
addition to allow for much more complex macro librares to be built.
Especially when trying to use macros in place of html elements, where
lots of things are optional.
The proposed syntax was something like
<#macro theMacroName paramName? > ... </#macro>
the ? after the parameter name making it optional. Am I correct in
saying that since it is optional, if a undefined variable is passed to
currently this works if the macro is defined with a default value for
the parameter as in
<#macro theMacroName paramName=""> ... </#macro>
I would also like to know if this optional syntax can be applied to the
<#assign>, <#local>, <#global> or anywhere that builtins can be used.. ie
currently <$assign thingy = undefinedValue/> gives an invalid reference
exception. I would like to be able to do
<$assign thingy = model.expression? /> which should succeed with thingy
being undefined if model.expression is undefined
This allows for coding things like
<#assign colour = model.defaultColour?/>
...lotsa code here...
<#if colour?exists>
....
</#if>
...lotsa code here...
<#if colour?exists>
....
</#if>
<#if model.defaultColour?exists>
<#assign colour = model.defaultColour/>
</#if>
which isn't all that bad since freemarker doesn't scope variables like
java :)
I guess that another way to do the 'allow null reference' is
paramName?default(undefined)
though this introduces a new keyword, and is quite verbose.
<#macro name param?default(undefined) > ... </#macro>
Keen to know your thoughts,
Cameron
--
Any damn fool can write code that a computer can understand...
The trick is to write code that humans can understand.
[Martin Fowler
http://www.martinfowler.com/distributedComputing/refactoring.pdf]
Post by Cameron Braid
-------------------------------------------------------
This SF.Net email sponsored by: ApacheCon 2003,
16-19 November in Las Vegas. Learn firsthand the latest
developments in Apache, PHP, Perl, XML, Java, MySQL,
WebDAV, and more! http://www.apachecon.com/
_______________________________________________
FreeMarker-devel mailing list
https://lists.sourceforge.net/lists/listinfo/freemarker-devel
Loading...