Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow keyboard search to be localized 📡 #500

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,21 @@ COPY resources/keyman-site.conf /etc/apache2/conf-available/
RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
RUN chown -R www-data:www-data /var/www/html/

# Because the base Docker image doesn't include locales, install these to generate locale files.
# gettext needed to compile .po files to .mo with msgfmt
RUN apt-get update && apt-get install -y \
locales \
gettext

# Install PHP-extension gettext for localization at runtime
RUN docker-php-ext-install gettext
RUN docker-php-ext-enable gettext

# Only enable en_US locale in /etc/locale.gen
# PHP will use textdomain() to specify "localization" .mo files
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \
&& dpkg-reconfigure --frontend=noninteractive locales \
&& update-locale

COPY --from=composer-builder /composer/vendor /var/www/vendor
RUN a2enmod rewrite headers; a2enconf keyman-site
42 changes: 42 additions & 0 deletions _includes/locale/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
### Setup for Localization

[init-container.sh](../../resources/init-container.sh) contains steps for the Docker container to compile .po files to .mo files which PHP uses for `gettext()`.

If you want to compile the files on your host machine, install `gettext`.

```bash
sudo apt-get install gettext
```

### Adding locales

The Docker image has the "en_US.UTF-8" locale enabled in `/etc/locale.gen`
We'll use `textdomain` to specify filenames for "switching" localization.
The filenames will include the `%locale%` as defined in the [crowdin.com project](https://crowdin.com/project/keymancom).
In the example below, the English file `keyboards-en.po` is copied to `keyboards-fr-FR.po` for French.

1. In `/_includes/locale/en/LC_MESSAGES/`
* Copy `keyboards-en.po` file and rename to the `keyboards-fr-FR.po`.
* Translate/upload the new .po file to crowdin
* Convert .po file to .mo with the following

```bash
msgfmt keyboards-fr-FR.po --output-file=keyboards-fr-FR.mo
```

(The container handles the msgfmt step in init-container.sh)

2. Add the file to the PHP (path is relative the PHP file)

```php
bindtextdomain("keyboards-fr-FR", "../_includes/locale");
```

3. To use French,
```php
textdomain('keyboards-fr-FR');
```

----

For formatted string, use the PHP wrapper [`_s(msgstr, $args)`](./locale.php).
2 changes: 2 additions & 0 deletions _includes/locale/en/LC_MESSAGES/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore generated files from msgfmt
*.mo
85 changes: 85 additions & 0 deletions _includes/locale/en/LC_MESSAGES/keyboards-en.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"

# Default English strings for keyboards/index.php

# Page Title
msgid "Keyboard Search"
msgstr "Keyboard Search"

# Page Description
msgid "Keyman Keyboard Search"
msgstr "Keyman Keyboard Search"

# Keyboard search bar
msgid "Keyboard search%s"
msgstr "Keyboard search%s"

# Search bar placeholder
msgid "Enter language or keyboard"
msgstr "Enter language or keyboard"

# Search Button Value
msgid "Search"
msgstr "Search"

# Link to start a new keyboard search
msgid "New search"
msgstr "New search"

# Search box prompt
msgid "Enter the name of a keyboard or language to search for%s"
msgstr "Enter the name of a keyboard or language to search for%s"

# Search box link for popular keyboards
msgid "Popular keyboards"
msgstr "Popular keyboards"

# Search box link for all Keyman keyboards
msgid "All keyboards"
msgstr "All keyboards"

# Search box hint: List header
msgid "Hints"
msgstr "Hints"

# Search box hint: Description
msgid "The search always returns a list of keyboards. It searches for keyboard names and details, language names, country names and script names."
msgstr "The search always returns a list of keyboards. It searches for keyboard names and details, language names, country names and script names."

# Search box hint: available prefixes to use in the search
msgid "You can apply prefixes"
msgstr "You can apply prefixes"

# (keyboards)
msgid "%skeyboards%s"
msgstr "%skeyboards%s"

# (languages)
msgid "%slanguages%s"
msgstr "%slanguages%s"

# (scripts, writing systems) or...
msgid "%sscripts, writing systems%s or"
msgstr "%sscripts, writing systems%s or"

# (countries) to filter your search results...
msgid "%scountries%s to filter your search results. For example"
msgstr "%scountries%s to filter your search results. For example"

# Search box hint: example of country search
msgid "searches for keyboards for languages used in Thailand."
msgstr "searches for keyboards for languages used in Thailand."

# Search box hint: BCP 47 prefix
msgid "Use prefix"
msgstr "Use prefix"

# Seach box hint: BCP 47 language example
msgid "to search for a BCP 47 language tag, for example"
msgstr "to search for a BCP 47 language tag, for example"

# Search box hint: BCP 47 language example
msgid "searches for Tigrigna %sEthiopia%s"
msgstr "searches for Tigrigna %sEthiopia%s"
94 changes: 94 additions & 0 deletions _includes/locale/en/LC_MESSAGES/keyboards-es-ES.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: keymancom\n"
"X-Crowdin-Project-ID: 740839\n"
"X-Crowdin-Language: es-ES\n"
"X-Crowdin-File: /master/keyboards/keyboards.po\n"
"X-Crowdin-File-ID: 2\n"
"Project-Id-Version: keymancom\n"
"Language-Team: Spanish\n"
"Language: es_ES\n"
"PO-Revision-Date: 2024-11-11 08:20\n"

# Page Title
msgid "Keyboard Search"
msgstr "Búsqueda por Teclado"

# Page Description
msgid "Keyman Keyboard Search"
msgstr "Keyman Búsqueda por Teclado"

# Keyboard search bar
msgid "Keyboard search%s"
msgstr "Búsqueda por teclado%s"

# Search bar placeholder
msgid "Enter language or keyboard"
msgstr "Ingresar idioma o teclado"

# Search Button Value
msgid "Search"
msgstr "Buscar"

# Link to start a new keyboard search
msgid "New search"
msgstr "Nueva buscar"

# Search box prompt
msgid "Enter the name of a keyboard or language to search for%s"
msgstr "Introduzca el nombre de un teclado o idioma para buscar%s"

# Search box link for popular keyboards
msgid "Popular keyboards"
msgstr "Teclados populares"

# Search box link for all Keyman keyboards
msgid "All keyboards"
msgstr "Todos los teclados"

# Search box hint: List header
msgid "Hints"
msgstr "Consejos"

# Search box hint: Description
msgid "The search always returns a list of keyboards. It searches for keyboard names and details, language names, country names and script names."
msgstr "La búsqueda siempre devuelve una lista de teclados. Busca nombres de teclados y detalles, nombres de idiomas, nombres de países y nombres de alfabetos."

# Search box hint: available prefixes to use in the search
msgid "You can apply prefixes"
msgstr "Puedes aplicar prefijos"

# (keyboards)
msgid "%skeyboards%s"
msgstr "%stescados%s"

# (languages)
msgid "%slanguages%s"
msgstr "%sidiomas%s"

# (scripts, writing systems) or...
msgid "%sscripts, writing systems%s or"
msgstr "%sguiones, sistemas de escritura%s o"

# (countries) to filter your search results...
msgid "%scountries%s to filter your search results. For example"
msgstr "%spaíses%s para filtrar los resultados de búsqueda. Por ejemplo"

# Search box hint: example of country search
msgid "searches for keyboards for languages used in Thailand."
msgstr "busca teclados para los idiomas utilizados en Tailandia."

# Search box hint: BCP 47 prefix
msgid "Use prefix"
msgstr "Utilice prefijo"

# Seach box hint: BCP 47 language example
msgid "to search for a BCP 47 language tag, for example"
msgstr "para buscar una etiqueta de idioma BCP 47, por ejemplo"

# Search box hint: BCP 47 language example
msgid "searches for Tigrigna %sEthiopia%s"
msgstr "busca Tigrigna %sEtiopía%s"

94 changes: 94 additions & 0 deletions _includes/locale/en/LC_MESSAGES/keyboards-fr-FR.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Crowdin-Project: keymancom\n"
"X-Crowdin-Project-ID: 740839\n"
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /master/keyboards/keyboards.po\n"
"X-Crowdin-File-ID: 2\n"
"Project-Id-Version: keymancom\n"
"Language-Team: French\n"
"Language: fr_FR\n"
"PO-Revision-Date: 2024-11-11 08:15\n"

# Page Title
msgid "Keyboard Search"
msgstr "Recherche au clavier"

# Page Description
msgid "Keyman Keyboard Search"
msgstr "Recherche de clavier Keyman"

# Keyboard search bar
msgid "Keyboard search%s"
msgstr "Recherche au clavier%s"

# Search bar placeholder
msgid "Enter language or keyboard"
msgstr "Entrez la langue ou le clavier"

# Search Button Value
msgid "Search"
msgstr "Recherche"

# Link to start a new keyboard search
msgid "New search"
msgstr "Nouvelle recherche"

# Search box prompt
msgid "Enter the name of a keyboard or language to search for%s"
msgstr "Saisissez le nom d'un clavier ou d'une langue à rechercher%s"

# Search box link for popular keyboards
msgid "Popular keyboards"
msgstr "Claviers populaires"

# Search box link for all Keyman keyboards
msgid "All keyboards"
msgstr "Tous les claviers"

# Search box hint: List header
msgid "Hints"
msgstr "Conseils"

# Search box hint: Description
msgid "The search always returns a list of keyboards. It searches for keyboard names and details, language names, country names and script names."
msgstr "La recherche renvoie toujours une liste de claviers. Elle recherche les noms et les détails des claviers, les noms de langues, les noms de pays et les noms d'écritures."

# Search box hint: available prefixes to use in the search
msgid "You can apply prefixes"
msgstr "Vous pouvez appliquer des préfixes"

# (keyboards)
msgid "%skeyboards%s"
msgstr "%sclaviers%s"

# (languages)
msgid "%slanguages%s"
msgstr "%slangues%s"

# (scripts, writing systems) or...
msgid "%sscripts, writing systems%s or"
msgstr "%sscripts, systèmes d'écriture%s ou"

# (countries) to filter your search results...
msgid "%scountries%s to filter your search results. For example"
msgstr "%spays%s pour filtrer vos résultats de recherche. Par exemple"

# Search box hint: example of country search
msgid "searches for keyboards for languages used in Thailand."
msgstr "recherche des claviers pour les langues utilisées en Thaïlande."

# Search box hint: BCP 47 prefix
msgid "Use prefix"
msgstr "Utiliser le préfixe"

# Seach box hint: BCP 47 language example
msgid "to search for a BCP 47 language tag, for example"
msgstr "pour rechercher une balise de langue BCP 47, par exemple"

# Search box hint: BCP 47 language example
msgid "searches for Tigrigna %sEthiopia%s"
msgstr "busca Tigrigna %sEtiopía%s"

44 changes: 44 additions & 0 deletions _includes/locale/locale.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

$locales = [
'en' => 'English', // Default
'es-ES' => 'Española',
'fr-FR' => 'Français'
];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently not used. Maybe when we settle on UX for specifying UI locale on the site...


/**
* Use textdomain to specify the localization file for "localization".
* Ignore if locale is "en" or the filename doesn't exist
* Filename expected to be "$basename-$locale.mo"
* locale - xx-YY locale as specified in crowdin %locale%
* basename - base name of the .mo file to use
*/
function setTextDomain($locale, $basename) {
$filename = sprintf("%s-%s", $basename, $locale);
$fullPath = __DIR__ . "/en/LC_MESSAGES/" . $filename . ".mo";
if(file_exists($fullPath)) {
textdomain($filename);
} else {
# Log or warn?
return;
}
}

/**
* Wrapper to format string with gettext '_(' alias and variable args
* s - the format string
* args - optional remaining args to the format string
*/
function _s($s, ...$args) {
return vsprintf(_($s), $args);
}

/**
* Wrapper of echo and _s
*/
function echo_s($s, ...$args) {
$tempString = _s($s, $args);
echo $tempString;
}


Loading