Skip to Content
Technical Articles

UI5ers Buzz #53: Terminologies in UI5

Terminologies in UI5

In our globalized world most companies have a diverse international customer base, selling products to consumers and customers in different industries all around the globe.
As different as these industries might appear, the functional requirements of certain business applications are often quite similar. For example, think about a shopping system. The app for a sports shop is functionally pretty similar to the app for a travel shop. As an application developer, you don’t want to develop two different shop systems when the main differences between these applications are mostly content-related. In many such cases, the apps only differ in wording and vocabulary.
Building a generic application which caters to different industries is already hard enough, even without worrying about terminologies.

But worry not, we got your back!

Since UI5 version 1.77, we provide an easy-to-use approach for customizing applications for different industries.
In this blog post we want to share with you the capabilities of this new feature and give you a stepwise guide on how to use it.
In the following we will call the content-related vocabularies terminologies.

Introduction to Terminologies

As mentioned earlier, a terminology is a content-related vocabulary fitted to a certain industry or business scenario. With Version 1.77, UI5 has gained the capability of defining one or more terminologies for an application, which can be activated during the start-up of your application component. Find more details on the new APIs here.

Up to now, UI5 has only supported resource bundles and *.properties files as a way of providing a localized and translated version of your application. This practically meant you only had a single scenario “hard-coded” into your application. If you now wanted to adapt an application for a similar scenario or industry (as in our shop example above), this typically meant a lot of manual effort. You either had to copy the application or provide additional controller logic to switch between i18n resource models (or bundles for that matter).

With our new feature, we introduce a new dimension to the whole localization scenario.
You can now represent multiple terminologies in one application while still supporting multiple languages as well. This now allows you to represent your application on two dimensions with only one code base and no additional controller or app logic.
One dimension being the language, the other being the content.

But enough of the introduction!
You are developers and want to see some code, right?

Next, we will just walk you through a sample application, which we adapted to offer multiple terminologies.
When you see this demo app and the minimalistic coding needed, we are confident that everything else will become clear to you, too.

Walkthrough

Let’s get started with the practical part of this blog post. In this section, we will take the Shop Administration Tool from the Demo Kit and enhance it with a set of terminologies.

1. Download and run the Demo App

Our first step is to download the app from the Demo Kit. You can download the Shop Administration Tool app here. Click on Download and choose the Shop Administration Tool from the list.

In this exercise we are going to use the command-line interface of the UI5 Tooling to run the app.

After you’ve downloaded the shopping app, run the following commands to serve the app:

npm install --global @ui5/cli
cd "Shop Administration Tool"
npm install
ui5 serve

Open http://localhost:8080/index.html in your browser to launch the app. It should look like this:

1.1 The Folder Structure

Let’s quickly look at the project structure. All the application code is placed in the webapp folder. Open the webapp folder and you’ll see the localization folder called i18n. It contains the *.properties files, one for each language (i18n_de and i18n_en), and a default bundle. We call these top-level *.properties files in the following base bundles. These bundles contain the localized text variants for the application.

In the screenshot, you can also see that our project contains a terminologies folder. In there, you find two more folders, named sports and travel. Each of these folders contain additional *.properties files.

1.2 A Short Primer on the .properties Files

The *.properties files you find in our project contain key-value pairs. The keys are arbitrary and will be used in binding paths inside the ResourceModel that has been defined in the manifest.json. The values are the localized strings which will end up in the UI.

The concept of terminologies is based on overdefining the keys. Take a look at the *.properties files in the i18n/terminologies folder, and you will see that all files (re-)use the same keys. Yet, not all keys are used there, but only the subset that differs from the base bundles. The terminology bundles only need to contain the delta to the base bundles. If you reuse a key in a terminology bundle, the values defined for the same keys in the base bundle are overwritten at runtime.

In the following sections, you will see what this means in practice, and what it will look like in the UI.

To better understand the handling of *.properties files, please also have a look at the dev guide entry and the sample app linked below. They illustrate the way UI5 resolves bundles and retrieves the values inside the *.properties files:

2. Before we continue

Now that you have the application running, something else needs to be done.
Since the Shop Administration Tool app is a complete sample application, it already includes a full configuration of terminologies. For the sake of this walkthrough we first need to remove this configuration and start afresh with a blank manifest.json.

If you want to follow us on this walkthrough, please change the sap.ui5/models section from the manifest.json file to the following content. We’re going to remove the existing definition of terminologies, so we can rebuild them step by step:

"models": {
    "i18n": {
        "type": "sap.ui.model.resource.ResourceModel",
        "settings": {
            "bundleUrl": "i18n/i18n.properties",
            "async": true,
            "fallbackLocale": "en",
            "supportedLocales": ["en", "de"],
            "enhanceWith": []
        }
    },
    "side": {
        "type": "sap.ui.model.json.JSONModel",
        "uri": "model/sideContent.json"
    },
    "alerts": {
        "type": "sap.ui.model.json.JSONModel",
        "uri": "model/alerts.json"
    },
    "customer": {
        "type": "sap.ui.model.json.JSONModel",
        "uri": "model/customers.json"
    }
}

3. Adding a terminology to our project

If you want to customize your application to be enabled for certain terminologies or different industries, the first thing you’d want to do is to open the manifest.json file and the sap.ui5/models section where your ResourceModels are defined, and do some modifications. In our walkthrough we will only pay attention to the i18n model and ignore the other models.

To enhance the base bundle (or base text file) i18n/i18n.properties with additional terminologies, we will add the new terminologies property and certain terminology definitions to the configuration. A terminology definition includes a bundleName or bundleUrl, which points to some resource bundle containing different wording or vocabulary, and a list of supported locales. In our sample application, the supported locales are en and de. For every supported locale, a dedicated resource bundle must be available.

Let’s add travel as our first additional terminology. After you’re done with Step 3, the sap.ui5/models section in your manifest.json file should look like this:

"models": {
    "i18n": {
        "type": "sap.ui.model.resource.ResourceModel",
        "settings": {
            "bundleUrl": "i18n/i18n.properties",
            "async": true,
            "fallbackLocale": "en",
            "supportedLocales": ["en", "de"],
            "terminologies": {
                "travel": {
                    "bundleUrl": "i18n/terminologies/travel/i18n.terminologies.travel.properties",
                    "bundleUrlRelativeTo": "manifest",
                    "supportedLocales": ["en", "de"]
                }
            },
            "enhanceWith": []
        }
    }
}

This configuration part inside the manifest will end up in the sap.base.i18n.ResourceBundle, which will take care of requesting the correct resource bundle files. You can read more about the terminologies property here, and about the terminology definition here.

4. Activating the travel terminology

After we’ve completed our first modifications in the manifest.json, we’re going to activate the travel terminology in our sample app. There are several ways how the available terminologies can be activated.

One way is the sap-ui-activeTerminologies URL parameter, which we’ll use in this walkthrough. You can read about the other options in the Developer’s Guide. To activate the travel terminology we simply add the URL parameter with travel as its argument, and run the app:

http://localhost:8080/index.html?sap-ui-activeTerminologies=travel

When you do this, you’ll notice that the UI has now adapted to the travel industry. More specifically, the image has changed, and so has the app title, as well as pretty much every text.

This specific sample application is tailored to have a main purpose, in this case to serve as a general shop administration tool. Additionally, we have included content for two other versions: sports and travel. This would probably be the first thing you’d do as an application developer if you wanted to introduce terminologies into your application.

5. Adding a second terminology to the mix

Adding a second terminology is as easy as the previous step. Let’s add sports as an additional terminology:

"models": {
    "i18n": {
        "type": "sap.ui.model.resource.ResourceModel",
        "settings": {
            "bundleUrl": "i18n/i18n.properties",
            "async": true,
            "fallbackLocale": "en",
            "supportedLocales": ["en", "de"],
            "terminologies": {
                "travel": {
                    "bundleUrl": "i18n/terminologies/travel/i18n.terminologies.travel.properties",
                    "bundleUrlRelativeTo": "manifest",
                    "supportedLocales": ["en", "de"]
                },
                "sports": {
                    "bundleUrl": "i18n/terminologies/sports/i18n.terminologies.sports.properties",
                    "bundleUrlRelativeTo": "manifest",
                    "supportedLocales": ["en", "de"]
                }
            },
            "enhanceWith": []
        }
    }
}

Run your application with the URL parameter sap-ui-activeTerminologies=sports, and you’ll see a different result: http://localhost:8080/index.html?sap-ui-activeTerminologies=sports

6. Layering of terminologies

When you take another look at the manifest configuration, you’ll probably have already noticed the enhanceWith section, which is still empty. The enhanceWith property is an array, that allows you to define additional bundle configurations. For the purpose of this demo we’re going to add additional resource bundles, which will be layered on top of the original base bundle. The resource bundles we’re going to add to the enhanceWith section are inside a folder called reuse. There, we find two additional folders, appvar1 and appvar2, which contain the resource bundles we’re going to use.

We start with appvar1 and add the terminology bundles for travel and sports. The definition of the terminology bundles looks much like the definition of the base bundle, except that we have different bundle URLs:

"models": {
    "i18n": {
        "type": "sap.ui.model.resource.ResourceModel",
        "settings": {
            "bundleUrl": "i18n/i18n.properties",
            "async": true,
            "fallbackLocale": "en",
            "supportedLocales": ["en", "de"],
            "terminologies": {
                "travel": {
                    "bundleUrl": "i18n/terminologies/travel/i18n.terminologies.travel.properties",
                    "bundleUrlRelativeTo": "manifest",
                    "supportedLocales": ["en", "de"]
                },
                "sports": {
                    "bundleUrl": "i18n/terminologies/sports/i18n.terminologies.sports.properties",
                    "bundleUrlRelativeTo": "manifest",
                    "supportedLocales": ["en", "de"]
                }
            },
            "enhanceWith": [
                {
                    "bundleUrl": "reuse/appvar1/i18n/i18n.properties",
                    "fallbackLocale": "en",
                    "supportedLocales": [
                        "en", "de"
                    ],
                    "terminologies": {
                        "sports": {
                            "bundleUrl": "reuse/appvar1/i18n/terminologies/sports/i18n.terminologies.sports.properties",
                            "bundleUrlRelativeTo": "manifest",
                            "supportedLocales": [
                                "en", "de"
                            ]
                        },
                        "travel": {
                            "bundleUrl": "reuse/appvar1/i18n/terminologies/travel/i18n.terminologies.travel.properties",
                            "bundleUrlRelativeTo": "manifest",
                            "supportedLocales": [
                                "en", "de"
                            ]
                        }
                    }
                }
            ]
        }
    }
}

If you now reload the page with the URL
http://localhost:8080/index.html?sap-ui-activeTerminologies=travel, you should see that the app has changed again, this time from a generic Travel Shop Administration Tool to an app for a specific branch of this industry, which in this example is a Vehicle Rental Administration Tool.

And once we add the resource bundle and the terminology bundle for appvar2 to the enhanceWith array, we’ll see another change in the UI: The app has now changed from a Vehicle Rental Administration Tool to a Bike Rental Administration Tool.

{
    "bundleUrl": "reuse/appvar2/i18n/i18n.properties",
    "fallbackLocale": "en",
    "supportedLocales": [
        "en", "de"
    ],
    "terminologies": {
        "travel": {
            "bundleUrl": "reuse/appvar2/i18n/terminologies/travel/i18n.terminologies.travel.properties",
            "bundleUrlRelativeTo": "manifest",
            "supportedLocales": [
                "en", "de"
            ]
        }
    }
}

As mentioned in the Short Primer on the .properties Files, the concept of terminologies is based on overdefining keys within the .properties files. The terminology bundles will be applied in the order they appear in the enhanceWith array. If a key is used on the UI, UI5 will first look at the last entry of the enhanceWith array. In case the key is not found there, UI5 will look at the second-to-last entry and so on, until the base bundle is reached.

In the following image one tile is highlighted. The text comes from the terminology bundle of appvar1. This happens because the key used in the tile is not defined in the bundle of appvar2, so UI5 will behave as described and look up the text in the second-to-last enhanceWith entry (which in our case is appvar1).

For a better understanding of this behavior, check out the Bundle Resolution app.

Summary: Today You Learned …

  • … what terminologies are.
  • … how to configure terminologies in the manifest.
  • … how to activate terminologies for your Component.
  • … how to layer terminologies on top of each other.

Closing Words

As software developers we tend to lose ourselves in cute technical problems. We create applications, tools, and even entire programming languages without a second thought. But we rarely take a step back and consider why we do all this.

In closing, let us take that step together and move our focus back to the actual reason why we do our job as front-end developers. And for that we’d like to share a quote with you. A quote which has refocused us many times over the years. And we sincerely believe a lot of you will relate to it.

Jef Raskin (1943-2005) was an important figure in computer science, an early advocate of usability, and he is commonly quoted for his Laws of Interface Design. At the end of the first chapter of his book The Humane Interface, you find the following small sentence:

As far as the customer is concerned, the interface is the product. [1]

Twenty years later, we believe that this notion is often overlooked, yet it is truer than ever.
In the end it is all about the customer’s desire for a well-made product. Providing a customized and localized experience to your customers is a sign of respect. Respect for their time and resources. It shows that you care, because winning a customer is hard work, but losing them… well that’s easy. Especially if you don’t speak their language.

We believe localization and customizability are fundamental ingredients of success. They allow you to scale. Not only on a technical, but also on a contentual level. Being able to scale on a contentual level will broaden your customer base and thus, without a doubt, will make your business grow.

Further Reading

References

[1] Raskin, Jef; The humane interface: New Directions for Designing Interactive Systems; 2000; page 5;

 

Previous Post: UI5ers Buzz #52: The Rendering Evolution: Semantic Rendering and CSS Variables

Author

Thorsten & Tommy: We’re colleagues in the UI5 Core Framework team, and we are always happy to contribute nice features to this great UI framework. The coolest part, however, is that we get the chance to share our stuff with you and help you build better applications. Until next time ­čÖé

 

2 Comments
You must be Logged on to comment or reply to a post.