I would like to store my FreeMarker templates in a database table that looks something like:
template_name | template_content
---------------------------------
hello |Hello ${user}
goodbye |So long ${user}
When a request is received for a template with a particular name, this should cause a query to be executed, which loads the relevant template content. This template content, together with the data model (the value of the 'user' variable in the examples above), should then be passed to FreeMarker.
However, the FreeMarker API seems to assume that each template name corresponds to a file of the same name within a particular directory of the filesystem. Is there any way I can easily have my templates loaded from the DB instead of the filesystem?
EDIT: I should have mentioned that I would like to be able to add templates to the database while the application is running, so I can't simply load all templates at startup into a new StringTemplateLoader (as suggested below).
Since 2.3.20 you can simply construct a
Template
using a string:which is a convenience constructor for
Template(name, new StringReader(sourceCode), cfg)
.Old question, but for anyone having the same issue, I achieved an easy solution without the need of a custom template loader or having to load the template at startup.
Suppose you have in your database the dynamic template:
database:
You can just create a Freemarker file (ftlh) that interprets a string received (
content
) and generates a template from it, using interpret:dynamic.ftlh:
Then in your java code you only need to get the string from your database (just like retrieving any other data from the database), and use the file that has
interpret
to generate the template:java:
(Change the methods
getFromDatabase()
andgetConfiguration()
to whatever you want to get the dynamic content from the database and get the Freemarker configuration object, respectively)This should print:
Then you can change your dynamic content in the database or create others, add new parameters and so on, without the need of creating other Freemarker files (ftlh).
Implement configuration.
Example :
}
Then u can use it like this :
For those looking for some code, here it is. Take a look at the comments in the code for a better understanding.
DBTemplate:
TemplateLoader implementation (EMF is an instance of an EntityManagerFactory):
Setup the configuration class:
And finally, use it:
This works great, and allows you to use all of Freemarker's features like imports, includes, etc. Look at the following examples:
Or in:
I use this loader on my own CMS (CinnamonFramework) and works like a charm.
Best,
A couple of ways:
Create a new implementation of TemplateLoader to load templates direct from the database, and pass it to your Configuration instance using
setTemplateLoader()
prior to loading any templates.Use a StringTemplateLoader that you configure from your database when your application starts. Add it to the configuration as above.
Edit in light of the questioner's edit, your own implementation of TemplateLoader looks like the way to go. Check the Javadoc here, it's a simple little interface with only four methods, and its behaviour is well documented.
We use a StringTemplateLoader to load our tempates which we got from the db (as Dan Vinton suggested)
Here is an example:
Edit You don't have to load all templates at startup. Whenever we will access the template, we'll fetch it from the DB and load it through the StringLoader and by calling template.process() we generate (in our case) the XML output.