Module:Lang: Difference between revisions
No edit summary |
m bugfix with 'dictionary' fallback option |
||
(50 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local util_module = require("Module:Utilities") | |||
local lang_codes_set = mw.loadJsonData("Data:LangCodes.json") | |||
local dictionary_module = require("Module:Dictionary") | |||
-- Overrides applied to searches by key. Designed to handle edge cases where | |||
-- the expected key does not have a localization entry | |||
local KEY_OVERRIDES = { | |||
MoveSlowPercent_label = 'MovementSlow_label', | |||
BonusHealthRegen_label = 'HealthRegen_label', | |||
BarbedWireRadius_label = 'Radius_label', | |||
BarbedWireDamagePerMeter_label = 'DamagePerMeter_label', | |||
BuildUpDuration_label = 'BuildupDuration_label', | |||
TechArmorDamageReduction_label = 'TechArmorDamageReduction_Label', | |||
DamageAbsorb_label = 'DamageAbsorb_Label', | |||
InvisRegen_label = 'InvisRegen_Label', | |||
EvasionChance_label = 'EvasionChance_Label', | |||
DelayBetweenShots_label = 'DelayBetweenShots_Label', | |||
} | |||
function get_lang_file(lang_code) | function get_lang_file(lang_code) | ||
local | local file_name = string.format("Data:Lang_%s.json", lang_code) | ||
local success, data = pcall(mw.loadJsonData, file_name) | |||
if success then | |||
return data | |||
else | |||
return nil | |||
end | |||
end | end | ||
-- Get a localized string by the raw key | -- Get a localized string by the raw key | ||
p.get_string = function(frame) | p.get_string = function(key, lang_code_override, fallback_str, remove_var_index) | ||
-- If called internally (direct Lua call), args will be passed directly. | |||
-- If called from wikitext, `key` will be the `frame` object, and we get args from `frame.args`. | |||
-- Handle the case where it's called via #invoke (i.e., from wikitext) | |||
if type(key) == "table" and key.args then | |||
local frame = key | |||
key = frame.args[1] | |||
lang_code_override = frame.args["lang_code_override"] | |||
fallback_str = frame.args["fallback_str"] | |||
remove_var_index = frame.args["remove_var_index"] | |||
end | |||
-- Determine lang_code if not overridden | |||
local lang_code = lang_code_override | |||
if (lang_code == '' or lang_code == nil) then | |||
lang_code = get_lang_code() | |||
end | |||
-- Retrieve lang data | |||
local data = get_lang_file(lang_code) | local data = get_lang_file(lang_code) | ||
local label = data[key] | if (data == nil) then | ||
if (label == nil) then | return string.format("Lang code '%s' does not have a json file", lang_code) | ||
end | |||
-- Localize | |||
local label = data[KEY_OVERRIDES[key] or key] | |||
if (label == nil) then | |||
-- Apply fallback | |||
local fallback_tooltip = mw.getCurrentFrame():expandTemplate{title = "MissingValveTranslationTooltip"} | |||
local fallback | |||
if (fallback_str == 'en') then | |||
fallback = p.get_string(key, 'en', key .. fallback_tooltip, remove_var_index, upper_lower) | |||
elseif fallback_str == 'dictionary' then | |||
return dictionary_module.translate(key, lang_code_override) | |||
elseif fallback_str ~= nil then | |||
fallback = fallback_str | |||
else | |||
return '' | |||
end | |||
return fallback .. fallback_tooltip | |||
end | |||
-- Apply remove_var | |||
if (remove_var_index ~= nil) then | |||
label = util_module.remove_var(label, remove_var_index) | |||
end | end | ||
Line 24: | Line 83: | ||
-- Search for a localized string using its English label | -- Search for a localized string using its English label | ||
p.search_string = function(frame) | p.search_string = function(frame) | ||
local | local label = frame.args[1] | ||
local | local lang_code_override = frame.args[2] | ||
local data = get_lang_file(lang_code) | |||
return p._search_string(label, lang_code_override) | |||
end | |||
-- search_string, but for internal use by other modules | |||
p._search_string = function(label, lang_code_override) | |||
lang_code = lang_code_override | |||
if (lang_code == '' or lang_code == nil) then | |||
lang_code = get_lang_code() | |||
end | |||
-- Load the language files | |||
local data_en = get_lang_file('en') -- English data | |||
local data_lang = get_lang_file(lang_code) -- Target language data | |||
if (data_lang == nil) then | |||
return string.format("Lang code '%s' does not have a json file", lang_code) | |||
end | |||
-- Search for the key in the English data | |||
local key = nil | |||
for k, v in pairs(data_en) do | |||
if v == label then | |||
key = k -- Find the key corresponding to the label | |||
break | |||
end | |||
end | |||
if (key == nil) then | |||
return string.format("English label '%s' not found", label) | |||
end | |||
if (data_lang[key] == nil) then | |||
return label | |||
end | |||
return data_lang[key] | |||
end | |||
function get_lang_code() | |||
local title = mw.title.getCurrentTitle() | |||
local lang_code = title.fullText:match(".*/(.*)$") | |||
if lang_code == nil or lang_codes_set[lang_code] == nil then | |||
return 'en' | |||
end | |||
return lang_code | |||
end | end | ||
return p | return p |
Latest revision as of 19:49, 15 October 2024
Overview[edit source]
overview
Functions[edit source]
get_string[edit source]
Localizes a given string to the current language, i.e. Data:Lang_en.json for english.
Parameters[edit source]
- key - Key string to localize
- lang_code_override (OPTIONAL) - Overrides the current language to a specific language code
- fallback_str (OPTIONAL) - Passing
en
causes it to return the english localization if it can't be localized to the current language. Passing any other string causes it to return that string if it can't be localized. Both have Template:MissingValveTranslationTooltip appended. Use this very often as some keys are not yet localized in every language by the game. Passingdictionary
causes it to return the translation via Data:Dictionary if it can't be localized. If parsing the fallback_str from lua and is computationally expensive (i.e. add_space_before_cap), consider using fallback outside this function so it only computes when needed. - remove_var_index (OPTIONAL) - Removes %variables% from the resulting string. -1 also removes the character prefixing %variables%, while 1 removes the postfixed character, and 0 removes only the %variables%.
NOTE: Optional parameters are ideally named when not all parameters are provided, though named parameters can only be passed by invoke, and not internal lua calls.
Examples[edit source]
Invokes from wikitext:
{{#invoke:Lang|get_string|CitadelHeroStats_Weapon_Falloff}}
Falloff Range
{{#invoke:Lang|get_string|CitadelHeroStats_Weapon_Falloff|lang_code_override=es}}
Distancia de caída
Examples for fallback_str[edit source]
{{#invoke:Lang|get_string|StatDesc_CritDamageBonusScale|lang_code_override=es}}
Escala de críticos adicional
{{#invoke:Lang|get_string|StatDesc_CritDamageBonusScale|lang_code_override=es|fallback_str=en}}
Escala de críticos adicional
{{#invoke:Lang|get_string|StatDesc_CritDamageBonusScale|lang_code_override=es|fallback_str=Crit Damage Bonus Scale}}
Escala de críticos adicional
{{#invoke:Lang|get_string|Tech Items|fallback_str=dictionary}}
Key 'Tech Items' is not in Data:Dictionary
Examples for remove_var_index[edit source]
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild}}
Default %hero_name% Build
TODO: Debug why is =0 still removing that extra space? Doesn't matter yet I suppose, no use cases for 0 yet
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=0}}
Default Build
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=-1}}
Default Build
When calling by internal modules, the parameters cannot be named, and therefore have to be in order. Unused parameters before the last used parameter should be nil
. Such as, .get_string('hero_atlas', nil, 'en')
search_string[edit source]
Searches for the unlocalized key corresponding to a given english string, then localizes it to the current language. NOTE: Use sparingly, always use get_string instead where plausible, as it has time complexity O(1) compared to search_string's O(10,000).
Parameters[edit source]
- string - English string to search for
Examples[edit source]
From wikitext:
{{#invoke:Lang|search_string|Abrams}}
Abrams
local p = {}
local util_module = require("Module:Utilities")
local lang_codes_set = mw.loadJsonData("Data:LangCodes.json")
local dictionary_module = require("Module:Dictionary")
-- Overrides applied to searches by key. Designed to handle edge cases where
-- the expected key does not have a localization entry
local KEY_OVERRIDES = {
MoveSlowPercent_label = 'MovementSlow_label',
BonusHealthRegen_label = 'HealthRegen_label',
BarbedWireRadius_label = 'Radius_label',
BarbedWireDamagePerMeter_label = 'DamagePerMeter_label',
BuildUpDuration_label = 'BuildupDuration_label',
TechArmorDamageReduction_label = 'TechArmorDamageReduction_Label',
DamageAbsorb_label = 'DamageAbsorb_Label',
InvisRegen_label = 'InvisRegen_Label',
EvasionChance_label = 'EvasionChance_Label',
DelayBetweenShots_label = 'DelayBetweenShots_Label',
}
function get_lang_file(lang_code)
local file_name = string.format("Data:Lang_%s.json", lang_code)
local success, data = pcall(mw.loadJsonData, file_name)
if success then
return data
else
return nil
end
end
-- Get a localized string by the raw key
p.get_string = function(key, lang_code_override, fallback_str, remove_var_index)
-- If called internally (direct Lua call), args will be passed directly.
-- If called from wikitext, `key` will be the `frame` object, and we get args from `frame.args`.
-- Handle the case where it's called via #invoke (i.e., from wikitext)
if type(key) == "table" and key.args then
local frame = key
key = frame.args[1]
lang_code_override = frame.args["lang_code_override"]
fallback_str = frame.args["fallback_str"]
remove_var_index = frame.args["remove_var_index"]
end
-- Determine lang_code if not overridden
local lang_code = lang_code_override
if (lang_code == '' or lang_code == nil) then
lang_code = get_lang_code()
end
-- Retrieve lang data
local data = get_lang_file(lang_code)
if (data == nil) then
return string.format("Lang code '%s' does not have a json file", lang_code)
end
-- Localize
local label = data[KEY_OVERRIDES[key] or key]
if (label == nil) then
-- Apply fallback
local fallback_tooltip = mw.getCurrentFrame():expandTemplate{title = "MissingValveTranslationTooltip"}
local fallback
if (fallback_str == 'en') then
fallback = p.get_string(key, 'en', key .. fallback_tooltip, remove_var_index, upper_lower)
elseif fallback_str == 'dictionary' then
return dictionary_module.translate(key, lang_code_override)
elseif fallback_str ~= nil then
fallback = fallback_str
else
return ''
end
return fallback .. fallback_tooltip
end
-- Apply remove_var
if (remove_var_index ~= nil) then
label = util_module.remove_var(label, remove_var_index)
end
return label
end
-- Search for a localized string using its English label
p.search_string = function(frame)
local label = frame.args[1]
local lang_code_override = frame.args[2]
return p._search_string(label, lang_code_override)
end
-- search_string, but for internal use by other modules
p._search_string = function(label, lang_code_override)
lang_code = lang_code_override
if (lang_code == '' or lang_code == nil) then
lang_code = get_lang_code()
end
-- Load the language files
local data_en = get_lang_file('en') -- English data
local data_lang = get_lang_file(lang_code) -- Target language data
if (data_lang == nil) then
return string.format("Lang code '%s' does not have a json file", lang_code)
end
-- Search for the key in the English data
local key = nil
for k, v in pairs(data_en) do
if v == label then
key = k -- Find the key corresponding to the label
break
end
end
if (key == nil) then
return string.format("English label '%s' not found", label)
end
if (data_lang[key] == nil) then
return label
end
return data_lang[key]
end
function get_lang_code()
local title = mw.title.getCurrentTitle()
local lang_code = title.fullText:match(".*/(.*)$")
if lang_code == nil or lang_codes_set[lang_code] == nil then
return 'en'
end
return lang_code
end
return p