Implementing multi-language prototypes in Bedrock

Posted on 17 June 2021 at 11:34 by Wolfr_

For a recent prototype, the requirement was that we would work in multiple languages. In the case of this project Dutch and English.

Now that things are still fresh, I’m doing this writeup so that I know what to do next time. And maybe this will help some people? Blogging is how I remember 😉

So first of all you will want to make two folders in content/templates with the shortcodes for your languages. So in this case a nl and and en folder.

Choose one of your languages to be the main language. Now, create files that match the URL structure on both sides. So let’s say you have an about.pug in en you will have an over-ons.pug in the nl part.

Here’s how that would look in a tree structure:

.
|-- en
|   `-- about.pug
`-- nl
    `-- over-ons.pug

Now use template extension to extend the template in the non-main language*. So let’s say that nl is the main language we are developing in. Then, don’t repeat the full template in the en version.

Instead use extends /templates/nl/over-ons in en/about.pug ; and literally only that. The file is needed to create the URL. The extension makes sure the content is exactly the same.

Then, in the “Over ons” template you can then localize content. To make sure you can localize content at all you will need translation strings. Make a new file in data called content-strings.js. In this file, create a structure as follows:

'use strict';

let contentStrings = [
  {
    "readMore": "Lees meer",
    "chooseLanguage": "Kies taal"
  },
  {
    "readMore": "Read more",
    "chooseLanguage": "Choose language"
  },
];

module.exports = contentStrings;

Now you can call this structure in your template:

#{contentData.contentStrings[0].readMore}

This syntax is no fun; and also, we are not showing the right language in the en part of the site.

Let’s provide a helper function to be able to correctly show the right string in the right language in master.pug . Add this code to the pageVariables block:

- var activeLangIndex = null
- var lang = pathname.split("/")[0];
-
    if (lang == "nl") { activeLangIndex = 0 }
    if (lang == "en") { activeLangIndex = 1 }
- var t = contentData.contentStrings[activeLangIndex]

What are we doing here? We are associating the active language with the first part of the URL, and pointing to a lil variable called t (for translation, get it?) to be a helper.

Now we can simply write:

#{t.readMore}

And lo an behold, on the nl part it will show up as Lees meer and on the en part it will show up as Read more.

So this is the basic gist of how you would implement multiple languages using the powerful Pug templating language together with Bedrock’s content data feature.


*I realize this can get tedious. Bedrock is meant as a prototyping environment and not to create production sites. In our project, we translate a few parts of the prototype to a different language, but in production a CMS or a JS framework with a more full-fledged i8n solution is swapped in. However, some recent changes to Bedrock made me wonder if we shouldn’t just go ahead and try to make Bedrock output ready for production. We are close to having all the features you need for simple websites.

Perhaps if you really want to go to production you can script the generation of the en structure using a helper script. But for small sites it is probably faster to just do the manual work.

Leave a Reply

Your email address will not be published. Required fields are marked *