Re: How to stop lazy loading of <#include> files?

Chris <[email protected]>
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Unfortunately, there's no way we can calculate variables in a lazy way, 
because there's a giant calculateStuff() method that we use, and all the 
parameters need to be known in advance. And the parameters are defined 
in the template. End-users, over which we have no control, need to put 
${get.this} or ${get.that} in the template where ever they like, and we 
need to know about "this" and "that" in advance.

So, static analysis is the only option.

I understand your point about nesting includes in an <#if>. We'd just 
have to calculate all the variables in both branches.

I think what we're going to have to do is add a preprocessor in our 
template loading code that detects <#include> and replaces it with the 
contents of another file. This isn't fatal.

Caching isn't a problem. We had to replace the entire template loading 
mechanism anyway. We subclassed Configuration, removed the guts of it, 
did the same with Template, built our own cache, and now we've got 
better control.




On 1/5/2011 5:54 PM, Daniel Dekany wrote:
> Both of what you are trying to do is quite difficult to solve... To
> load raw templates, you can just get the TemplateLoader with
> yourConfiguration.getTemplateLoader, and then use its API. However
> then FreeMarker will cache that for you, since it only caches the
> parsed templates (that you could try to examine with it's un-public
> API). Parsing a template to find variable references and includes is
> also not easy. Also both ${...}-s and #include-s can be inside an #if
> and like, so your guess of what is actually needed based on static
> analysis would be inaccurate (pessimistic). That's also why you can't
> force #includes to happen before template processing BTW... they are
> indeed runtime commands.
>
> So, maybe the easier way would be to actually make those variable
> lazily calculated in the data-model. If you only need this for
> top-level variables, then all you need to do is writing a
> TemplateHashModel implementation that only calculates the variable
> when it's first requested. Then pass this object to Template.process
> instead of a Map (or whatever you are using as the data-model root
> currently). If you need something more tricky... the object wrapper
> infrastructure of FM is quite flexible, so it might still can be
> solved.
>
>
> Wednesday, January 5, 2011, 11:08:03 PM, Chris wrote:
>
>> My app, unfortunately, needs to analyze the content of a template before
>> creating a model. It needs to know whether certain expensive-to-create
>> ${variable}s are present before generating the model.
>>
>> We're trying to use<#include>  so we can share common elements in our
>> web pages, like headers and sidebars. Unfortunately, this presents a
>> problem because the Template class loads<#include>  objects in a lazy
>> way. It's not until you call Template.process() that the system calls
>> the TemplateLoader for each include file.
>>
>> How can I force the system to load all of the includes in advance?
>>
>> Then, once they're loaded, how can I get the raw (unprocessed) text of
>> the page, includes included?
>



------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.