mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-28 17:01:14 +00:00
Merge pull request #1808 from ASTROWwwW/feat/locale-key-fallback
feat(es_extended): fall back to English for missing locale keys
This commit is contained in:
@@ -1,20 +1,69 @@
|
|||||||
Locales = {}
|
Locales = {}
|
||||||
|
|
||||||
|
--- English fallback for missing keys. locale.lua runs in every resource VM, so
|
||||||
|
--- a resource may opt out through its own Config.LocaleFallback; otherwise the
|
||||||
|
--- shared "esx:localeFallback" convar decides (enabled by default).
|
||||||
|
local function localeFallbackEnabled()
|
||||||
|
if Config.LocaleFallback ~= nil then
|
||||||
|
return Config.LocaleFallback
|
||||||
|
end
|
||||||
|
|
||||||
|
return GetConvar("esx:localeFallback", "true") ~= "false"
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Read and execute a locale file, returning its table or false if unreadable.
|
||||||
|
local function readLocale(locale)
|
||||||
|
local success, result = pcall(function()
|
||||||
|
return assert(load(LoadResourceFile(GetCurrentResourceName(), ("locales/%s.lua"):format(locale))))()
|
||||||
|
end)
|
||||||
|
|
||||||
|
return success and result or false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Copy every key the target locale is missing from English into it once, warn
|
||||||
|
--- about the gaps, then let the English table go. The locale ends up
|
||||||
|
--- self-contained, so no per-call fallback and only one table stays in memory.
|
||||||
|
local function backfillFromEnglish(locale, translations)
|
||||||
|
local english = readLocale("en")
|
||||||
|
if not english then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local missing = {}
|
||||||
|
for key, value in pairs(english) do
|
||||||
|
if translations[key] == nil then
|
||||||
|
translations[key] = value
|
||||||
|
missing[#missing + 1] = key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #missing > 0 then
|
||||||
|
print(("[es_extended] locale [%s] is missing %d translation(s), falling back to English: %s")
|
||||||
|
:format(locale, #missing, table.concat(missing, ", ")))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Lazily load and cache a locale file, false if it cannot be read.
|
||||||
|
local function loadLocale(locale)
|
||||||
|
if Locales[locale] == nil then
|
||||||
|
local translations = readLocale(locale)
|
||||||
|
|
||||||
|
if translations and locale ~= "en" and localeFallbackEnabled() then
|
||||||
|
backfillFromEnglish(locale, translations)
|
||||||
|
end
|
||||||
|
|
||||||
|
Locales[locale] = translations
|
||||||
|
end
|
||||||
|
|
||||||
|
return Locales[locale]
|
||||||
|
end
|
||||||
|
|
||||||
function Translate(str, ...) -- Translate string
|
function Translate(str, ...) -- Translate string
|
||||||
if not str then
|
if not str then
|
||||||
error(("Resource ^5%s^1 You did not specify a parameter for the Translate function or the value is nil!"):format(GetInvokingResource() or GetCurrentResourceName()))
|
error(("Resource ^5%s^1 You did not specify a parameter for the Translate function or the value is nil!"):format(GetInvokingResource() or GetCurrentResourceName()))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Load the locale file if it hasn't been loaded yet
|
local translations = loadLocale(Config.Locale)
|
||||||
if Locales[Config.Locale] == nil then
|
|
||||||
local success, result = pcall(function()
|
|
||||||
return assert(load(LoadResourceFile(GetCurrentResourceName(), ("locales/%s.lua"):format(Config.Locale))))()
|
|
||||||
end)
|
|
||||||
|
|
||||||
Locales[Config.Locale] = success and result or false
|
|
||||||
end
|
|
||||||
|
|
||||||
local translations = Locales[Config.Locale]
|
|
||||||
if not translations then
|
if not translations then
|
||||||
if Config.Locale == "en" then
|
if Config.Locale == "en" then
|
||||||
return "Locale [en] does not exist"
|
return "Locale [en] does not exist"
|
||||||
@@ -38,4 +87,4 @@ end
|
|||||||
|
|
||||||
_ = Translate
|
_ = Translate
|
||||||
-- luacheck: ignore _U
|
-- luacheck: ignore _U
|
||||||
_U = TranslateCap
|
_U = TranslateCap
|
||||||
|
|||||||
@@ -4,6 +4,11 @@ local txAdminLocale = GetConvar("txAdmin-locale", "en")
|
|||||||
local esxLocale = GetConvar("esx:locale", "invalid")
|
local esxLocale = GetConvar("esx:locale", "invalid")
|
||||||
Config.Locale = (esxLocale ~= "invalid") and esxLocale or (txAdminLocale ~= "custom" and txAdminLocale) or "en"
|
Config.Locale = (esxLocale ~= "invalid") and esxLocale or (txAdminLocale ~= "custom" and txAdminLocale) or "en"
|
||||||
|
|
||||||
|
-- When a key is missing from the active locale, fall back to the English string
|
||||||
|
-- instead of returning a placeholder. Set convar "esx:localeFallback" to "false"
|
||||||
|
-- to keep the placeholder (useful when authoring a new translation).
|
||||||
|
Config.LocaleFallback = GetConvar("esx:localeFallback", "true") ~= "false"
|
||||||
|
|
||||||
-- For ox inventory, this will automatically be adjusted, do not change! For other inventories, leave as false unless specifically instructed to change.
|
-- For ox inventory, this will automatically be adjusted, do not change! For other inventories, leave as false unless specifically instructed to change.
|
||||||
Config.CustomInventory = false
|
Config.CustomInventory = false
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user