Re: macro errors
Daniel Dekany <[email protected]>
| Newsgroups | gmane.comp.web.freemarker.user |
|---|---|
| Message-ID | <[email protected]> |
Wednesday, July 25, 2012, 6:09:00 AM, Sam Steingold wrote:
> Hi,
> I am getting various macro errors:
>
> <#macro sentiment scmr model><#if scmr??>
> <#assign senti = "${scmr.results[model]}">
> <#if senti??>
> <td>${senti} ---- ${senti.sentimentType}</td>
> <td>${senti.score?html}</td>
> <#else><td align="center" colspan="2">none</td>
> </#if>
> </#if></#macro>
>
> first error:
>
> POSITIVE(1.0/1) ---- Expected hash. senti evaluated instead to freemarker.template.SimpleScalar
>
> this is coming from "${senti} ---- ${senti.sentimentType}"
> apparently, "senti" is the string representation of the object,
> not the object itself.
> how do I fix that?
>
> second error:
>
> Error executing macro: sentiment required parameter: scmr is not specified.
>
> this is coming from this invocation:
>
> <@sentiment model=model scmr=result.title/>
>
> here `result' is non-null, but result.title is null.
> I do check for that in the macro, but, apparently, it has to be done
> outside. Why?
Yeah, the null-madness from the dark ages of FreeMarker, here to stay
with us as far as backward compatibility is kept. Basically, it's
suspected by FreeMarker that the expression result.title is a typo,
and that's why it's undefined (null), hence the error. Now, maybe it's
defined, like `result` is a JavaBean where you have a getTitle()
method that returns null, but FreeMarker doesn't differentiate,
because, if `result` is a Map on the Java-side and there's no title
then there's indeed no "title" key (hence it can't be told if
result.title is a typo or just Java-null). Surely you could tell that
if `result` is a JavaBean, but you should be to able to switch
back-and-forth between a JavaBean `result` and a Map `result` in the
data-model without changing (breaking) the behavior of templates, so
you get the common subset.
What to do? Here's a hack... If know that result.title should be a
String or null, you can call the macro as (note the "!"):
<@sentiment model=model scmr=result.title! />
Then in the macro you can do <#if a?is_sequence>title was null</#if>
or such.
There's also an old implementation bug (that's kept for
backward-compatibility), where, if you pass an undefined expression to
a macro as a parameter (like even something that's indeed a typo), and
the macro defines a default value for the parameter, that default
value will kick in. So if you prefer, you can just do this:
<#macro sentiment scmr! model><#if scmr?is_sequence>
and then you don't need the `!` when calling the macro.
BTW, instead of `?is_sequence` you could use `== ''` too, however if
the parameter can be legally an empty string then it's not a generic
solution.
> Thanks!
--
Best regards,
Daniel Dekany
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/