Page tree
Skip to end of metadata
Go to start of metadata

This page describes selected best practices within the context of i18n API.

Use message bundles

Provide a message bundle in your module. It makes translation easier. A translator can work with a plain text file and doesn't need to touch the code. A message bundle is a collection of .properties files. Each file contains key-value pairs of translated user interface text such as labels and messages. The keys in all .properties files of the same bundle are identical but the values are language specific translations.

Recommended filename structure

We recommend the following i18n filename patterns, for apps and modules, respectively:

app-<app-name>-messages_<locale>.properties
module-<module-name>-messages_<locale>.properties

Best practice

Create separate message bundles for user interface labels and template labels. Don't store these two groups of text in the same properties files or message bundles. They are aimed at different audiences and have different localization requirements.

Example: Message files in the Travel Demo

Use Java locale notation for <locale>

Make sure the locale is correct. Magnolia follows the Java locale notation.

Bundle *.properties into ./<module-name>/i18n/

Keep your message bundles in the following folders:

  • src/main/resources/<module-name>/i18n/ (Maven module development) or in
  • <magnolia.resources.dir>/<module-name>/i18n/ (light development).

Use generic i18n keys

Whenever possible (see here for more details and restrictions), use generic, i.e. shorter i18n keys. The shorter the form, the more modules will exist where the key can be instantly reused.

Use UTF-8 encoding

Use UTF-8 character encoding in .properties files.

Keep a separate file for template messages

Create separate message files for user interface labels and template labels. Don't store these two groups of text in the same properties files. They are aimed at different audiences and have different localization requirements.

For instance the magnolia-travel-demo module has two separate resource bundles for the front-end (template messages) and the back-end:

module-travel-demo-frontend_en.properties
# Navigation
navigation.telephone=1-800-123-4567
navigation.toggle=Toggle navigation
navigation.aboutDemo=About this demo

navigation.destination.title=Destinations
navigation.tourTypes.title=Tours

navigation.login=Log in
navigation.logout=Log out
navigation.registration=Register

# Search
search.placeholder=Search
search.pagesFoundFor=pages found for
search.toursFoundFor=tours found for
search.editMode=Search results will be displayed here.

# For editors
note.for.editors=Note for Editors:
note.for.editors.carousel=Carousel: Preview page to see carousel enabled.

#Image
image.alt.prefix=Image
image.alt.unavailable=no alternative text available

#Generic
# Text Image component
fields.constrainAspectRatio.label=Constrain aspect ratio
fields.constrainAspectRatio.buttonLabel=Crop image to match the theme of the site.
module-travel-demo-backend_en.properties
# Override the group name of STK
app-launcher.stk.label=MTE

# Social
travel-demo.templates.components.social=Social sharing
travel-demo.dialogs.components.social.label=Social sharing
travel-demo.dialogs.components.social.description=Shares a page across several social networks.
travel-demo.components.social.label=Social sharing
travel-demo.components.social.size.label=Icon size1
travel-demo.components.social.tabMain.size.options.16=16px
travel-demo.components.social.tabMain.size.options.24=24px
travel-demo.components.social.tabMain.size.options.32=32px
travel-demo.components.social.tabMain.size.options.48=48px
travel-demo.components.social.tabMain.floating.label=Floating
travel-demo.components.social.tabMain.floating.options.true=Yes
travel-demo.components.social.tabMain.floating.options.false=No
travel-demo.components.social.tabMain.vertical.label=Vertical
travel-demo.components.social.tabMain.vertical.options.true=Yes
travel-demo.components.social.tabMain.vertical.options.false=No
travel-demo.components.social.tabMain.rounded.label=Rounded icons
travel-demo.components.social.tabMain.rounded.options.true=Yes
travel-demo.components.social.tabMain.rounded.options.false=No
travel-demo.components.social.tabMain.services.label=Services

# Column layout
travel-demo.templates.components.columnLayout=Column Layout
travel-demo.components.columnLayout.label=Column Layout
travel-demo.components.columnLayout.description=Add a column layout to a page.
travel-demo.components.columnLayout.form.tabs.tabMain.label=Column Layout
travel-demo.components.columnLayout.tabMain.layout.label=Layout
travel-demo.components.columnLayout.tabMain.layout.description=Select the number of columns. The ratios indicate the width of the columns relative to one another.
travel-demo.components.columnLayout.tabMain.layout.options.6x6=2 cols (1:1)
travel-demo.components.columnLayout.tabMain.layout.options.8x4=2 cols (2:1)
travel-demo.components.columnLayout.tabMain.layout.options.4x8=2 cols (1:2)
travel-demo.components.columnLayout.tabMain.layout.options.9x3=2 cols (3:1)
travel-demo.components.columnLayout.tabMain.layout.options.3x9=2 cols (1:3)
travel-demo.components.columnLayout.tabMain.layout.options.4x4x4=3 cols (1:1:1)
travel-demo.components.columnLayout.tabMain.layout.options.6x3x3=3 cols (2:1:1)
travel-demo.components.columnLayout.tabMain.layout.options.3x6x3=3 cols (1:2:1)
travel-demo.components.columnLayout.tabMain.layout.options.3x3x6=3 cols (1:1:2)
travel-demo.components.columnLayout.tabMain.layout.options.3x3x3x3=4 cols (1:1:1:1)

# SearchResult
templates.components.searchResults=Search Results
travel-demo.components.searchResults.tabMain.label=Search Results
travel-demo.components.searchResults.tabMain.headline.label=Headline
travel-demo.components.searchResults.tabMain.headline.description=Enter the headline to be shown above the search results

# Carousel
travel-demo.templates.components.carousel=Carousel
travel-demo.components.carousel.label=Carousel
travel-demo.components.carousel.tabMain.id.label=Id
travel-demo.components.carousel.tabMain.id.description=Identifier of carousel. Must be unique per page.
travel-demo.components.carousel.tabMain.dots.label=Show dots
travel-demo.components.carousel.tabMain.dots.buttonLabel=
travel-demo.components.carousel.tabMain.arrows.label=Show arrows
travel-demo.components.carousel.tabMain.arrows.buttonLabel=
travel-demo.components.carousel.tabMain.fade.label=Fade transition
travel-demo.components.carousel.tabMain.fade.buttonLabel=
travel-demo.components.carousel.tabMain.variableWidth.label=Variable slide width
travel-demo.components.carousel.tabMain.variableWidth.buttonLabel=
travel-demo.components.carousel.tabMain.slidesToShow.label=Slides to show
travel-demo.components.carousel.tabMain.slidesToShow.buttonLabel=
travel-demo.components.carousel.tabMain.autoplay.label=Autoplay
travel-demo.components.carousel.tabMain.autoplay.buttonLabel=
travel-demo.components.carousel.tabMain.autoplaySeconds.label=Autoplay seconds
travel-demo.components.carousel.tabAdvanced.label=Advanced
travel-demo.components.carousel.tabAdvanced.slickConfig.label=Override slick config

# Jumbotron
travel-demo.templates.components.jumbotron=Jumbotron - Header for a page

# Home
travel-demo.templates.pages.home=Travel Home
travel-demo.pages.pageProperties.tabSearch.label=Search
travel-demo.pages.pageProperties.tabSearch.searchResultPage.label=Search result page

# Standart
travel-demo.templates.pages.standard=Travel Standard

# SearchResult
travel-demo.templates.pages.searchResultPage=Travel Search Result Page

# AboutDemo
travel-demo.templates.pages.aboutDemo=Travel About Demo Page

# Footer
travel-demo.templates.areas.footer.label=Footer