![]() |
||
|
||
![]() |
1. JSP versus FreeMarker? |
|||||||||||||||||||||||||||||||||||||||||
In principle, you can't really compare the two, since they are designed for a different range of tasks. FreeMarker is designed to be the view component in a system which follows the MVC pattern. This means that it is used to render the already prepared data (the model) to HTML (or other text). JSP undertakes wider range of tasks by design, but because of this, it is not really suitable as an MVC view component. Another difference is that FreeMarker is not tied to servlets or even networking; it is just an engine to generate text output by merging a template with Java objects that hold the data -- the data model. So you can integrate it into any system easily. Speaking pragmatically, if you develop MVC Web applications, most probably you will be better off with FreeMarker. You should read this if you are considering replacing JSP with FreeMarker: Programmer's Guide/Using FreeMarker with servlets/Using FreeMarker for ``Model 2'' Note, that since then, the disadvantage of JSP has been significantly decreased with the introduction of JSP 2.0 (JSP 2.0 + JSTL). | |||||||||||||||||||||||||||||||||||||||||
2. Velocity versus FreeMarker? |
|||||||||||||||||||||||||||||||||||||||||
Velocity is a simpler, more lightweight tool by design. Thus, it does not address many tasks that FreeMarker does, and its template language is less powerful in general, but it is simpler; visit http://freemarker.org/fmVsVel.html for details. Currently (2004 March) Velocity has wider third party support and much larger user community. | |||||||||||||||||||||||||||||||||||||||||
3. Will you ever provide backward compatibility? |
|||||||||||||||||||||||||||||||||||||||||
FreeMarker 2.0 was a complete rewrite of FreeMarker 1.x, by a new author. The 1.x series continues as separated project: FreeMarker Classic. Since 2.x follows different philosophy than 1.x, 2.0x releases were immature despite the high major version number. This caused further radical changes between 2.01 and 2.1. As of 2.1 things were much more matured, and 2.2 is almost backward compatible with 2.1. We hope that this tendency continues. Currently, the rule is that releases with different second version number (as 2.1.x and 2.2.x) are not (fully) compatible. Releases where only the third version number differs (as 2.2.1 and 2.2.6) are compatible. We always provide backward compatible bugfix releases for the released versions. So basically, you don't have to switch to a new, non-backward compatible release in an already written product. It's a something for something situation... FreeMarker recovers faster from design mistakes than many other projects, but the price of this is that major releases are not backward compatible. This is admittedly not optimal, it would be better if there are fewer design mistakes... but, well, it is the reality with our current developers. | |||||||||||||||||||||||||||||||||||||||||
4. The documentation writes about feature X, but it seems that FreeMarker doesn't know that, or it behaves in a different way as documented, or a bug that was supposedly fixed is still present. |
|||||||||||||||||||||||||||||||||||||||||
Are you sure that you are using the documentation written for the same version of FreeMarker that you actually use? Especially, note that our online documentation is for the latest usable FreeMarker release. You may use an older release. Are you sure that the Java class loader finds the same freemarker.jar that you expect to use? Maybe there is an older version of freemarker.jar around (such as in the Ant lib directory), which has higher priority. To check this, try to print the version number in a template with ${.version}. If it dies with ``Unknown built-in variable: version'' error message, then you use a release before 2.3-final or 2.2.8, but you can still try to get the version number in the Java code of your application with Configuration.getVersionNumber(). If this method is not present either, then you are using an early 2.3-preview, or a version before 2.2.6. If you think that the documentation or FreeMarker is wrong, please report it using the bug tracker, or the mailing list, or the forums on http://sourceforge.net/projects/freemarker/. Thank you! | |||||||||||||||||||||||||||||||||||||||||
5. Why does FreeMarker print the numbers with strange formatting (as 1,000,000 or 1 000 000 instead of 1000000)? |
|||||||||||||||||||||||||||||||||||||||||
FreeMarker uses the locale-sensitive number formatting capability of the Java platform. The default number format for your locale may uses grouping or other unwanted formatting. To prevent this, you have to override the number format suggested by the Java platform in the FreeMarker configuration. For example:
| |||||||||||||||||||||||||||||||||||||||||
6. Why does FreeMarker print bad decimal and/or grouping separator symbol (as 3.14 instead of 3,14)? |
|||||||||||||||||||||||||||||||||||||||||
Different countries use different decimal/grouping separator symbols. If you see incorrect symbols, then probably your locale is not set properly. Set the default locale of the JVM or override the default locale in the FreeMarker configuration:
| |||||||||||||||||||||||||||||||||||||||||
7. FreeMarker is confused on variable (macro) names such as foo-bar. Why? How to solve this? |
|||||||||||||||||||||||||||||||||||||||||
If you have a variable with strange name, such as foo-bar, FreeMarker will misinterpret what do you want when you write thing as ${foo-bar}. In this concrete case, it will believe that you want subtract the value of bar from foo. This FAQ entry explains how to handle situations like this. If you want to read the variable: Use the square bracket syntax. An example of square bracket syntax is baaz["foo"], which is equivalent with baaz.foo. As the subvariable name with the square bracket syntax is a string literal (in fact, arbitrary expression), it let you write baaz["foo-bar"]. Now you may say that it can be used for hash subvariables only. Yes, but top-level variables are accessible through special hash variable .vars. For example, foo is equivalent with .vars["foo"]. So you can also write .vars["foo-bar"]. Naturally, this trick works with macro invocations too: <@.vars["foo-bar"]/> If you want to create or modify the variable: All directives that let you create or modify a variable (such as assign, local, global, macro, function, etc.) allows the quotation of the destination variable name. For example, <#assign foo = 1> is the same as <#assign "foo" = 1>. So you can write things like <#assign "foo-bar" = 1> and <#macro "foo-bar">. | |||||||||||||||||||||||||||||||||||||||||
8. Why do I get "java.lang.IllegalArgumentException: argument type mismatch" when I try to use X JSP custom tag? |
|||||||||||||||||||||||||||||||||||||||||
On JSP pages you quote all parameter (attribute) values, it does not mater if the type of the parameter is string or boolean or number. But since custom tags are accessible in FTL templates as plain user-defined FTL directives, you have to use the FTL syntax rules inside the custom tags, not the JSP rules. Thus, according to FTL rules, you must not quote boolean and numerical parameter values, or they are interpreted as string values, and this will cause a type mismatch error when FreeMarker tries to pass the value to the custom tag that expects non-string value. For example, the flush parameter to Struts Tiles insert tag is boolean. In JSP the correct syntax was:
but in FTL you should write:
Also, for similar reasons, this is wrong:
and you should write:
(Not flush=${needFlushing}!) | |||||||||||||||||||||||||||||||||||||||||
9. How can I get the parameters to my TemplateMethodModelEx or TemplateTransformModel implementation as plain java.lang.*/java.util.* objects? |
|||||||||||||||||||||||||||||||||||||||||
Unfortunately, there is no general-purpose solution for this problem. The problem is that FreeMarker object wrapping is very flexible, which is good when you access variables from templates, but makes unwrapping on the Java side rather hard. For example, it is possible to wrap a non-java.util.Map object as TemplateHashModel (FTL hash variable). But then, it can't be unwrapped to java.util.Map, since there is no wrapped java.util.Map around at all. Still, you can use freemarker.template.utility.DeepUnwrap to unwrap the parameters, however it can be inefficient, as sometimes it has to build a new HashMap or ArrayList on the fly, also multi-type variables can keep only one of their types with this method. So rather you should access the parameters as TemplateModel-s, as templates do. | |||||||||||||||||||||||||||||||||||||||||
10. How can I use the output of a directive (macro) in expressions (as a parameter to another directive)? |
|||||||||||||||||||||||||||||||||||||||||
Capture the output into a variable with the assign or local directive. For example:
| |||||||||||||||||||||||||||||||||||||||||
11. Why do I have ``?''-s in the output instead of character X? |
|||||||||||||||||||||||||||||||||||||||||
This is because the character that you want to print can't be represented with the charset (encoding) used for the output stream, so the Java platform (not FreeMarker) substitutes the problematic character with question mark. In general you should use the same charset for the output as for the input, or which is even safer, you should always use UTF-8 charset for the output. The charset used for the output stream is not decided by FreeMarker, but by you, when you create the Writer that you pass to the process method of the template. Example: Here I use the charset of the template for the output in a HTTP servlet:
| |||||||||||||||||||||||||||||||||||||||||
12. How to retrieve values calculated in templates after template execution done? |
|||||||||||||||||||||||||||||||||||||||||
First of all, be sure your application is designed well: templates should display data, and almost never calculate data. If you are still sure you want to do it, read on... When you use <#assign x = "foo">, then you do not actually modify the data model (since that is read-only, see: Programmer's Guide/Miscellaneous/Multithreading), but create the x variable in the runtime environment of the processing (see Programmer's Guide/Miscellaneous/Variables). The problem is that this runtime environment will be discarded when Template.process returns, as it was created for a single Template.process:
To prevent this, you can do the below, which is equivalent with the above, except that you have chance to return the variables created in the template:
| |||||||||||||||||||||||||||||||||||||||||
13. Why is FreeMarker logging suppressed for my application? |
|||||||||||||||||||||||||||||||||||||||||
It is because FreeMarker does not find any logging system. To fix this, you must make available one of the following logging systems for your application: Avalon (org.apache.log), Log4J (org.apache.log4j), or use J2SE 1.4 or later (that contains java.util.logging). That is, the class-loader used with your application must find one of the mentioned classes. | |||||||||||||||||||||||||||||||||||||||||
14. In my Servlet based application, how do I show a nice error page instead of a stack trace when error occurs during template processing? |
|||||||||||||||||||||||||||||||||||||||||
First of all, use RETHROW_HANDLER instead of the default DEBUG_HANDLER (for more information about template exception handlers read this...). Now FreeMarker will not print anything to the output when an error occurs, so the control is in your hands. After you have caught the exception of Template.process(...) basically you can follow two strategies:
| |||||||||||||||||||||||||||||||||||||||||
15. I'm using a visual HTML editor that mangles template tags. Will you change the template language syntax to accommodate my editor? |
|||||||||||||||||||||||||||||||||||||||||
We won't change the standard version, because a lot of templates depend on it. Our view is that the editors that break template code are themselves broken. A good editor should ignore, not mangle, what it doesn't understand. | |||||||||||||||||||||||||||||||||||||||||
16. How fast is FreeMarker? Is it true that 2.x is slower than 1.x (FreeMarker classic)? |
|||||||||||||||||||||||||||||||||||||||||
First of all, don't forget that FreeMarker is only the view rendering component in an MVC system. Furthermore MVC templates tend to be simple: many static text with a few interpolations and loops and conditional block. So it is not like PHP or Model 1 JSP; your application performance is not affected that much by the execution time of templates. FreeMarker is certainly fast enough that it will only very rarely be a bottleneck in your application. Rather, other factors such as the speed of the data-base operations or network bandwidth will likely dominate. The impact of FreeMarker performance could be noticeable only for really busy sites (say, over 30 hits per second per server), where almost all database data is cached. If you are finding FreeMarker slow, do make sure that the cache of parsed templates works well (Configuration.getTemplate uses caching). Parsing a template file is a relatively costly step; in most long-running server-side applications, you will want to parse a template once and have it be used many times. Note that FreeMarker 2.1.4 and earlier versions have bugs that can ruin caching. FreeMarker 2.1 is slower than 1.7.1. This surely depends on your templates, but it could be slower by a factor of 2 or 3. But again, it does not means that response time will be 2 or 3 times slower; most FreeMarker user simply should not be able to perceive the change in the final response time. | |||||||||||||||||||||||||||||||||||||||||
17. How can my Java classes ask a template for information about its structure (e.g. a list of all the variables)? |
|||||||||||||||||||||||||||||||||||||||||
In FreeMarker 2.2, Template has an undocumented method for examining the parsed template: getRootTreeNode. But listing all accessed variables is not possible, because variable names can be dynamically generated from data. However, there's a more important reason why FreeMarker doesn't support this. The design of FreeMarker is based on the idea of a separation between business objects and presentation objects. This separation takes two forms:
Since the business objects don't rely on the templates, if you need to use them with some other presentation system, you won't have to rewrite your application. | |||||||||||||||||||||||||||||||||||||||||
18. If we distribute FreeMarker with our product, do we have to release the source code for our product? |
|||||||||||||||||||||||||||||||||||||||||
No. As of 2.0, FreeMarker is released under a BSD-style license. This means that source or binary distributions may be made freely, and can be included in other products, whether commercial or open source. The only restrictions apply to the copyright of FreeMarker itself, and the use of FreeMarker or its contributors as endorsements of your own product. See the LICENSE for further details. If you use FreeMarker, we hope you'll send us a link to some information about your product, but that's optional as well. |
![]() |
||
|
||
![]() |
![]() |
|
Page generated: 2004-06-15 22:17:59 GMT | FreeMarker Manual -- For FreeMarker 2.3 |