StanB123
StanB123

Reputation: 477

Refering to a specific page in Wicket i18n properties file

I am building my first ever Wicket project and I find that the amount of properties files in my code base is growing rapidly. Ideally I would like to contain all internationalization in a single file for each language/region. Just so I can find things easily.

I found out that my application properties file could be ideal for this. My application properties file is called ApiAdminApplication.properties. Now I am trying to add my translatables to this file, without making a mess of things.

According to the javadoc of ComponentStringResourceLoader this should be possible. Apparently the lookup order is as follows:

  page1.properties => form1.input1.Required
  page1.properties => Required
  form1.properties => input1.Required
  form1.properties => Required
  input1.properties => Required
  myApplication.properties => page1.form1.input1.Required
  myApplication.properties => Required

The second to last line contains the behavior I am looking for, but cannot get to work.

I have a page called CustomerEditPage which in turn contains a form with id customerForm

So here is what I am adding to ApiAdminApplication.properties, and what I think should work according to the snippet above:

CustomerEditPage.customerForm.name=Customer name

Sadly, this does not work. I can however get this to work by leaving out the page name, and starting with customerForm, but that is not what I want. I want per page internationalization contained in a single file.

Can anyone give me some pointers on this? Thanks.

Upvotes: 0

Views: 62

Answers (2)

StanB123
StanB123

Reputation: 477

After reporting the bug I ended up doing what martin-g suggested, and extended ClassStringResourceLoader. For your convenience, here is what I did:

public class PrefixedStringResourceLoader extends ClassStringResourceLoader {

    public PrefixedStringResourceLoader(Class<?> clazz) {
        super(clazz);
    }

    protected String getResourcePath(final Component component) {
        final Class<? extends Page> parentClass = component.getPage().getClass();

        final String resPath = super.getResourcePath(component);

        if (!resPath.isEmpty())
            return String.format("%s.%s", parentClass.getSimpleName(), resPath);

        return parentClass.getSimpleName();
    }

}

There is a small gotcha to this. It always requires you to work with complete resource paths. This can be a bit tricky, I had some problems with the snippet below:

<input type="submit" wicket:id="save" wicket:message="value:save" />

This evaluated to CustomerEditPage.customerForm.save.save, where I expected it to become: CustomerEditPage.customerForm.save. This is not the case because the wicket:message actually becomes a child of the save form input.

I ended up going for:

<input type="submit" wicket:id="save" wicket:message="value:caption" />

Which evaluates to CustomerEditPage.customerForm.save.caption, which I find somewhat more readable. Of course, you could roll your own more advanced resource loader, but this one is good enough for me.

Upvotes: 0

martin-g
martin-g

Reputation: 17533

I think the javadoc of ComponentStringResourceLoader is just wrong and should be fixed.

To accomplish what you need you will need to extend ClassStringResourceLoader and override getResourcePath(). In your impl you will have to prepend the result with the name of the page that owns the Component passed as a parameter.

Then you will need to register your loader at ApiAdminApplication#init() method with:

getResourceSettings().getStringResourceLoaders().add(new MyClassStringResourceLoader(ApiAdminApplication.class))

see the defaults.

Please file a bug report at https://issues.apache.org/jira/projects/WICKET/issues so that the javadoc issue is fixed (or someone else who knows better than me how to accomplish this can explain us).

Upvotes: 2

Related Questions