Editing Module:LangGive feedback
Jump to navigation
Jump to search
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
| Latest revision | Your text | ||
| Line 4: | Line 4: | ||
local dictionary_module = require("Module:Dictionary") | local dictionary_module = require("Module:Dictionary") | ||
-- Overrides applied to searches by key. | -- Caches to prevent repetitive file loading and table generation | ||
local lang_file_cache = {} | |||
local en_reverse_cache = nil | |||
-- Overrides applied to searches by key. | |||
local KEY_OVERRIDES = { | local KEY_OVERRIDES = { | ||
BurnDurationBase_label = 'AfterburnDurationBase_label', | BurnDurationBase_label = 'AfterburnDurationBase_label', | ||
| Line 39: | Line 42: | ||
SummonCount_label = 'GhoulCount_label', | SummonCount_label = 'GhoulCount_label', | ||
TetherDuration_label = 'ImmobilizeTrap_CurseDuration_label' | TetherDuration_label = 'ImmobilizeTrap_CurseDuration_label' | ||
} | |||
-- Moved static configuration mappings outside the function to avoid garbage collection pressure | |||
local REPLACEMENTS = { | |||
BonusFireRate = {icon='{{Icon/Brown|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}', label_color='#ffefd7', link='Fire Rate'}, | |||
BonusMoveSpeed = {icon='{{Icon/Green|[[File:Move_speed.png|link=Move speed|20px]]}}', label_color='#ffefd7', link='Move speed'}, | |||
BonusSprintSpeed = {icon='{{Icon/Green|[[File:Move_speed.png|link=Sprint speed|20px]]}}', label_color='#ffefd7', link='Sprint speed'}, | |||
BonusSpiritDamage = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', label_color='#bc8ee8', link='Spirit Damage'}, | |||
BonusWeaponDamage = {icon='{{Icon/NoColor|[[File:Bullet Damage.png|link=Weapon Damage|20px]]}}', label_color='#ec981a', link='Weapon Damage'}, | |||
bullet_armor_up = {icon='{{Icon/White|[[File:Barrier.png|link=Barrier|20px]]}}', label_color='#ffefd7', link='Barrier'}, | |||
bullet_damage = {icon='{{Icon/NoColor|[[File:Bullet_damage.png|link=Weapon Damage|20px]]}}', label_color='#ec981a', link='Weapon Damage'}, | |||
BulletResist = {icon='{{Icon/Brown|[[File:Bullet_Armor.png|link=Damage_Resistance|20px]]}}', label_color='#ec981a', link='Damage_Resistance'}, | |||
cast = {icon='{{Icon/White|[[File:Cast.png|link=|20px]]}}', label_color='#ffefd7', link=''}, | |||
CombatBarrier = {icon='{{Icon/White|[[File:Bullet Armor (item).png|link=Damage_Resistance|20px]]}}', label_color='#ffefd7', link='Barrier'}, | |||
cooldown = {icon='{{Icon/White|[[File:AttributeIconTechDuration.png|link=Ability Cooldown|20px]]}}', label_color='#ffefd7', link='Ability Cooldown'}, | |||
damage = {icon='{{Icon/NoColor|[[File:Damage heart.png|link=Damage|20px]]}}', label_color='#ec981a', link='Damage'}, | |||
DamageAmp = {icon='{{Icon/White|[[File:Damage heart.png|link=Damage Amp|20px]]}}', label_color='#ffefd7', link='Damage Amp'}, | |||
FireRate = {icon='{{Icon/White|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}', label_color='#ffefd7', link='Fire Rate'}, | |||
fire_rate = {icon='{{Icon/White|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}', label_color='#ffefd7', link='Fire Rate'}, | |||
Heal = {icon='{{Icon/Green|[[File:Healing.png|link=Health_Regen|20px]]}}', label_color='#13f278', link='Health_Regen'}, | |||
Healing = {icon='{{Icon/Green|[[File:Healing.png|link=Healing|20px]]}}', label_color='#13f278', link='Healing'}, | |||
Immobilize = {icon='{{Icon/White|[[File:Immobilize.png|link=Status Effects#Immobilized|20px]]}}', label_color='#ffefd7', link='Status Effects#Immobilized'}, | |||
invisible = {icon='{{Icon/White|[[File:Invisible.png|link=|20px]]}}', label_color='#ffefd7', link=''}, | |||
KnockBack = {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'}, | |||
KnockUp = {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'}, | |||
MaxHealth = {icon='{{Icon/Green|[[File:Healing.png|link=Health|20px]]}}', label_color='#13f278', link='Health'}, | |||
MeleeDamage = {icon='{{Icon/Brown|[[File:Melee damage.png|link=Melee Damage|20px]]}}', label_color='#ec981a', link='Melee Damage'}, | |||
MoveSpeed = {icon='{{Icon/Green|[[File:Move_speed.png|link=Move speed|20px]]}}', label_color='#ffefd7', link='Move speed'}, | |||
move_speed = {icon='{{Icon/Green|[[File:Move_speed.png|link=Move speed|20px]]}}', label_color='#ffefd7', link='Move speed'}, | |||
Pull = {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'}, | |||
Pulling = {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'}, | |||
Pulls = {icon='{{Icon/NoColor|[[File:Displacement.png|link=|20px]]}}', label_color='#ffefd7', link='Status_Effects'}, | |||
PureDamage = {icon='{{Icon/NoColor|[[File:Damage.png|link=Pure Damage|20px]]}}', label_color='#ffefd7', link='Pure Damage'}, | |||
ReducedFireRate = {icon='{{Icon/Brown|[[File:Fire_Rate.png|link=Fire Rate|20px]]}}', label_color='#ffefd7', link='Fire Rate'}, | |||
Regen = {icon='{{Icon/Green|[[File:Healing.png|link=Health_Regen|20px]]}}', label_color='#13f278', link='Health_Regen'}, | |||
revealed = {icon='{{Icon/White|[[File:Revealed.png|link=|20px]]}}', label_color='#ffefd7', link=''}, | |||
silence = {icon='{{Icon/White|[[File:Silence.png|link=|20px]]}}', label_color='#ffefd7', link=''}, | |||
Silence = {icon='{{Icon/Purple|[[File:Silence.png|link=Silence|20px]]}}', label_color='#bc8ee8', link='Silence'}, | |||
Slow = {icon='{{Icon/White|[[File:MoveSlow.png|link=Movement_Slow|20px]]}}', label_color='#ffefd7', link='Movement_Slow'}, | |||
slow = {icon='{{Icon/White|[[File:MoveSlow.png|link=Movement_Slow|20px]]}}', label_color='#ffefd7', link='Movement_Slow'}, | |||
SlowResistance = {icon='{{Icon/White|[[File:MoveSlow.png|link=Movement_Slow#Movement_Slow_Resist|20px]]}}', label_color='#ffefd7', link='Movement_Slow#Movement_Slow_Resist'}, | |||
Spirit = {icon='{{Icon/NoColor|[[File:Spirit_icon.png|link=Spirit Power|20px]]}}', label_color='#bc8ee8', link='Spirit Power'}, | |||
SpiritDamage = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', label_color='#bc8ee8', link='Spirit Damage'}, | |||
SpiritDPS = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', label_color='#bc8ee8', link='Spirit Damage'}, | |||
SpiritIcon = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', link='Spirit Damage'}, | |||
SpiritResist = {icon='{{Icon/Purple|[[File:Spirit_Armor.png|link=Damage_Resistance|20px]]}}', label_color='#bc8ee8', link='Damage_Resistance'}, | |||
StatDesc_TechPower = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', label_color='#bc8ee8', link='Spirit Damage'}, | |||
Stun = {icon='{{Icon/White|[[File:Status_Stun.png|link=Stun|20px]]}}', link='Stun'}, | |||
stun = {icon='{{Icon/White|[[File:Stun.png|link=|20px]]}}', label_color='#ffefd7', link=''}, | |||
tech_armor_up = {icon='{{Icon/White|[[File:Barrier.png|link=Barrier|20px]]}}', label_color='#ffefd7', link='Barrier'}, | |||
tech_damage = {icon='{{Icon/NoColor|[[File:Spirit damage.png|link=Spirit Damage|20px]]}}', link='Spirit Damage'}, | |||
WeaponDamage = {icon='{{Icon/NoColor|[[File:Bullet Damage.png|link=Weapon Damage|20px]]}}', label_color='#ec981a', link='Weapon Damage'}, | |||
Heals = {icon='{{Icon/Green|[[File:Healing.png|link=Health_Regen|20px]]}}', label_color='#13f278', link='Health_Regen'}, | |||
} | |||
local KEYBINDS = { | |||
MoveForward = "forward", | |||
AltCast = "alt_cast", | |||
} | } | ||
function get_lang_file(lang_code) | function get_lang_file(lang_code) | ||
if lang_file_cache[lang_code] ~= nil then | |||
return lang_file_cache[lang_code] | |||
end | |||
local file_name = string.format("Data:Lang_%s.json", lang_code) | local file_name = string.format("Data:Lang_%s.json", lang_code) | ||
local success, data = pcall(mw.loadJsonData, file_name) | local success, data = pcall(mw.loadJsonData, file_name) | ||
if success then | if success then | ||
lang_file_cache[lang_code] = data | |||
return data | return data | ||
else | else | ||
lang_file_cache[lang_code] = false -- Cache failures to avoid repeating pcall | |||
return nil | return nil | ||
end | end | ||
| Line 53: | Line 120: | ||
local function process_newlines(text) | local function process_newlines(text) | ||
if not text or type(text) ~= "string" then return text end | if not text or type(text) ~= "string" then return text end | ||
return text:gsub('"n', '<br/>') | return text:gsub('"n', '<br/>') | ||
end | end | ||
local function process_html_tags(text, frame) | local function process_html_tags(text, frame, lang_code) | ||
if not text or type(text) ~= "string" then return text end | if not text or type(text) ~= "string" then return text end | ||
-- Process HTML spans | -- Process HTML spans | ||
text = text:gsub('<span class="highlight">(.-)</span>', "<span style= font-weight:bold>%1</span>") | text = text:gsub('<span class="highlight">(.-)</span>', "<span style= font-weight:bold>%1</span>") | ||
| Line 123: | Line 136: | ||
-- Process panel tags | -- Process panel tags | ||
text = text:gsub('<Panel class=\"AbilityPropertyIcon prop_(.-)\">', function(key) | |||
local replacement = REPLACEMENTS[key] | |||
if replacement then | |||
local label_color = replacement.label_color or 'inherit' | |||
local icon = replacement.icon or '' | |||
local link = replacement.link or '' | |||
local translated = p.get_string('InlineAttribute_' .. key, lang_code, '') | |||
if translated == '' then | |||
return string.format('<span class="no-blue-link" style="text-wrap:nowrap; font-weight:bold; color:%s;">%s</span>', label_color, icon) | |||
else | |||
return string.format('<span class="no-blue-link" style="text-wrap:nowrap; font-weight:bold; color:%s;">%s [[%s|%s]]</span>', | |||
label_color, icon, link, translated) | |||
end | |||
else | |||
return '<span style="color:red;font-weight:bold;border-bottom:1px dotted red;" title="Missing attribute definition - Add \''..key..'\' to local replacements in [Module:Lang]">['..key..']</span>' | |||
end | |||
end) | |||
-- Process citadel_inline_attribute tags | -- Process citadel_inline_attribute tags | ||
text = text:gsub("{g:citadel_inline_attribute:'(.-)'}", function(key) | |||
local replacement = REPLACEMENTS[key] | |||
if replacement then | |||
local label_color = replacement.label_color or 'inherit' | |||
local icon = replacement.icon or '' | |||
local link = replacement.link or '' | |||
local translated = p.get_string('InlineAttribute_' .. key, lang_code, '') | |||
if translated == '' then | |||
return string.format('<span class="no-blue-link" style="text-wrap:nowrap; font-weight:bold; color:%s;">%s</span>', label_color, icon) | |||
else | |||
return string.format('<span class="no-blue-link" style="text-wrap:nowrap; font-weight:bold; color:%s;">%s [[%s|%s]]</span>', | |||
label_color, icon, link, translated) | |||
end | |||
else | |||
return '<span style="color:red;font-weight:bold;border-bottom:1px dotted red;" title="Missing attribute definition - Add \''..key..'\' to local replacements in [Module:Lang]">['..key..']</span>' | |||
end | |||
end) | |||
-- Process citadel_binding/citadel_keybind tags | |||
text = text:gsub("{g:citadel_binding:'(.-)'}", function(key) | |||
-- Process citadel_binding/citadel_keybind tags | |||
local lower_key = key:lower() | local lower_key = key:lower() | ||
local replacement = KEYBINDS[key] or lower_key | |||
local replacement = | local translated = p.get_string('citadel_keybind_' .. replacement, lang_code, '') | ||
local translated = | |||
if translated ~= nil and translated ~= '' then | |||
return "'''" .. translated .. "'''" | |||
else | else | ||
return '<span style="color:red;font-weight:bold;border-bottom:1px dotted red;" title="Missing keybind - Add \''..key..'\' to local replacements in [Module:Lang]">['..key..']</span>' | return '<span style="color:red;font-weight:bold;border-bottom:1px dotted red;" title="Missing keybind - Add \''..key..'\' to local replacements in [Module:Lang]">['..key..']</span>' | ||
end | end | ||
end) | |||
-- Force spaces around keybinds where the source data omits them | -- Force spaces around keybinds where the source data omits them | ||
text = text:gsub("'''([a-zA-Z])", "''' %1") | text = text:gsub("'''([a-zA-Z])", "''' %1") | ||
| Line 196: | Line 196: | ||
text = text:gsub("'''%s+:", "''':") | text = text:gsub("'''%s+:", "''':") | ||
return frame:preprocess(text) | |||
end | end | ||
function p.get_string(key, lang_code_override, fallback_str, remove_var_index, item_name) | function p.get_string(key, lang_code_override, fallback_str, remove_var_index, item_name) | ||
local frame | local frame | ||
if type(key) == "table" and key.args then | if type(key) == "table" and key.args then | ||
| Line 216: | Line 215: | ||
end | end | ||
local lang_code = lang_code_override | local lang_code = lang_code_override | ||
if (lang_code == '' or lang_code == nil) then | if (lang_code == '' or lang_code == nil) then | ||
| Line 222: | Line 220: | ||
end | end | ||
local data = get_lang_file(lang_code) | local data = get_lang_file(lang_code) | ||
if (data == nil) then | if (data == nil) then | ||
| Line 228: | Line 225: | ||
end | end | ||
local label = data[KEY_OVERRIDES[key] or key] | local label = data[KEY_OVERRIDES[key] or key] | ||
if label == nil and key ~= nil and key:sub(-6) == '_label' then | |||
local postvalue_key = key:sub(1, -7) .. '_postvalue_label' | |||
label = data[postvalue_key] | |||
end | |||
if (label == nil) then | if (label == nil) then | ||
local fallback_tooltip = frame:expandTemplate{title = "MissingValveTranslationTooltip"} | local fallback_tooltip = frame:expandTemplate{title = "MissingValveTranslationTooltip"} | ||
local fallback | local fallback | ||
| Line 253: | Line 247: | ||
end | end | ||
if type(label) == "string" and label:find("|") then | if type(label) == "string" and label:find("|") then | ||
label = label:gsub("^.*|", "") | |||
end | end | ||
if type(label) == "string" and label:find("#") then | |||
label = label:gsub("^.*#", "") | |||
end | end | ||
if (remove_var_index ~= nil) then | if (remove_var_index ~= nil) then | ||
label = util_module.remove_var(label, remove_var_index) | label = util_module.remove_var(label, remove_var_index) | ||
end | end | ||
if item_name and item_name ~= '' then | if item_name and item_name ~= '' then | ||
local item_data_module = require('Module:ItemData') | local item_data_module = require('Module:ItemData') | ||
label = label:gsub("{s:([^}]+)}", function(variable_name) | label = label:gsub("{s:([^}]+)}", function(variable_name) | ||
local value = item_data_module.get_prop({args = {item_name, variable_name}}) | local value = item_data_module.get_prop({args = {item_name, variable_name}}) | ||
if value then | if value then | ||
value = value:gsub("[^0-9+-.]", "") | value = value:gsub("[^0-9+-.]", "") | ||
return value ~= "" and value or variable_name | return value ~= "" and value or variable_name | ||
else | else | ||
return variable_name | return variable_name | ||
end | end | ||
end) | end) | ||
end | end | ||
label = process_newlines(label) | label = process_newlines(label) | ||
label = process_html_tags(label, frame) | label = process_html_tags(label, frame, lang_code) -- Added lang_code parameter | ||
-- | |||
-- Note: mw.html.create() wraps text in a <div> block. If you just need raw text, | |||
-- you should drop this wrapper and return `label` directly to save extra processing. | |||
local html = mw.html.create() | local html = mw.html.create() | ||
html:wikitext(label) | html:wikitext(label) | ||
| Line 297: | Line 282: | ||
end | end | ||
p.search_string = function(frame) | p.search_string = function(frame) | ||
local label = frame.args[1] | local label = frame.args[1] | ||
| Line 309: | Line 293: | ||
-- search_string, but for internal use by other modules | -- search_string, but for internal use by other modules | ||
p._search_string = function(label, lang_code_override) | p._search_string = function(label, lang_code_override) | ||
lang_code = lang_code_override | local lang_code = lang_code_override -- Fixed missing local statement (was leaking globally) | ||
if (lang_code == '' or lang_code == nil) then | if (lang_code == '' or lang_code == nil) then | ||
lang_code = p.get_lang_code() | lang_code = p.get_lang_code() | ||
end | end | ||
local data_lang = get_lang_file(lang_code) | |||
local data_lang = get_lang_file(lang_code) | |||
if (data_lang == nil) then | if (data_lang == nil) then | ||
error("Lang code '%s' does not have a json file", lang_code) | error("Lang code '%s' does not have a json file", lang_code) | ||
end | end | ||
if not en_reverse_cache then | |||
en_reverse_cache = {} | |||
local data_en = get_lang_file('en') | |||
if data_en then | |||
for k, v in pairs(data_en) do | |||
if en_reverse_cache[v] == nil then | |||
en_reverse_cache[v] = k | |||
end | |||
end | |||
end | end | ||
end | end | ||
local key = en_reverse_cache[label] | |||
if (key == nil) | |||
if (key == nil) or (data_lang[key] == nil) then | |||
return label | return label | ||
end | end | ||