How to make a site multilingual?

Asked

Viewed 3,508 times

11

I have a site made in PHP, now I came up with the obligation to make the site multilingual. I need to translate titles, menus and error messages. User added texts do not need to be translated.

I’ve seen a lot of different approaches like:

Definition of constants:

It consists of defining constants in different PHP files, for example pt_PT.php and then making the inclusion include 'pt_PT.php'; translations before page loading.

Example: define( 'USER' , 'UTILIZADOR' );

Definition of arrays:

Consists of defining arrays also with inclusion include 'pt_PT.php';.

Example: $lang['USER'] = 'UTILIZADOR';

Example in this answer.

Gettext:

After seeing this issue discovered that it may be by function gettext.

For those who need here a mini tutorial to use the gettext and the poedit

Database:

There is also the possibility to store translations in a table of translations.

+-------+------------+--------+-----
|sigla  | pt_PT      | en     | ...
+-------+------------+--------+-----
| usr   | utilizador | user   | ...
+-------+------------+--------+-----

Different pages for each language:

I have also seen, have replicated pages for different languages:

www.myhost.pt/en/index.php
www.myhost.pt/pt_PT/index.php


In my case I don’t need to have content translation, which is the best option?

Advantages/Disadvantages?

Is there a better option? Which one?

PS: The most consensual solution I’ve seen is through gettext.

  • possible duplicate of How to translate a website into PHP?

  • 2

    It is not duplicate, I refer to that question. My question is quite different. At least they bothered to read the questions?

  • In the link to possible dusplicata, has an excellent response from @Arivanbasos

  • @Brunoaugusto I edited the question and added the example of the answer you identified.

  • Now the duplicate signaling no longer makes sense. I removed it, but now it could be classified as "based on opinions" because to know the best way, it would require points of view from those who have already used all the alternatives and obtained a certain benchmark. But apparently I can’t vote again.

  • @Brunoaugust in this answer you have some disadvantages of methods in array and constants. It has nothing to do with opinions. It’s a question of advantages and disadvantages and I don’t translate content.

Show 1 more comment

3 answers

9

The solution I use:

I created a file with a translation array for each language, and I set the language on the page.

Languages.php

<?php
/*
#
# Translations system
# (C)2014 - MyEnterprise
#
*/

// Criar a array de todas as linguas
$translationsArray = array();

// Criar a array para cada lingua
$translationsArray["pt_BR"] = array();
$translationsArray["en_US"] = array();

# PT-BR            $lang     $string
$translationsArray["pt_BR"]["HelloWorld"] = "Olá mundo!";
$translationsArray["pt_BR"]["Title"]      = "Título";
$translationsArray["pt_BR"]["Welcome"]    = "Seja bem-vindo a %s";

# EN-US            $lang     $string
$translationsArray["en_US"]["HelloWorld"] = "hello World!";
$translationsArray["en_US"]["Title"]      = "Title";
$translationsArray["en_US"]["Welcome"]    = "Welcome to %s";

index php.

    <?php
// função para pegar string do arquivo languages.php
function getLanguageString($string, $lang="pt_BR", $parameters=null) {
    /*
    / levando em conta como exemplo: 
    / $translationsArray["pt_BR"]["Welcome"]    = "Seja bem-vindo a %s";
    /
    / $string = "ID" da string, seria o "Welcome"
    / $lang = A lingua para pegar a string, no caso pt_BR ou en_US
    / $parameters = uma array de valores para substituir os %s se tiver algum(s)
    */

// incluir o arquivo languages.php ou abortar o script
if (!require("languages.php")) {
    die("ERRO ao carregar arquivo de linguas");
}

    $actualTranslatedString = $translationsArray[$lang][$string];

    if (!empty($parameters)) {
        return vsprintf($actualTranslatedString, $parameters);
    }
    else {
        return $actualTranslatedString;
    }
}

// Exemplo:
$siteLang = "pt_BR";
$siteName = "GitHub";
$parameters = array(
    0 => $siteName
);

$bemVindo = getLanguageString("Welcome", $siteLang, $parameters); 
echo $bemVindo;

Here it worked. the

  • 2

    pq o -1? I just made a suggestion..

  • Weird -1, yeah, yeah... The code is well commented and usually a low-quality response is simply a copy/code piece with no explanation. Maybe this comment explain something... note that the comment has two votes, the -1 may have come from anyone...

  • The -1 must have been by showing the implementation by array, but that’s not what I ask, I ask which is the best alternative. Advantages and disadvantages of both. Anyway it is very good your suggestion. + 1

7

The forms cited are valid and functional, but I see a problem in using constant and arrays to this end, you may forget to set any of these for a particular language and will have problems.

A suggestion would be to use an interface and classes with methods that return text, example:

interface Language {
    public function getLabelNome();
}

class ptBR implements Language {

    public function getLabelNome(){
       return "Nome";
   }

}

class enUS implements Language {
    public function getLabelNome() {
        return "Name";
    }
}

class esES implements Language{
    public function getLabelNome() {
        return "Nombre";
    }

}

When the user chooses the language, you instantiate the class of that language, in this way with the help of the interface, you ensure that you will have all the translations available.

Another advantage using methods is that you can treat the return form of text, example

public function getLabelNome($uper = false){
    return $uper ? "NOME" : "Nome";
}

$lang = new ptBR();
echo $lang->getLabelNome(true); // retorna em maiúsculo

Edited

As mentioned by @Kazzkiq in the comments below, another advantage would be not allowing the user to change the value of words outside the file where they are created.

  • 3

    In my opinion, this is the most organised and standardized solution available. In addition to having the advantage of not allowing the user to change the value of the words outside the file where they are created. (In the case of array, I could easily edit the value of a word and screw up any code that used it down there)

  • Well placed @Kazzkiq, another advantage :)

  • Good solution, the translator is limited to one class, without changing the other.

  • One more alternative, and why not to use arrays nor constant. Thank you.

4

Well the solution I adopted, after much study and conversation here at the office, was gettext with poedit.

Here’s a tutorial where I guided myself: PHP and Javascript Internationalization using Gettext and Poedit

Is simple and effective,

1 - Install poedit and gettext as in the above tutorial* ;

2 - Replace our messages/namesName in PHP code with _("mensagem");

3 - Open the poEditor editor* and update, load messages to translate as id’s;

4 - Just translate, save the file .po in the right place and this floor.

*I know it’s in English, but I’m not going to translate, because that’s not the idea of the answer.

To translate my BD user types I created a class that prints the result from BD to a file translate.php and from there I can do the translation with the poedit, example:

public function createArrayTipo()
{
    $filePHP   = fopen("translate.php", "a");
    $inicial = true;

    if (!is_resource($filePHP))
        return false;

    $sql_activity     = "SELECT id, name FROM user_type";
    $result_activity  = mysqli_query( $this->mysqli , $sql_activity  );

    fwrite($filePHP, "\n  \$tipos_user = array(");
    while($row = mysqli_fetch_array($result_activity))
        {
        if(!$inicial)
        fwrite($filePHP, ",");

        fwrite($filePHP, "'".$row['id']."' => _('".$row['name']."')" );

        $inicial = false;
    }
    fwrite($filePHP, "); \n");
    fclose($filePHP);
}

My question remains unanswered, but here is one more option.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.