Build a Ready-To-Use Jekyll Setup — Part 2: Bilingual Website
--
Intro
This article is the second part of a series on how to build a Jekyll setup that can be used to develop multi-page websites with static contents in two languages and which are served by an Apache HTTP Server. In the first part of this guide we prepared a basic Jekyll setup with two pages, CSS/Sass and JavaScript.
In This Part
We are going to make our website bilingual without additional plugins. What we want is to have an element in the navigation bar which allows us to toggle the language. Our implementation will meet the following features:
- When pushing the toggle element, the browser will request the current page in the alternative language
- The value of the lang attribute in the
html
element will always adjust to the language code of the current page - The path of the URL must match the language of the current page, e.g. the German path of
/legal.html
must be/impressum.html
Prerequisites
It is recommended that you follow Part 1 of this guide before proceeding. Alternatively you can download the resulting source code from Part 1 on GitHub, as we will use it as a starting point here.
Current State
After completing Part 1 of this guide, the current folder structure looks as follows:
/
_includes/
footer.html
head.html
header.html
nav.html
scripts.html
_layouts/
default.html
_sass/
base.scss
css/
main.scss
js/
main.js
_config.yml
Gemfile
Gemfile.lock
index.html
legal.html
Collections
We start this part by adding the following lines to the existing _config.yml
:
The url
will be used in the <base>
element in the documents head section to serve as the base for all relative paths. The baseurl
can be adjusted in case you serve your website from a subdirectory.
In order to make our website bilingual, we need to make use of Jekyll collections. A collection will host the pages belonging to one language. We are taking ISO 639–1 language codes for the collection names. In our case en
for English and de
for German. We also need to set output
true, otherwise the pages of the collections won’t be build.
Next, we delete the index.html
and legal.html
files and create the folders (collections) _en
and _de
in the project root directory. They must have the same names as specified in the _config.yml
plus a leading underscore.
We now can create the pages corresponding to the respective language, either as HTML or Markdown files.
In the _de/
directory, create the following files with the respective content.
index.html
:
The content ist similar to the index.html
files from Part 1 of this guide, except that we add two more attributes in the Front Matter, name
and lang
. lang
is used to determine the language of the current file. Its value must equal the name of the collection as defined in the _config.yml
configuration file (de), otherwise the method used in this guide won’t work.
name
is the cross-language file name, which will be used to determine the current file in the alternative language when when pushing the toggle element. Therefore, the index.html
files in both collections need to have home as the value of the name
attribute. You can use different names but they have to be the same in German and the English file.
impressum.html
:
impressum.html
follows the same structure as index.html
except the different name
.
Next, we need to create the related pages in English. Therefore, create the following files in the _en/
directory.
index.html
:
In contrast to the index.html
of the German collection, we need to set en as the value of the lang
attribute.
legal.html
:
legal.html
is the English counterpart to impressum.html
. Since we want the URL to meet the language of the current page, we choose a different file name for the English version. However, it is important that the values of the name
attribute are the same for legal.html
and impressum.html
, otherwise we won`t be able identify the correct HTML file when toggling the language.
Toggle Element
We now have to implement the toggle element in the navigation bar which requests the current file in a different language. Since the requested URL will be different, depending on the current page, it must be generated dynamically. We therefore need to figure out two things in advance: First, we need to determine the language of the current page, in order to address the collection of the alternative language. Second, we need to determine the name of the current file to select its corresponding counterpart.
Therefore, we modify nav.html
as follows:
The first task is accomplished by checking whether the language of the current page is English (line 5). Since we only have one alternative language, I decided for a hard-coded solution. Either in line 6 or 8 we then access the collection for the alternative language by calling the site
variable with the desired collection name. The correct file is then determined by comparing the page.name
variable of the current file against the names of the files in the selected collection — that is why the value of the name
variable needs to be the same in both versions of a file, the German and the English. The correct page is then assigned to the translated
variable.
Since where
returns an array, we need to loop over translated
(line 11 to 13). The url, relative to the root directory, can be retrieved by the page’s url variable, item.url
, which is then used to build the reference of the toggle element, depending on the language of the current page. As the label we simply take the value of the page’s lang
variable.
Language of the Document
As a last step in this part we need to set the correct language code in the <html>
element within the layout file. This is done by linking the value of the lang
attribute of the <html>
element to the value of the page’s lang
variable. Therefore, we modify line 2 of the layout default.html
as follows:
Result
We now have the following folder structure:
/
_de/
impressum.html
index.html
_en/
index.html
legal.html
_includes/
footer.html
head.html
header.html
nav.html
scripts.html
_layouts/
default.html
_sass/
base.scss
css/
main.scss
js/
main.js
_config.yml
Gemfile
Gemfile.lock
Running bundle exec jekyll serve
in your terminal now builds and serves the website under http://127.0.0.1:4000.
The toggle element now requests the same page in the alternative language, the URL also adapts to the selected language and the correct language code is set in the html
element.
Source Code
GitHub: Jekyll Setup - Part 2
In the Next Part
At this point, the remaining navigation items are not working properly, since they are not yet dynamically generated. In part three of this guide, we therefore implement a dynamic navigation bar.