Localization for Struts Freemarker users

Because it took me freaking forever to find instructions on how to do this…

  1. You do NOT need a message-resource tag in your struts configuration files. Those are outdated instructions for old versions of Struts.You do not need to edit ANY xml at all.
  2. Your Action needs to implement Freemarker’s TemplateMethodModel interface
  3. You need a package.properties file (the default locale) and a then another one for each other locale / language you want to support (ex. package_en_US.properties). These should be located in the same package as the Struts action that will be needing them. You can also do ClassName.properties if you want to tie some to a particular class.
  4. Add the code snippet below to your Action. There’s a backup here if it’s borked below.
  5. Insert localized text into the page with a call like this ${text(“property.name”)} Struts will take care of figuring out the default language from the user’s browser. If you have a better way of determining this there is documentation out there on how to programatically specify the locale you want to be used

    public class MyAction extends ActionSupport implements TemplateMethodModel { /*Your functionality here */

     * when you need to display a localized piece of text in
     * the ftl just use  ${text("some.property.name")}
     * there should be a package.properties or ClassName.properties
     * file in the same source package directory as the Action that
     * will be using them. There *is* a way to set a global properties file
     * but I don't know the details.
     * Obviously the text for other languages would be specified in files like
     * package_en_US.properties
     * @return an implementation of TemplateMethodModel which takes a
     * one parameter method, the parameter is the name of the localized property
     * you want to access.
    public TemplateMethodModel getText(){
        return this;
    public TemplateModel exec(List args) throws TemplateModelException {
        if (args.size() != 1) {
            throw new TemplateModelException("Wrong arguments");
        return new SimpleScalar(getText((String)args.get(0)));


ecgn adds the following notes about actions:
There has to be an action class involved in the Struts/Freemarker action.

Example – the following simple page view won’t work:

<action name=”ShowLogin”>
   <result type=”freemarker”>Login.ftl</result>

To get it to work, I have to insert a “dummy” action into the process:

<action name=”ShowLogin” class=”actions.DummyAction”>
<result type=”freemarker”>Login.ftl</result>

Keywords / Google Food: localization, internationalization, i18n, freemarker, struts