Language switch in Kirby CMS

Published by on

I try to offer as much of the content on my website as possible in multiple languages. The translation and internationalisation interfaces of my content management system Kirby help me to do this. They make it easy to create multilingual content.

Recently, however, I encountered a small problem that took more time to solve than I had expected.

It is about the integration of the language switcher, which is located at the bottom of each page and contains a link to the current page in another language version:

Diese Seite gibts auch auf Deutsch.

To do this, I first added a new entry in the corresponding translation file under site/language/$lang_code.php for the languages I want to support (in my case German and English):

<?php

return [
    'code' => 'de',
    'default' => true,
    'direction' => 'ltr',
    'locale' => 'de_DE.utf-8',
    'name' => 'Deutsch',
    'translations' => [
        'footer_translated' => 'Diese Seite gibts auch auf <a href="{language_url}">{language_name}</a>',
    ]
];
<?php
return [
    'code' => 'en',
    'default' => false,
    'direction' => 'ltr',
    'locale' => 'en_US.utf-8',
    'name' => 'English',
    'translations' => [
        'footer_translated' => 'This page is also available in <a href="{language_url}">{language_name}</a>.',
    ]
];

Next, I created the following snippet in the file site/snippets/language_switch.php:

<?php

use Kirby\Toolkit\I18n;

$current_language = $kirby->language();

foreach ($kirby->languages() as $language) {
    if ($language !== $current_language) {
        $url_for_target_language = $page->url($language->code());

        if (!empty($_GET)) {
            $query_string = http_build_query($_GET);

            if (strlen($query_string) > 0) {
                $url_for_target_language = $url_for_target_language . '?' . $query_string;
            }
        }

?>
        <p lang="<?= $language->code() ?>">
            <?= I18n::template(
                'footer_translated',
                null,
                [
                    'language_url' => $url_for_target_language,
                    'language_name' => $language->name()
                ],
                $language->code()
            ) ?>
        </p>
<?php
    }
}
?>

In this code there are some interesting Kirby functions are linked together:

  • First, all languages that are available in Kirby are run through in a loop, skipping the language that the page is currently viewed in.
  • Next, the URL of the current page is searched for in another language. We get this by calling the auxiliary function $page->url() with a parameter and passing it the target language: $page->url($language->code()).
  • If necessary, all $_GET request parameters are also passed through to the new URL.
  • We use the lang attribute to tell the browser that the text is written in a different language from the rest of the document. The helper function $language->code() helps us with this,
  • Finally, we use the function I18n::template() to output the translated text in the target language. In addition, we also replace {language_name} with the name of the language and {language_name} with the URL of the language version. The function t(), which I usually use to translate template strings, unfortunately does not allow us to make substitutions.

The snippet is then used in all my templates via snippet('language_switch');.

Leave a comment

Available formatting commands

Use Markdown commands or their HTML equivalents to add simple formatting to your comment:

Text markup
*italic*, **bold**, ~~strikethrough~~, `code` and <mark>marked text</mark>.
Lists
- Unordered item 1
- Unordered list item 2
1. Ordered list item 1
2. Ordered list item 2
Quotations
> Quoted text
Code blocks
```
// A simple code block
```
```php
// Some PHP code
phpinfo();
```
Links
[Link text](https://example.com)
Full URLs are automatically converted into links.

Replied on your own website? Send a Webmention!