On Sat, Sep 2, 2017 at 7:33 PM, Woonsan Ko <[email protected]> wrote:
> On Sat, Sep 2, 2017 at 3:36 AM, Daniel Dekany <[email protected]> wrote:
>> Saturday, September 2, 2017, 5:24:11 AM, Woonsan Ko wrote:
>>
>>> On Thu, Aug 24, 2017 at 4:04 PM, Daniel Dekany <[email protected]> wrote:
>>>> Thursday, August 24, 2017, 9:53:11 AM, Daniel Dekany wrote:
>>>>
>>>>> Thursday, August 24, 2017, 6:19:29 AM, Woonsan Ko wrote:
>>>>>
>>>>>> On Mon, Aug 21, 2017 at 12:19 AM, Daniel Dekany <[email protected]> 
>>>>>> wrote:
>>>>>>> Monday, August 7, 2017, 9:18:36 PM, Woonsan Ko wrote:
>>>>>>>
>>>>>>>> On Mon, Aug 7, 2017 at 11:03 AM, Daniel Dekany <[email protected]> 
>>>>>>>> wrote:
>>>>>>>>> If you are going to implement these directly as
>>>>>>>>> TemplateDirectiveModel-s and TemplateFunctionModel-s, then you better
>>>>>>>>> wait until I merge at least the FREEMARKER-63 PR... probably also
>>>>>>>>> FREEMARKER-64. I will try to do that tonight. At least 63.
>>>>>>>>
>>>>>>>> OK, I'll watch and wait for that. :-)
>>>>>>>
>>>>>>> FREEMARKER-63, 64 and 65 has been committed. Try to use CallableUtils
>>>>>>> for argument validation and other exception creation. See
>>>>>>> AssertFailsDirective as an example. Of course, ideas for improving
>>>>>>> CallableUtils are highly welcome.
>>>>>>>
>>>>>>> BTW, certainly there are several TemplateFunctionModel and
>>>>>>> TemplateDirectiveModel implementations that could but don't yet use
>>>>>>> CallableUtils for argument validation. If you spot some, you may go
>>>>>>> ahead and improve them.
>>>>>>
>>>>>> Thank you so much! I've briefly browsed the PRs linked from the JIRA
>>>>>> tickets, and it is really great!
>>>>
>>>> Though you better look at the examples in the 3.0 branch, because
>>>> FREEMARKER-65 wasn't a PR; I have committed it directly there. (Maybe
>>>> I shouldn't do that.)
>>>>
>>>>>> Really easy to extend it with
>>>>>> TemplateCallableModel. Very simple but really powerful! I also saw
>>>>>> IncludePage directive (as named "include_page")  in
>>>>>> freemarker-servlet; it looks really straightforward.
>>>>>> I'll try to write equivalent directives or functions from spring JSP
>>>>>> Tag Library [1] and spring-form JSP Tag Library [2].
>>>>>
>>>>> Certainly quite a few changes will be needed compared to the JSP
>>>>> taglib. One such question if when and how escaping related
>>>>> functionality will appear, as escaping is a core facility in FTL.
>>>>> Also there are strange things like `<spring:url path=... var='v'>`.
>>>>> I'm not sure why that isn't a function (used like
>>>>> <c:set v=spring:ulr(path)>)...
>>>>
>>>> With correct JSP syntax that actually would be
>>>>
>>>>   <c:set var="v" value="${spring:url("somePath")}">
>>>>
>>>> if spring:url was a function. So it's kind of understandable that they
>>>> rather go with
>>>>
>>>>   <spring:url path="somePath" var="v" />
>>>>
>>>> But in FreeMarker it would be just:
>>>>
>>>>   <#assign v = spring.url("somePath")>
>>>>
>>>> or if you want to print it into the HTML:
>>>>
>>>>   <a href="${spring.url("somePath")}">
>>>>
>>>> So this was a case where what's a custom tag in JSP should be a
>>>> function in FreeMarker, not a directive.
>>>>
>>>>> Also note that in FTL you can have positional parameters for
>>>>> directives, and named parameters for functions.
>>>>
>>>> Usually, if a directive has a required parameter, whose meaning is
>>>> obvious for almost anybody, then that should be a positional
>>>> parameter. A very clear case of this is <#if something>. A less clear
>>>> case, but still maybe a good idea is making the "path" parameter of
>>>> form:input, form:label etc. positional:
>>>>
>>>>     <tr>
>>>>       <td><@form.label "contactPerson">Contact person</@></td>
>>>>       <td><@form.input "contactPerson"/></td>
>>>>     </tr>
>>>>
>>>> I think anyone who knows even a little about Spring forms will know
>>>> that "contactPerson" is the property name in the backing form bean. Or
>>>> if not, path="contactPerson" is not much more helpful either.
>>>>
>>>> Another place where FreeMarker differs from the approach of the Spring
>>>> JSP tags is when you refer to a value of the model (or to any Servlet
>>>> attribute). Like, you have an "employee" bean in the Spring Model, and
>>>> as far as I see in JSP you are supposed to bind that to a form like
>>>> this:
>>>>
>>>>   <form:form action="/storeEmployee" modelAttribute="employee">
>>>>
>>>> While technically possible, that's quote alien from FreeMarker. If the
>>>> directive wants to do something with the `emloyee` object, then pass
>>>> the object itself to it as argument, not the name of it. Like this:
>>>>
>>>>   <@form.form action="/storeEmployee" model=employee>
>>>>
>>>> Unless, the `form` directive indeed has to know the *name* of the
>>>> variable, as opposed to just the value of it... I'm not sure if that's
>>>> the case here. But I have seen this patter a few times in JSP (pass
>>>> the name of something instead of the thing itself), and had the
>>>> feeling that often it's just to avoid the more noisy
>>>> `model="${employee}"` syntax. FreeMarker has no such problem, as it's
>>>> just `model=employee` there, which is even less verbose than passing
>>>> the name of the variable.
>>>>
>>>>> Also that a value can be both a function and a directive; maybe
>>>>> useful for message printing. If called like a function, it returns a
>>>>> string, if called like a tag, it prints the message without
>>>>> escaping... maybe.
>>>>
>>>> So that practically means that these two will be equivalent:
>>>>
>>>>   <@spring.message "foo" />
>>>>
>>>>   ${spring.message("foo")?noEsc}
>>>>
>>>> Now this is maybe too confusing for most users and thus is a bad idea.
>>>> But if spring.message will only have one type, then that's surely
>>>> function, not directive (unlike in the FM2 Spring integration).
>>>
>>> <spring:message /> tag also has many optional parameters: message,
>>> code, arguments, argumentSeparator, text, var, scope, htmlEscape and
>>> javaScriptEscape. Without 'var' support by a directive, it means
>>> invoking the function for the same parameters every time. code means
>>> resource bundle key, text means default value if not found, and
>>> message means an argument for the Spring-specific
>>> MessageSourceResolvable. So, in this specific case, I don't know which
>>> one should take the positional parameter. Perhaps 'code'?
>>
>> Yes. That's the only required parameter to start with. Also, if you
>
> One problem is that 'code' is not required in spring tag. Perhaps
> someones are using the tag without 'code' in some cases.
> I assume the only positional parameter for 'code' in FTL function
> could be optional with default value being null, right?

I've tried with the idea as spring.message function:
- 
https://github.com/woonsan/incubator-freemarker/blob/feature/FREEMARKER-55-2/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java

It reads 'code' and message arguments from positional vargs, with no
predefined positional args since it should support 'message' named
parameter without 'code'.
For example,
<th>${spring.message("user.firstName")!}</th>
<p>${spring.message("user.form.message", user.firstName,
user.lastName, user.email)?html}</p>
(ref: 
https://github.com/woonsan/spring-mvc-freemarker3-demo/blob/master/src/main/webapp/WEB-INF/views/useredit.ftl)

Still need to add an example using 'message' named parameter.

Regards,

Woonsan

>
>> look at `spring.message("foo")`, I think you would intuitively think
>> that it prints the "foo" message. As of the others, I guess we don't
>> need "text" as you can write ${spring.message("foo")!'default'}, nor
>> do we need the xxxEscape parameters, as we have HTML auto-escaping and
>> `spring.message("foo")?jsString`.
>
> Oh, cool! I didn't know we have ?jsString. Perfect.
>
>>
>>>>
>>>> Something that would be interesting if the spring.message function can
>>>> somehow tell if a message is plain text or HTML. Like you can
>>>> configure which messages are HTML on name patterns (or a content
>>>> pattern, like all HTML values start with "<span>"). After all, without
>>>> such a rule, how do the developers themselves know if a message should
>>>> be HTML or plain text. Hopefully the have some exact policy for that.
>>>> If spring.message knows that rule too, then for HTML messages it
>>>> should return a TemplateMarkupOutputModel instead of a string, so it
>>>> will be automatically non-escaped. Then people can just write
>>>> ${spring.message("foo")} without worrying about `?noEsc`. And then we
>>>> certainly don't need the directive "overload" either.
>>>
>>> As far as I know, MessageTag extends HtmlEscapingAwareTag which has
>>> the following javadoc:
>>>
>>>  * <p>Provides a "htmlEscape" property for explicitly specifying whether to
>>>  * apply HTML escaping. If not set, a page-level default (e.g. from the
>>>  * HtmlEscapeTag) or an application-wide default (the "defaultHtmlEscape"
>>>  * context-param in {@code web.xml}) is used.
>>
>> So then it seems we indeed need some spring library configuration
>> parameter that associates an output format (as in
>> http://freemarker.org/docs/dgui_misc_autoescaping.html) to each
>> message, based on patterns. By default everything should be just plain
>> text, to be on the safe side (i.e., auto-escaping will happen for
>> them, because ${} does that). The equivalent of "defaultHtmlEscape"
>> being on is that you assoicate "HTML" output format to all messages.
>
> +1
>
>>
>> This also reinforces that, at least in the first iteration,
>> spring.message should be function only, not a directive.
>> `${spring.message("foo")}` isn't more verbose than
>> `<@spring.message "foo" />` anyway.
>
> +1
>
>>
>> BTW, I think it may worth having a special syntax for message
>> insertion in the template language. For example,
>> %{label.greet user, today} would be a syntactical sugar for
>> ${someframewok.message('label.greet', user, today)}. But that's
>> another topic.
>
> Sounds promising!
>
> Woonsan
>
>>
>>> Regards,
>>>
>>> Woonsan
>>>
>>>>
>>>>>> By the way, I'm wondering what the best practices are in naming those
>>>>>> models. Should it be better with 'form', 'spring_form', 'spring.form',
>>>>>> or something else? Prefixing with something sounds safer to me.
>>>>>
>>>>> In the templates they should be accessible as <@spring.bind ...> and
>>>>> such. In the case of the form tags, as it's in a separate namespace in
>>>>> JSP, maybe it should be <@form.input ...> etc. (Though I'm not 100%
>>>>> sure if its practical the structure of the JSP taglibs so closely, and
>>>>
>>>> I meant: "if it's practical to follow the structure of the JSP taglibs
>>>> so closely"
>>>>
>>>>> maybe we could just go with <@spring.input ...>. I don't know.)
>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> Woonsan
>>>>>>
>>>>>> [1]
>>>>>> https://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-tld.html
>>>>>> [2]
>>>>>> https://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-form-tld.html
>>>>>>
>>>>>>>
>>>>>>>>> Besides, just to be absolutely clear, I would merge your current PR as
>>>>>>>>> well, if it doesn't raise licensing issues, which is of course a
>>>>>>>>> blocker.
>>>>>>>>
>>>>>>>> Sure, no worries. I was also under a concern about that and wanted to
>>>>>>>> get feedbacks before doing too much. ;-)
>>>>>>>>
>>>>>>>> Regards,
>>>>>>>>
>>>>>>>> Woonsan
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Monday, August 7, 2017, 4:23:26 PM, Woonsan Ko wrote:
>>>>>>>>>
>>>>>>>>>> On Sun, Aug 6, 2017 at 6:14 AM, Daniel Dekany <[email protected]> 
>>>>>>>>>> wrote:
>>>>>>>>>>> The big problem is that spring.ftl is copyrighted by some of the
>>>>>>>>>>> Spring authors (or the Spring project as a whole - it's not clear). 
>>>>>>>>>>> So
>>>>>>>>>>> certainly we can't just copy it. It has to be reimplemented without
>>>>>>>>>>> looking at the source, or something absurd like that. Perhaps the 
>>>>>>>>>>> best
>>>>>>>>>>> is to start out from the spring JSP taglib, as that's the most 
>>>>>>>>>>> widely
>>>>>>>>>>> used templating solution (I assume), so certainly that's the one 
>>>>>>>>>>> where
>>>>>>>>>>> all the features are exposed.
>>>>>>>>>>>
>>>>>>>>>>> I wonder if using #import + FTL is the best way of adding
>>>>>>>>>>> framework-level functionality that's used by a lot of people. It's
>>>>>>>>>>> surely an OK way, but it's not the highest performance way. The 
>>>>>>>>>>> other
>>>>>>>>>>> way is using a shared variable (or some other kind of commonly 
>>>>>>>>>>> visible
>>>>>>>>>>> variable) and implement the library in Java using
>>>>>>>>>>> TemplateDirectiveModel-s and TemplateFunctionModel-s. It's less
>>>>>>>>>>> convenient than doing it in FTL, but it has to be done once, while 
>>>>>>>>>>> you
>>>>>>>>>>> save some resources everywhere where it's used. Though as most of
>>>>>>>>>>> these macros/functions are quite simple, I don't think the 
>>>>>>>>>>> performance
>>>>>>>>>>> difference matters much. But, it also avoids the legal issue above. 
>>>>>>>>>>> I
>>>>>>>>>>> mean, many of these function/macros are so trivial, that it's hard 
>>>>>>>>>>> to
>>>>>>>>>>> implement them on a different way in FTL than as it is in the Spring
>>>>>>>>>>> source code, but if you implement them in Java, then it's much 
>>>>>>>>>>> harder
>>>>>>>>>>> to accuse anyone with stealing. (A minor annoyance right now is that
>>>>>>>>>>> that part of the FreeMarker API is not yet settled; see 
>>>>>>>>>>> FREEMARKER-63,
>>>>>>>>>>> FREEMARKER-64, FREEMARKER-65. But hopefully it will be in a good
>>>>>>>>>>> enough shape soon. And see other thread; input is welcome!)
>>>>>>>>>>>
>>>>>>>>>>> As of template aliases, at the first glance that's fine. Note that
>>>>>>>>>>> there's MultiTemplateLoader which does something similar, but I 
>>>>>>>>>>> assume
>>>>>>>>>>> it would be less neat (and/or slower) to do this with that. (But if
>>>>>>>>>>> the spring functionality won't be #import-ed after all (as above), 
>>>>>>>>>>> the
>>>>>>>>>>> whole thing can become unnecessary...)
>>>>>>>>>>
>>>>>>>>>> Thank you very much for sharing your insights. Greatly helpful 
>>>>>>>>>> advice.
>>>>>>>>>> I agree that it might be better with template model(s) rather than
>>>>>>>>>> library FTL in various aspects.
>>>>>>>>>> Let me try with that approach again and let you know soon with a new 
>>>>>>>>>> PR.
>>>>>>>>>>
>>>>>>>>>> Thank again,
>>>>>>>>>>
>>>>>>>>>> Woonsan
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Sunday, August 6, 2017, 7:22:00 AM, ASF GitHub Bot (JIRA) wrote:
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>     [
>>>>>>>>>>>> https://issues.apache.org/jira/browse/FREEMARKER-55?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16115649#comment-16115649
>>>>>>>>>>>>  ]
>>>>>>>>>>>>
>>>>>>>>>>>> ASF GitHub Bot commented on FREEMARKER-55:
>>>>>>>>>>>> ------------------------------------------
>>>>>>>>>>>>
>>>>>>>>>>>> GitHub user woonsan opened a pull request:
>>>>>>>>>>>>
>>>>>>>>>>>>     https://github.com/apache/incubator-freemarker/pull/31
>>>>>>>>>>>>
>>>>>>>>>>>>     FREEMARKER-55: spring.ftl marco lib support
>>>>>>>>>>>>
>>>>>>>>>>>>     - Support <#import "/spring.ftl" as spring> like Spring 
>>>>>>>>>>>> Framework does.
>>>>>>>>>>>>     - By default, the system lib from /spring.ftl is read from the
>>>>>>>>>>>> specific classpath, not from app's template path.
>>>>>>>>>>>>        The system template aliases map can be customized through
>>>>>>>>>>>> SpringResourceTemplateLoader.systemTemplateAliases property.
>>>>>>>>>>>>     - The same macros and functions are defined in /spring.ftl as
>>>>>>>>>>>> Spring Framework's, with syntax changes to comply with FM3.
>>>>>>>>>>>>     - Note: As the system template lib support is handled by
>>>>>>>>>>>> SpringTemplateLoader in this PR, it means developers should always
>>>>>>>>>>>> use SpringTemplateLoader directly or indirectly in order to use the
>>>>>>>>>>>> system macro library. Please review this decision.
>>>>>>>>>>>>     - TODOs: review/test/refine each macro and functions in 
>>>>>>>>>>>> spring.ftl.
>>>>>>>>>>>>
>>>>>>>>>>>> You can merge this pull request into a Git repository by running:
>>>>>>>>>>>>
>>>>>>>>>>>>     $ git pull https://github.com/woonsan/incubator-freemarker 
>>>>>>>>>>>> feature/FREEMARKER-55
>>>>>>>>>>>>
>>>>>>>>>>>> Alternatively you can review and apply these changes as the patch 
>>>>>>>>>>>> at:
>>>>>>>>>>>>
>>>>>>>>>>>>     https://github.com/apache/incubator-freemarker/pull/31.patch
>>>>>>>>>>>>
>>>>>>>>>>>> To close this pull request, make a commit to your master/trunk 
>>>>>>>>>>>> branch
>>>>>>>>>>>> with (at least) the following in the commit message:
>>>>>>>>>>>>
>>>>>>>>>>>>     This closes #31
>>>>>>>>>>>>
>>>>>>>>>>>> ----
>>>>>>>>>>>> commit 8e0f33c419d982279d7fb22a9dfdc66f47abaf2c
>>>>>>>>>>>> Author: Woonsan Ko <[email protected]>
>>>>>>>>>>>> Date:   2017-07-14T15:27:17Z
>>>>>>>>>>>>
>>>>>>>>>>>>     FREEMARKER-55: Renaming Freemarker to FreeMarker
>>>>>>>>>>>>
>>>>>>>>>>>> commit ec8d687d4ce2c0e1bb3e3ca073b139eacc198527
>>>>>>>>>>>> Author: Woonsan Ko <[email protected]>
>>>>>>>>>>>> Date:   2017-07-14T15:53:51Z
>>>>>>>>>>>>
>>>>>>>>>>>>     Merge branch '3' into feature/FREEMARKER-55
>>>>>>>>>>>>
>>>>>>>>>>>> commit e7cb6f7cfc241689c85527971bf6e1ea7ced9127
>>>>>>>>>>>> Author: Woonsan Ko <[email protected]>
>>>>>>>>>>>> Date:   2017-07-14T17:57:29Z
>>>>>>>>>>>>
>>>>>>>>>>>>     Merge branch '3' into feature/FREEMARKER-55
>>>>>>>>>>>>
>>>>>>>>>>>> commit c6eb09de91e57035c1e0e3c4d3490b3b96622bab
>>>>>>>>>>>> Author: Woonsan Ko <[email protected]>
>>>>>>>>>>>> Date:   2017-07-16T18:24:55Z
>>>>>>>>>>>>
>>>>>>>>>>>>     Merge branch '3' into feature/FREEMARKER-55
>>>>>>>>>>>>
>>>>>>>>>>>> commit 870209fa8e0acd0bb3186053dfd549b5c758e37d
>>>>>>>>>>>> Author: Woonsan Ko <[email protected]>
>>>>>>>>>>>> Date:   2017-07-18T00:38:03Z
>>>>>>>>>>>>
>>>>>>>>>>>>     Merge branch '3' into feature/FREEMARKER-55
>>>>>>>>>>>>
>>>>>>>>>>>> commit 4481406a2f4eeb30d6d044a4ac158efab7ba7a7b
>>>>>>>>>>>> Author: Woonsan Ko <[email protected]>
>>>>>>>>>>>> Date:   2017-08-06T01:28:54Z
>>>>>>>>>>>>
>>>>>>>>>>>>     Merge branch '3' into feature/FREEMARKER-55
>>>>>>>>>>>>
>>>>>>>>>>>> commit fcd9e672ec515e3042bc5efd229b7d12c23e7d88
>>>>>>>>>>>> Author: Woonsan Ko <[email protected]>
>>>>>>>>>>>> Date:   2017-08-06T05:09:12Z
>>>>>>>>>>>>
>>>>>>>>>>>>     FREEMARKER-55: system template lib for spring app: spring.ftl.
>>>>>>>>>>>>
>>>>>>>>>>>> ----
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>> FM3 freemarker-spring module, Web MVC support
>>>>>>>>>>>>> ---------------------------------------------
>>>>>>>>>>>>>
>>>>>>>>>>>>>                 Key: FREEMARKER-55
>>>>>>>>>>>>>                 URL: 
>>>>>>>>>>>>> https://issues.apache.org/jira/browse/FREEMARKER-55
>>>>>>>>>>>>>             Project: Apache Freemarker
>>>>>>>>>>>>>          Issue Type: Task
>>>>>>>>>>>>>    Affects Versions: 3.0.0
>>>>>>>>>>>>>            Reporter: Daniel Dekany
>>>>>>>>>>>>>
>>>>>>>>>>>>> Add Spring "Web MVC framework" functionality to freemarker-spring.
>>>>>>>>>>>>> This can be complex task (and the issue possibly has to be 
>>>>>>>>>>>>> subdivided), as it involves things like:
>>>>>>>>>>>>> * Some aspects of the FreeMarker 2 integration (developed by the 
>>>>>>>>>>>>> Spring developers) are quite confusing ({{FreemarerConfigurer}}, 
>>>>>>>>>>>>> etc.), and we are looking into if it needs to be like that.
>>>>>>>>>>>>> * See if we can support {{@EnableWebMvc}} (note that FreeMarker 2 
>>>>>>>>>>>>> support is hard coded into {{ViewResolverRegistry}}, which we 
>>>>>>>>>>>>> can't modify)
>>>>>>>>>>>>> * Creating custom directives/methods to expose Spring features 
>>>>>>>>>>>>> like the Spring JSP Tag Library does (but in a way that firs 
>>>>>>>>>>>>> FreeMarker better)
>>>>>>>>>>>>> * Expose JSP custom tag support from the {{freemarker-servlet}} 
>>>>>>>>>>>>> module.
>>>>>>>>>>>>> Depends on: FREEMARKER-54
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> This message was sent by Atlassian JIRA
>>>>>>>>>>>> (v6.4.14#64029)
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Thanks,
>>>>>>>>>>>  Daniel Dekany
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Thanks,
>>>>>>>>>  Daniel Dekany
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Thanks,
>>>>>>>  Daniel Dekany
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>> --
>>>> Thanks,
>>>>  Daniel Dekany
>>>>
>>>
>>
>> --
>> Thanks,
>>  Daniel Dekany
>>

Reply via email to