Any web application contains boiler plate text: text that is not part of the enterprise data from web services or databases that is manipulated by the end users using the application but that is part of the application definition itself. Text that is shown as prompt, title, message, hint text and in other ways.
Developers can sprinkle the boilerplate text all throughout the application, in pages, JavaScript and other code sections. But they should not do that. Changing boiler plate text is a frequent requirement from the business. Having all boilerplate text in a central location makes such changes a lot easier. Additionally, many organizations require applications to be multi-lingual: different groups of users speak different languages and want to have the application support them in their own language. That means boiler plate text is not just defined once in that central location, but once for every language the application needs to support.
Java (Web) applications typically make use of a built in structure for centralizing (and internationalizing) boiler plate text; it is called Resource Bundle. Usually, resource bundles are implemented using property files – one per supported language – that contain key-value pairs; note that the XLIFF file format for resource bundles is gaining ground. The key is referred to in pages, code and wherever a boiler plate text element is required, the value is the language specific and centrally managed translation of the key.
This article will demonstrate how to apply resource bundles in an ADF Faces application. However, the true purpose of this article is to serve as an introduction to a subsequent article that will demonstrate how you can decide to implement your resource bundle using a database table instead of a file. Managing database backed resource bundles can be a lot easier than managing their file based equivalent – through a simple edit page for example, used by an application administrator or business representative. Besides, with resource bundles in the database, changes can be applied without having to go through full redeployment of the application.
In other subsequent articles I will discuss how to support not just different boilerplate text items for different languages but also different sets of boiler plate text for user groups that vary by location, role, department, age or personal preference. We will discuss how to refresh a resource bundle in running application and finally we will see how we can create an in-line resource bundle editing mechanism that allows users to manipulate the boiler plate text in context in a running application.
Steps for adding centralized boilerplate text management to ADF applications using Resource Bundles
1. Open JDeveloper and Create a new Fusion Web application
2. Create a new JSF page and add a few components to the page – say a PanelHeader, an inputText and a button;
note that each of these elements has boiler plate text properties: panel title, input field label (or prompt) and hint text, button label and tooltip. Some of these properties are assigned default values (hard coded) and others can be assigned in line, hard coded. Of course, that is not what we are looking for.
3. Create a new file called ApplicationBundle.properties in an application directory, such as /nl/amis/view/bundles:
4. Edit the new file – add a few entries, like
Note that JDeveloper has built in support for editing resource bundles (either property files like this one or XLIFF style bundles or even Java Classes). From the Application menu,pick the option Edit Resource Bundles:
Browse for the properties file and the editor takes it from there:
5. Nothing at this point connects the page to the bundle – or vice versa. The next step is to make the JSF framework aware that this application uses a resource bundle and that the properties file we just created is its implementation.
Open the faces-config.xml file. Open the Application tab. Add a Resource Bundle. The BaseName is the name of the properties file we just created – including the directory structure expressed as Java package name – but without the extension .properties. In this case: nl.amis.view.bundles.ApplicationBundle. The variable that is specified will be used in EL expression in the pages and code of the application when referring to entries from the resource bundle – and should therefore have a short name.
In the XML source, these lines were added:
6. Replace hard coded boilerplate text in the page with references to entries in the resource bundle, using the variable bnd.
Fortunately, JDeveloper provides code completion help to make defining the bundle references easier:
7. But wait, there is more. JDeveloper has additional support for managing resource bundles. You can configure the ViewController project with one or more resource bundles. We have already seen how JDeveloper can help in editing these bundles. It can also help in finding the resources from those bundles – as well as make it easy to support multiple bundles. Let’s see how this goes:
Open the Project Properties. Select the Resource Bundles category:
here the default bundle configuration is done. We can change the name of the default bundle – to use the one we already created – or we can go to the second tab and add our own bundle:
With this set up, we can edit textual properties from the property palette in a more declarative way, as is done here for the button label:
and the JDeveloper text resource selector appears:
The page is slightly modified (automatically). A variable is added, referring to an ADF managed bean that interprets references we make to resource bundle entries in this page. This is needed to support multiple bundles. Note: we will not be using this JDeveloper/ADF mechanism.
8. Run the page. You will see how the hard coded, default boiler plate values have been replaced at run time by values from the resource bundle.
Resources
Download JDeveloper application with the application demonstrated in this article: ADFFacesWithResourceBundle_stepOne_FileBased.
ADF documentation on internationalizing applications using resource bundles: http://docs.oracle.com/cd/E15051_01/web.1111/b31973/af_global.htm.
Programmatically accessing resource bundles, for example from JSF managed beans: http://adfcodebits.blogspot.nl/2010/04/bit-5-accessing-resource-bundle-from.html.
AMIS Blog, Luc Bors on storing modifications on top of resource bundles in database tables: https://technology.amis.nl/2012/07/11/adf-11g-label-modifications-and-persisting-resource-bundle-changes/
Other articles in this series:
-
Introduction to Resource Bundles in ADF applications for centralizing (management of) boilerplate text
-
Implement resource bundles for ADF applications in a database table
-
Supporting multiple languages in ADF applications backed by resource bundles – and programmatically controlling the JSF locale
-
Adding customization (or context sensitivity) to boilerplate text from database backed resource bundles in ADF applications
-
Refresh resource bundle from within the ADF application – to absorb changes in database backed bundles
-
Live update of Resource Bundle from within running ADF application
-
Live resource bundle entry editing in a generic way through declarative component and UI component tree manipulation
-
Creating reusable ADF Library with generic live resource bundle editing functionality and reusing it in any ADF application
Hi Lucas, Article was very informative and we tried similar approach in our project. One of our client requirement is to customize these lables on top of our XLF files. What is the best approach to achieve ? Any hint/help would be much appreciated. Thanks.
Sachin
Hello Lucas, very nice article !
could you help me to understand how i can integrate your way of boilerplate text centralization with the likely messages centralization by throw jboexception. I’m writing a new application and i can’t step forward without to solve this question with an rational programmatic way….
Let me know, your preciuous feedback
have a nice day, Et