Choiceformatting i18n messages

This page describes how you can choiceformat an i18n message using just FreeMarker and a message value.

Use case: Display tour duration in words

Background context

In the Magnolia Travel Demo, tour duration is a user-selectable option with four pre-configured duration values: 2, 7, 14 and 21 days. The configuration is stored in a content type definition of the tours module.

/tours/contentTypes/tour.yaml
...
    - name: duration
      options:
        2-days:
          name: 2-days
          value: 2
        7-days:
          name: 7-days
          value: 7
        14-days:
          name: 14-days
          value: 14
        21-days:
          name: 21-days
          value: 21
      type: Long
...

With this configuration, the user can set a duration of a specific tour in the detail view of the Tours app:

Tour duration selector in the detail view of the Tours app

To display the duration value on a published page, the following key-value pair is used in the English i18n message bundle of the tours module:

/tours/i18n/module-travel-tours-frontend_en.properties
...
tour.duration={0} days
...

The FreeMarker part of rendering the value is defined in a DIV element of the tourDetail-content-tags.ftl script in the travel-demo-content-tags module:

/travel-demo-content-tags/templates/components/tourDetail-content-tags.ftl
...
  <div class="property-value">${i18n.get('tour.duration', [tour.duration!])}</div>
...

FreeMarker retrieves the value set by the user in the Tours app and integrates it with the tour.duration i18n message. The information that the Kyoto tour lasts 7 days is then displayed like this on a published page:

A duration value displayed on the English page

However, it is obvious that the i18n value constructed as {0} days would produce a grammatically unacceptable form if we added 1 as an additional item to the range of selectable options:

...
    - name: duration
      options:
        1-day:
          name: 1-day
          value: 1
        2-days:
          name: 2-days
          value: 2
        7-days:
          name: 7-days
          value: 7
        14-days:
          name: 14-days
          value: 14
        21-days:
          name: 21-days
          value: 21
      type: Long
...

Grammatically unacceptable form displayed on the English page

This problem can be solved by choiceformatting the i18n message. Below, we do not expand the range of the pre-configured values (2, 7, 14 and 21), but instead modify the current configuration in such a way that the following messages will be displayed for the four already existing values:

Value Message displayed

2

Weekend

7

Week

14

Fortnight

21

Three weeks

Choiceformatting the i18n value

The first modification required is in the value of the tour.duration i18n key. We change the key-value pair to the following form:

/tours/i18n/module-travel-tours-frontend_en.properties
...
tour.duration={0,choice,2#Weekend|7#Week|14#Fortnight|21#Three weeks}
...

In this form, the i18n value functions as a condition which chooses the message that meets the numerical value selected by the user.

Adjusting the FreeMarker code

A second update for this modification to work correctly is required in the FreeMarker script. There, we need to make sure that the value type passed to the choiceformatted value is a number, not a string:

/travel-demo-content-tags/templates/components/tourDetail-content-tags.ftl
...
  <div class="property-value">${i18n.get('tour.duration', [tour.duration?number!])}</div>
...

After this modification, the length of the example 7-day tour is finally displayed using just a single word, Week:

Duration of the 7-day Kyoto tour rendered as Week

If the editor changed the tour duration parameter to, for instance, 21 days, the page would display Three weeks instead, and so on:

Duration of the 21-day Kyoto tour rendered as Three weeks

Feedback