Hi all,

I am using FreeMarker since 6 years now. Its working very well for my 
web-frontend, email-templating and (in combination with Fyling Saucer / 
OpenHtmlToPDF https://github.com/danfickle/openhtmltopdf 
<https://github.com/danfickle/openhtmltopdf>) my PDF reporting needs.

It`s cool that FreeMarker is actively develop, even if the current version 
already has more or less everything I need. The minor releases you did the last 
years had all nice little feature additions, which were not required, but 
useful never the less.

For FreeMarker 3 I would have the following requirement: 

Feel free to throw around the Java-API/implementation however you like. If I 
get a ton of compile errors and just have to follow a migration guide, then I 
am happy to do so. That would not be a problem.

But please try to stay as compatible with the existing templates as possible. 
If you really have/want to remove a builtin or system global because its 
deprecated and/or limiting the evolution of FreeMarker then ensure that the 
templates using the old constructs throw an error at parse time. As I always 
preload all templates when starting my servers in production mode that would 
allow me to catch all migration issues. If those removed bultins would only 
throw an error at runtime this would be a show stopper for me. I would not be 
able to migration to FreeMarker 3. And I think that would block the migration 
for other projects too. So please be careful with removing things from the 
template language.

The following features would be great in FreeMarker 3:

- An official way to define variable types in templates. IntellJ Ultimate fully 
supports FreeMarker and allows to define explicit types for variables and macro 
parameters 
(https://www.jetbrains.com/help/idea/2016.3/template-languages-velocity-and-freemarker.html
 
<https://www.jetbrains.com/help/idea/2016.3/template-languages-velocity-and-freemarker.html>).
 You can define them globally for your project and per file / macro. I.e

To define a global root model:
[#-- @ftlvariable name="" type=„xy.myapplcation.model.PageRootFacade"  --]

To define a single variable / macro parameter:
[#-- @ftlvariable name="confluenceArtikel" 
type="xy.myapplcation.model.ConfluenceArticleFacade" —]

Using this comments IntellJ is able to provide full content assist, javadocs 
and even navigation to the Java model object sources. That way FreeMarker gets 
„semistatic“ typed in the IDE and non existing property/method names get 
flagged by IntelliJ. 

Some official supported statement to define this types would be great, e.g.

[#variable name="confluenceArtikel" 
type="xy.myapplcation.model..ConfluenceArticleFacade“]
or
<#variable name="confluenceArtikel" 
type="xy.myapplcation.model..ConfluenceArticleFacade“>

depending on your bracket style. 

- Separate the parser AST from the ExecutionTree. Currently the parser AST is 
also the ExecutionTree and gets executed in place. This is fast to build, 
simple and works well. But the way it is now blocks many optimizations. Ideally 
the pass to convert the parser AST to the ExecutionTree  could be configured. A 
„simple“ and fast mode as default, which just converts the parser AST to an 
ExecuteTree like it is now. But it would be possible to write a optimizing pass 
which uses the type information from the <#variable> declarations and create 
bytecode which tries to do as many things as static typed as possible. Such an 
optimizing pass / mode is of course optional and could be implemented later and 
even require the newest Java version. If delivered as optional maven dependency 
it could also use tools like ByteBuddy.

- If the parser AST would be an official API it would allow IDEs to use it to 
parse the structure and type information from error free templates and build an 
index. Even if it would just be an "inofficial, can change with every 
release“-API I think it could help other IDEs a lot. (IntellJ IDEA has/will 
always implement its own parser, but Eclipse or NetBeans could use that).

- An parser AST would also allow to walk the tree to extract method calls. 
Currently I use reflection (+ setAccessible(true)) to extract all method calls 
to a „magic“ method „_“, which I use for gettext style translations. E.g. from 
a template like: 

<buttton>${_(„My shiny button“)}</button>

the text „My shiny button“ is extracted and put it into a .po file for future 
translation. It works, but is a hack, and sometimes needs fixes when upgrading 
FreeMarker as internal structures/variables change. An official way to do such 
things would be nice.

To be honest, I don`t think that I will have time to implement any of that for 
FreeMarker 3. So this are just suggestions. But maybe some of this, especially 
building an optimized ExecutionTree, could attract new people.

Thanks for this great project and keep up the good work!

cu,
  Emmy

--
Emmeran Seehuber
Dipl. Inf. (FH)
Schrannenstraße 8
86150 Augsburg
USt-IdNr.: DE266070804

Reply via email to