[
https://issues.apache.org/jira/browse/FREEMARKER-61?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16083565#comment-16083565
]
Daniel Dekany edited comment on FREEMARKER-61 at 7/12/17 7:22 AM:
------------------------------------------------------------------
{{sort}} is currently parameterless, so adding parameters would mean that the
return value of {{foo?sort}} will have to change from purely sequence to
sequence plus method, which is not 100% backward compatible. But I think
{{sort_using}} (or rather, {{sort_with}}?) is not worse than {{sort}} anyway,
because it expresses clearly what the argument does. (Adding one more built-in
name is not really new syntax, I'm not afraid of it... there are hundreds of it
already.)
Using {{ObjectConstructor}} is highly discouraged because of security concerns.
It can't be removed due to backward compatibility unfortunately, but some use
{{freemarker.core.TemplateClassResolver.SAFER_RESOLVER}} to fix this issue. We
can't build a core feature on its existence. But, if {{MyComparator}}
implements {{TemplateModel}} (which is an empty interface), then you can use
{{?new}}.
Why do you want unwrapping per item to be the default? Also, why do you want it
to a be an option exposed to the caller? When would you use {{true}} or
{{false}}, as a template author? (Most users have no idea what object wrapping
is, so the parameter doesn't make sense for them. Also, as FM2 doesn't support
named parameters in function calls, it can't be guessed what that
{{true}}/{{false}} means there. My first bet would be that its increasing vs
descending order, but I would be wrong.)
Edit: OK, I just realize you don't want unwrapping per item, you want the
models to be passed to the {{Comparator}}. Makes sense, though yet again it's
not very performant. Instead of {{String compareThis = user.getName()}} you
would have {{if (\!(user instanceof TemplateHashModel)) die(); TemplateModel
value = ((TemplateHashModel) user).get("name"); if (\!(value instanceof
TemplateScalarModel)) die(); String stringToCompare = ((TemplateScalarModel)
value).getAsString()}}. Models just aren't for data grinding.
was (Author: ddekany):
{{sort}} is currently parameterless, so adding parameters would mean that the
return value of {{foo?sort}} will have to change from purely sequence to
sequence plus method, which is not 100% backward compatible. But I think
{{sort_using}} (or rather, {{sort_with}}?) is not worse than {{sort}} anyway,
because it expresses clearly what the argument does. (Adding one more built-in
name is not really new syntax, I'm not afraid of it... there are hundreds of it
already.)
Using {{ObjectConstructor}} is highly discouraged because of security concerns.
It can't be removed due to backward compatibility unfortunately, but some use
{{freemarker.core.TemplateClassResolver.SAFER_RESOLVER}} to fix this issue. We
can't build a core feature on its existence. But, if {{MyComparator}}
implements {{TemplateModel}} (which is an empty interface), then you can use
{{?new}}.
Why do you want unwrapping per item to be the default? Also, why do you want it
to a be an option exposed to the caller? When would you use {{true}} or
{{false}}, as a template author? (Most users have no idea what object wrapping
is, so the parameter doesn't make sense for them. Also, as FM2 doesn't support
named parameters in function calls, it can't be guessed what that
{{true}}/{{false}} means there. My first bet would be that its increasing vs
descending order, but I would be wrong.)
Edit: OK, I just realize you don't want unwrapping per item, you want the
models to be passed to the {{Comparator}}. Makes sense, though yet again it's
not very performant. Instead of {{String compareThis = user.getName()}} you
would have {{if (!(user instanceof TemplateHashModel)) die(); TemplateModel
value = ((TemplateHashModel) user).get("name"); if (!(value instanceof
TemplateScalarModel)) die(); String stringToCompare = ((TemplateScalarModel)
value).getAsString()}}. Models just aren't for data grinding.
> ?sort_using with a Comparator parameter
> ---------------------------------------
>
> Key: FREEMARKER-61
> URL: https://issues.apache.org/jira/browse/FREEMARKER-61
> Project: Apache Freemarker
> Issue Type: New Feature
> Components: engine
> Affects Versions: 2.3.26-incubating
> Reporter: Ondra Žižka
>
> Hi Daniel :)
> I know that lists should be sorted before passing them to the template in
> general.
> In our case, the template is backed by a generic API for graph database which
> gives an {{Iterable}} for any 1:N relation. So sorting needs to happen in the
> template.
> Now I'd like to sort that, for which the {{?sort_by(["...", "..."])}} is good
> enough, except when it gets a bit more complicated - e.g. sometimes the
> values are missing in which case it should sort by something else...
> Doing that in a template is not a good idea, so I suggest this, elegant in my
> opinion, solution:
> First you'd have a Comparator in Java, and perhaps register it like you do
> with {{FreemarkerMethod}}.
> Then you could pass this as a parameter to {{?sort_using.}}
> {code}
> public class SortByName implements Comparator { ... }
> myData.persons?sort_using("SortByName")
> {code}
> This would be even better if it could pass parameters to the constructor:
> {code}
> public class SortByName implements Comparator {
> public SortByName(boolean ladiesFirst) { ... }
> }
> myData.persons?sort_using("SortByName", [true])
> {code}
> This would greatly leverage sorting in templates while not complicating the
> template syntax or cluttering {{?sort_by}}.
> Thanks for considering.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)