My name is Thorsten Ortlepp. I am a Software Developer and currently focused on Java development. If you want to know more about me, read my blog or click on one of the items below:

New in my blog: Multilingual websites with JBake

As I wrote in the last post, I created my website and blog with Jbake. Both, the website itself and the blog are available in English and German. In this post I am going to write about how this works and how I created the website.

The prerequisite for the whole website is the Apache web server with mod_negotiation which enables content negotiation. In short, content negotiation gives you the possibility to serve different content on the same URI, the content is delivered depending on the client’s capabilities or configuration.

It’s easy to turn on content negotiation, just place the following lines in a .htaccess file:

<IfModule mod_negotiation.c>
  AddLanguage en .en
  AddLanguage de .de
  LanguagePriority en de
  DefaultLanguage en
  DirectoryIndex index index.html

These lines are quite self explaining: Files that are ending with .en are containing English content, files that are ending with .de are containing German content. English has a higher priority than German and English is used as default language – e.g. if the visitor configured French as his preferred language.

In the next step you have to convince JBake to create files with the ending .en for English content and files with the ending .de for German content. Unfortunately, that is not possible out of the box, but there is a trick you can use: Create two separate blogs, one for each language. Then Gradle can be used to "bake" both blogs separately and then to merge everything together in one blog.

For my blog, I use this folder and file hierarchy:

 - assets
    - favicon.ico
    - ...
 - templates
    - page.ftl
    - ...
 - websiteDE
    - content
       - index.adoc
       - ...
    - jbake.properties
 - websiteEN
    - assets
       - .jbakeignore
    - content
       - index.adoc
       - ...
    - jbake.properties
 - build.gradle
 - buildDE.gradle
 - buildEN.gradle

There are some characteristics: For example, both blogs are using the same templates. Where it is necessary, the output is adjusted according to the language, e.g. for date formats. Besides static resources ("assets") are existing and processed just once, for the second blog there is just a kind of "fake" asserts folder without any content. For details you can see my example project at the end of this post.

Now, there is one last detail missing: It should be possible to change the language manually. I am using a simple cookie to store the selected language. If the Apache web server is configured properly via the .htaccess file, an existing cookie overrides the preferred languages the user configured in his browser:

SetEnvIf Cookie "language=(.+)" prefer-language=$1
Header append Vary cookie

To enable the user to change the language, JavaScript can be used:

function setLanguageEnglish() {
 document.cookie = "language=en;path=/";

A cookie with the preferred language is stored and the current website is reloaded - in the language the user selected.

And finally, here is an example project that is quite similar to my original website and blog: jbake-example.zip . You can build the site by running gradle in the root directory of the project.

Read more: My Blog