loading...
Cover image for Implementing a Multi-language Manager in a Web App

Implementing a Multi-language Manager in a Web App

demonicious_ profile image Demonicious ・4 min read

The world is huge, and more than 7 billion people live on it. Not all of them speak the same language. Therefore, to truly internationalize an application, you're bound to add Multiple languages at some point.

Multi-language support is often an overlooked aspect of successful websites. It's a feature that you should always look out for when starting a new project.

In this article, I'll show you how to add Multi-lingual support to a website in PHP, using concepts that will easily translate to other Frameworks, Languages, etc.

1. Why PHP ?

I chose PHP because It's by far the most commonly used web language, and It's nowhere close to being dead.

This article is not PHP only, the concepts you see here will translate to other languages like Node.js, Python, and even front-end frameworks like React, Svelte or Vue.

2. Furthermore

This article mainly shows how to build a "Language Management" system, adding different languages is up to you.

3. Let's Start!

For now we only have a simple index.php file with some inline CSS & Static Text content.

Static Page

The goal is to make the word "Hello" and the line below to be Multi-lingual.

To start, we probably need a config file that determines Default Language & List of Available languages.

I will create this file as language/config.php.

<?php

// language/config.php

/* If you're not familiar with PHP Associative arrays, 
   they behave exactly like JSON or JavaScript objects. */

$language_config = [
    'default' => 'english',

    'list'    => [

        'english',
        'spanish',

    ]    
];

After creating the config file, I would like to create a "Language" class that is responsible for:

  • Getting the selected language.
  • Selecting any available language.
  • Getting the variables from the currently selected language.

I will create this file as class.php next to my config.php.

├── language
│   ├── config.php
│   └── class.php
└── index.php

I will define a simple constructor that sets the default & list properties. We'll deal with the language property later. We also set a lang_vars property as an empty array. This is required for later.

<?php

// language/class.php

class Language {
    private $language;
    private $default;
    private $list;
    private $lang_vars

    public function __construct($language_config) {
        $this->default = $language_config['default'];
        $this->list    = $language_config['list'];
        $this->lang_vars = array();
    }
}

It's time to create methods that are responsible for:

  • Getting selected language.
  • Setting a language if it exists in the list.

I won't be storing the "language" in a database, because I think it's entirely unnecessary. Cookies will be more than enough for the job.

SetLanguage Method:

The SetLanguage method will check if the language exists in the config list, and set a "selected_language" cookie if true.

public function SetLanguage($language) {
   $language = strtolower($language);

   $exists = in_array($language, $this->list);

   if($exists) {
        $this->language = $language;
        return setcookie(
            'selected_language',   // Name of the Cookie
            $language,             // Value of the Cookie
            strtotime('+10 year'), // will expire 10 years later.
            '/'                    // Cookie Path
        );
    }

    return false;
}

GetLanguageMethod:

The GetLanguage method sets the language property of the class by reading cookie value and also returns it. If a cookie is not found, It calls the SetLanguage cookie for the default language.

public function GetLanguage() {
    $language = $this->default;

    if(isset($_COOKIE['selected_language'])) 
        $language = $_COOKIE['selected_language'];
    else
        $this->SetLanguage($this->default);

    $this->language = $language;

    return $language; 
}

We'll call this method inside the class constructor to set the language on load.

public function __construct() {
    $this->default = $language_config['default'];
    $this->list    = $language_config['list'];
    $this->lang_vars = array();

    $this->GetLanguage();
}

Now we have a Class that let's you Select languages and store them in cookies, and also correctly reads the selected languages from cookies.

All that's left to do is create some way of Getting Language Variables based on current language. Language Variables are just arrays that have different items based on different languages.

For this, I will create a directory vars under language. This vars directory will includes directories containing Language Variable files for each language. For example:

├── language
│   ├── vars
│   │   ├── english
│   │   │   └── greetings.php
│   │   └── spanish
│   │       └── greetings.php
│   ├── config.php
│   └── class.php
└── index.php

Our greetings.php file for english would look like this:

<?php

$lang['hello_word']           = 'Hello';
$lang['how_are_you_sentence'] = 'How are you doing on this fine day?';

The same file for spanish would look like this:

<?php

$lang['hello_word']           = 'Hola';
$lang['how_are_you_sentence'] = '¿Cómo te va en este buen día?';

Now we just need to create 2 more methods that are responsible for:

  • Loading Language Variable files.
  • Returning value of a Language Variable.

LoadVariables Method:

The LoadVariables method will require_once a language file based on the currently selected language.

I created a lang_vars property in the class that holds all the loaded variables (Empty Array by Default) - Here is my simple implementation of this method:

public function LoadVariables($name) {
    require_once(__DIR__ . DIRECTORY_SEPARATOR . 'vars/' . $this->language . '/' . $name . '.php');
    $this->lang_vars = array_merge($this->lang_vars, $lang);
}

Var Method:

The Var method will simply return the value of a Language Variable that has previously been loaded using LoadVariables.

public function Var($name) {
    return 
    isset($this->lang_vars[$name]) ? 
    $this->lang_vars[$name] :  null;
}

The Language Manager is now complete, All that's left to do is to Create an Interface file that you can load into index.php and use our Language Manager.

I will create this file as manager.php inside language.

<?php

require_once "config.php";
require_once "class.php";

$Language = new Language($language_config);

This file can now be included inside index.php to make the Static text multi-lingual:

<?php
    require_once "language/manager.php";

    $Language->LoadVariables('greetings');
?>

/* Boring Markup */

<span class="title">
    <?php echo $Language->Var('hello_word') ?> Dev.to
</span>
<p>
    <?php echo $Language->Var('how_are_you_sentence') ?>
</p>

Spanish Language

However you wanna make the user select languages is up to you, Maybe use a Query String (GET Variable) or a Dynamic Route.

Final Product ( Class + Example ) on GitHub

This was mainly a conceptual article, rather than a Language Specific one. Without much effort, these concepts can translate to other Languages / Frameworks.

I hope you learnt something new, and have a nice day :)

Discussion

markdown guide