Locales de script FiveM : scripts traduisibles avec en.lua, ox_lib et ESX

Rendez votre script FiveM traduisible : un dossier locales avec en.lua et es.lua, une fonction locale simple, le système locale d'ox_lib, ESX TranslateCap et une configuration de langue.

Votre script a 'You have no money' codé en dur à quarante endroits. Un propriétaire de serveur à Madrid ou Berlin le veut dans sa langue, et le seul moyen est d'éditer le code. La solution est une couche locale : les chaînes vivent dans des fichiers par langue, le code demande des clés. Ce guide montre une simple version Lua simple, puis le système d'ox_lib et celui d'ESX.

L'idée

Au lieu de :

lua
ESX.ShowNotification('You have no money')

le code écrit :

lua
ESX.ShowNotification(L('no_money'))

et un fichier de langue fournit le texte pour no_money. Les traducteurs modifient ensuite les fichiers, jamais le code, et les fichiers locale ouverts peuvent être livrés non chiffrés (consultez escrow_ignore).

Une simple fonction locale Lua

Disposition du dossier :

text
my_script/
  fxmanifest.lua
  config.lua
  locales/
    en.lua
    es.lua
  shared/locale.lua

locales/en.lua :

lua
Locales = Locales or {}

Locales['en'] = {
    no_money = 'You have no money',
    bought   = 'You bought %s for $%s',
}

locales/es.lua :

lua
Locales = Locales or {}

Locales['es'] = {
    no_money = 'No tienes dinero',
    bought   = 'Compraste %s por $%s',
}

shared/locale.lua, la fonction qui cherche une clé :

lua
function L(key, ...)
    local lang = Locales[Config.Locale] or Locales['en']
    local text = lang[key] or Locales['en'][key] or key
    if select('#', ...) > 0 then
        return text:format(...)
    end
    return text
end

Manifeste, avec les locales d'abord et la config avant la fonction :

lua
fx_version 'cerulean'
game 'gta5'

shared_scripts {
    'config.lua',
    'locales/*.lua',
    'shared/locale.lua',
}
client_script 'client/main.lua'
server_script 'server/main.lua'

Et dans config.lua :

lua
Config = {}
Config.Locale = 'en'

Utilisation, avec des espaces réservés %s remplis par string.format :

lua
print(L('bought', 'bread', 5))   -- You bought bread for $5

Les retombées sont importantes : une clé manquante dans es retombe sur en, et une clé manquante partout retourne la clé elle-même, de sorte que vous voyez no_money à l'écran au lieu d'une erreur. Un trou dans une traduction montre alors une clé visible, pas un crash.

Conseil : gardez les mêmes clés dans chaque fichier de langue. Un petit script qui compare les clés en avec chaque autre fichier attrape les traductions manquantes avant la sortie.

Le système locale d'ox_lib

Si votre script dépend déjà d'ox_lib, vous pouvez utiliser ses locales intégrées au lieu d'écrire L(). La forme est : charger ox_lib dans le manifeste, mettez vos traductions dans un dossier locales/ (ox_lib utilise des fichiers .json nommés par langue, comme locales/en.json), incluez-les avec files, et appelez lib.locale() une fois :

lua
-- fxmanifest.lua
shared_script '@ox_lib/init.lua'
files { 'locales/*.json' }
json
{
  "no_money": "You have no money",
  "bought": "You bought %s for $%s"
}
lua
lib.locale()   -- load the language

lib.notify({ description = locale('no_money'), type = 'error' })
print(locale('bought', 'bread', 5))

Vérifiez la documentation ox_lib pour le format actuel et pour comment la langue est choisie (un convar serveur), car la disposition des fichiers et les noms des options ont changé entre les versions. Si vous voyez ox_lib/init.lua non trouvé, corrigez cela d'abord : ox_lib init.lua non trouvé.

ESX et TranslateCap

Les scripts ESX ont leur propre modèle local. Les fichiers locale remplissent une table Locales et le framework fournit une fonction de traduction :

lua
-- fxmanifest.lua
shared_scripts {
    '@es_extended/imports.lua',
    '@es_extended/locale.lua',
    'locales/*.lua',
    'config.lua',
}
lua
-- locales/en.lua
Locales['en'] = {
    ['no_money'] = 'You have no money',
}
lua
TriggerEvent('esx:showNotification', TranslateCap('no_money'))

Les anciens scripts utilisent _U('no_money') pour la même chose. TranslateCap est le nom actuel dans le récent ESX Legacy, et la langue est sélectionnée par Config.Locale ou le paramètre du framework lui-même. Comme avec ox_lib, vérifiez la documentation de la version ESX que vous exécutez pour les noms exacts des fichiers et celle des deux fonctions qu'elle attend.

QBCore a un module Lang similaire (locales/en.lua utilisant Lang:t('key')) qui fonctionne de la même façon : une table par langue et une fonction qui résout les clés.

Choisir la langue

Offrez une ligne de config, près du haut de config.lua :

lua
Config.Locale = 'en'   -- 'en', 'es', 'fr'...

Si votre script est un mélange de client, serveur et NUI, souvenez-vous que le texte NUI a besoin de ses propres traductions : envoyez les chaînes à la page une fois quand elle s'ouvre, au lieu d'écrire l'anglais dans le HTML. Consultez FiveM NUI avec React et Vite pour passer des données à la page.

Liste de contrôle

Symptôme Solution
Texte anglais codé en dur dans le code Déplacez-le vers locales/en.lua et appelez L('key')
attempt to index a nil value sur Locales[...] Chargez les fichiers locale avant le code qui les lit
La clé brute s'affiche à l'écran La clé manque dans la langue choisie et dans en
Mauvaise langue utilisée Vérifiez Config.Locale et le convar locale
ox_lib locale() retourne la clé Appelez d'abord lib.locale() et incluez locales/*.json dans files
NUI toujours anglais Passez les chaînes traduites à la page

Réponses rapides

Où dois-je mettre les traductions dans un script FiveM ?

Dans un dossier locales/ avec un fichier par langue, comme en.lua et es.lua, chargés avant le code qui les utilise. Le script demande ensuite une clé, jamais une chaîne littérale.

ox_lib a-t-il un système locale ?

Oui. Il lit les fichiers locale et vous donne locale('key') après que vous appeliez lib.locale(). Vérifiez la documentation ox_lib pour le format de fichier actuel et le paramètre qui choisit la langue.

Comment choisir la langue ?

Avec une valeur Config.Locale dans votre config, ou avec un convar que votre framework ou ox_lib lit. Retombez sur l'anglais quand une clé ou une langue manque.

Des scripts sans ce problème

Mic PhoneUn téléphone pliable qui se déplie en tablette et se prolonge jusqu’au vrai téléphone du joueur.Voir le script →Shop CreatorCréez un magasin en moins d’une minute — propriétaires, employés, coffres et braquages inclus.Voir le script →Item Creator V2Créez des items utilisables avec animations, props, effets et plus — sans écrire une ligne de code.Voir le script →

À lire aussi