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 >>
