Step to have user preferences available in your application(s):

1) Implement the Application interface for each "module" of your web-app. These implementations will define a name(getName) and an object defining the parameters you want users to be able to customize: the newPreferencesModel should return a new instance of the model object which will be used to store the user's preferences; the getPreferencesInfo() method should return an array of PreferenceInfo implementations, each describing every item that the user will be able to customize. (I guess this can be related to the javabean/BeanInfo model)

So, on one side you have your preferences model object, one the other, you have their definitions. This is currently only feasible through code, since I'm not a big fan of config files: there are always too many, they are a pain to maintain, and they often end up being as verbose as plain code; however, if someone comes up with good ideas in this area, I'd be happy to include the contributions.

As the interface says, PreferenceInfo describe each item the user can customize, by giving it

The keyName of the PreferenceInfo has two usages : it must correspond to the model's property which it defines, and it is used in the UI to display the name of the property, by using it as the key in the translation system.

Alright, now we have covered the "Application" concept, let's move on:
2) Register all your application implementations in your IOC container
3) Register ApplicationsProvider in your IOC container (currently there is only a CDI-based implementation)

VoilĂ , you're done. In your main decorator or template, you'll now just need to provide a link to the preferences.action within the namespace you configured it.

Internationalization (i18n)

Before reading this, make sure you know about standard java i18n, because we won't recap. In case you don't, >>> tutorial to i18n <<<
In the webwork based implementation, we obviously use ww's i18n system. Of course we had to trick it a bit: usually, translation chains are retrieved based on the current action's class. Instead of that, we wanted to use the Application classes as base location... Ok, what does this all mean? Well, all in all, it's very easy: if you want i18n, just provide properties files named like your Application implementations are. Alright, a sample?
// here use the snippet macro to include FirstSampleApp
then all you'll need is to define the translations accordingly: you should have a directory structure similar to this:
net/incongru/berkano/sample/FirstSampleApp.properties
net/incongru/berkano/sample/FirstSampleApp_fr.properties
net/incongru/berkano/sample/FirstSampleApp_fr_BE.properties
net/incongru/berkano/sample/FirstSampleApp_zn.properties

What keys should I use, you'll ask. Easy:
// here use the snippet macro to include FirstSampleApp.properties

Tips, ideas, ...

I usually have a "global" implementation for generic or global parameters like language, skin choice, ...

(warning) This will currently only work if you use berkano-seraph, or if you provide your own implementation of UserPropertyHelper.