Re: Configuration initialization per web request issue

Daniel Dekany <[email protected]> Sun, 10 Feb 2013 11:18:17 +0100
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Sunday, February 10, 2013, 5:58:54 AM, Albert Kam wrote:

> I want to use freemarker's multiple StringTemplateLoader-s per each
> request. This means that i will have to new Configuration() per each
> request, right ? I wonder if this is the right way to do it, since
> i've read somewhere that Configuration should be initialized once
> per webapp because it's expensive ?

The the biggest expense of not using a long-lived/shared Configuration
instance (and perhaps the only significant expense) is that you trash
the previously built template-cache each time you create a new
configuration. The template-cache stores the templates pre-parsed, so
when you request a template with Configuration.getTemplate(someName,
someLocale) for the 2nd time, FreeMarker will not load and parse it
again.

> Why do i need this approach is because i want to get locale
> specific templates per request, which i put inside a properties
> file, and then fill up the templates.
>
> Example of the entry in the properties file :
> my.template.key1=my.freemarker.template1.here
> my.template.key2=my.freemarker.template2.here
>
> So the logic what i have in mind is :
> - i have the keys in the UI (dynamiclly obtained)
> - i load templates with resourcebundle depending of current user's locale
> - initialize configuration object
> - setup multiple string template loaders with those i load from
> resourcebundle and set them to configuration object via MultiTemplateLoader
> - setup the models n get the template outputs
> - print them onto UI response
>
> All of these can happen per web request.
>
> Is this approach appropriate ? Thank you !

The template cache uses name+locale as the key to look up entries, so
just because you have different locales per request, you don't have to
give up caching. The problematic case is when the templates have no
"name" with which you can identify them, or they have but you don't
have a last modification time for them yet they are changing. In that
case you can't use the cache for *those* templates. But you can still
use the a common configuration, you just use `new Template(...)` to
create ad-hoc Template instances, instead `config.getTemplate(...)`.
The caveat with `new Template(...)` is that templates that are not
available with `config.getTemplate(...)` can't be
#include-ed/#import-ed in other templates.

Of course, to use the template-cache, you need a TemplateLoader that
stays during the whole life-cycle of the Configuration. A
StringTemplateLoader that's recreated for each request won't do. So if
you have some custom template storage, instead of filling a
StringTemplateLoader each time, maybe you can implement the
TemplateLoader interface and then do `config.setTemplateLoader(new
MyResourceBundleTemplateLoader(...))` once.

-- 
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013 
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb