Re: Configuration initialization per web request issue

Daniel Dekany <[email protected]> Sun, 10 Feb 2013 12:14:14 +0100
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Sunday, February 10, 2013, 12:07:35 PM, Albert Kam wrote:

> Your reply is very helpful. I think i understand the important
> points about caching and whether it's cachable or not. This clears
> up about the expensiveness without caching, having to reparse everything per request.
>
> I just realized we can get the localized template by passing the
> locale in the config.getTemplate(),
> so with this, i dont need to use properties anymore.
>
> I will just use cfg.setDirectoryForTemplateLoading() and use
> multiple ftl files instead of merging all into one properties file,
> therefore having the caching feature and no need for custom
> template loader anymore (which in my previous idea wont work well,
> because all caches will be purged if the properties file was
> changed, even if for just one property)
>
> The convinience that i will lose is everything is not inside 1 file
> anymore like the properties file, but i think i can cope with it with some tools.

I suppose this is clear, but with a custom TemplateLoader you can
still put all the templates into the same file.

-- 
Best regards,
 Daniel Dekany


> Thank you !
>
> Regards from Jakarta,
> Albert
>
>
> On Sun, Feb 10, 2013 at 5:18 PM, Daniel Dekany <[email protected]> wrote:
> 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