Module:AbilitySection: Difference between revisionsGive feedback
Gammaton32 (talk | contribs) m Reverted edit by Gammaton32 (talk) to last revision by Vergir Tag: Rollback |
Use Data:Dictionary keys for ability card tab labels instead of hardcoded English (with help from vergir-bot LLM) |
||
| (16 intermediate revisions by 5 users not shown) | |||
| Line 1: | Line 1: | ||
-- | -- See /doc for docs | ||
local p = {} | local p = {} | ||
local utils = require "Module:Abilities/utils" | local utils = require "Module:Abilities/utils" | ||
local lang = require "Module:Lang" | local lang = require "Module:Lang" | ||
local | local AbilityHints = require "Module:AbilityHints" | ||
local resource_lookup = mw.loadJsonData("Data:ResourceLookup.json") | local resource_lookup = mw.loadJsonData("Data:ResourceLookup.json") | ||
local dictionary_data = mw.loadJsonData("Data:Dictionary") | |||
-- Tab definitions — order here determines display order. | -- Tab definitions — order here determines display order. | ||
-- label_dict_key names the [[Data:Dictionary]] entry holding the tab label; the Notes | |||
-- tab reuses the existing 'Notes' entry rather than adding a duplicate. | |||
local TABS = { | local TABS = { | ||
{ key = 'notes', label_dict_key = 'Notes' }, | |||
{ key = 'tips', label_dict_key = 'AbilityCardTabTips' }, | |||
{ key = 'interactions', label_dict_key = 'AbilityCardTabInteractions' }, | |||
} | } | ||
local SHOW_ALL_DICT_KEY = 'AbilityCardTabShowAll' | |||
-- Tab labels are read from the dictionary directly instead of going through | |||
-- Module:Dictionary, which appends Template:NeedsTranslationTooltip markup to | |||
-- anything untranslated. mw.ext.tabber.render HTML-escapes a label and reuses it as a | |||
-- DOM id, so that markup would show up as literal text in the tab and mangle the | |||
-- anchor. Untranslated labels therefore fall back to English silently. | |||
local function tab_label(dict_key) | |||
local entry = dictionary_data[dict_key] | |||
if entry == nil then return dict_key end | |||
return entry[lang.get_lang_code()] or entry.en or dict_key | |||
end | |||
local function get_hero_key(hero_name) | local function get_hero_key(hero_name) | ||
if hero_name == nil or hero_name == '' then return nil end | |||
if string.sub(hero_name, 1, 5) == "hero_" then return hero_name end | |||
local entry = resource_lookup[hero_name:lower()] | |||
if entry == nil then return nil end | |||
return entry.key | |||
end | end | ||
local function trim(s) | local function trim(s) | ||
return s:match('^%s*(.-)%s*$') | |||
end | |||
-- Process content in the Interactions tab to build list of icons to draw in ability hints beside ability card | |||
local function process_interactions(html, ability_num) | |||
local manual, idx, seen = {}, 0, {} | |||
local out = html:gsub('(<div)([^>]*data%-iconbox%-icon="[^"]*"[^>]*)(>)', function(pre, attrs, post) | |||
local file = attrs:match('data%-iconbox%-icon="([^"]*)"') | |||
if file and file ~= '' then | |||
local base = mw.ustring.lower((file:gsub('%.%w+$', ''))) | |||
local entry = resource_lookup[base] | |||
if entry ~= nil and entry.type == 'item' and not seen[base] then | |||
seen[base] = true | |||
idx = idx + 1 | |||
local box_id = 'ai-int-' .. ability_num .. '-' .. idx | |||
table.insert(manual, { | |||
file = file, | |||
title = attrs:match('data%-iconbox%-title="([^"]*)"') or '', | |||
state = attrs:match('data%-iconbox%-state="([^"]*)"') or 'normal', | |||
anchor = box_id, | |||
}) | |||
return pre .. attrs .. ' id="' .. box_id .. '"' .. post | |||
end | |||
end | |||
return pre .. attrs .. post | |||
end) | |||
return out, manual | |||
end | end | ||
local function build_tabber(wikitext_map) | local function build_tabber(wikitext_map, tab_overrides) | ||
tab_overrides = tab_overrides or {} | |||
local filled = {} | |||
for _, tab in ipairs(TABS) do | |||
if wikitext_map[tab.key] ~= '' then | |||
local tab_wt = tab_overrides[tab.key] | |||
if tab_wt == nil or tab_wt == '' then tab_wt = wikitext_map[tab.key] end | |||
table.insert(filled, { | |||
key = tab.key, | |||
label = tab_label(tab.label_dict_key), | |||
tab_wt = tab_wt, | |||
all_wt = wikitext_map[tab.key], | |||
}) | |||
end | |||
end | |||
if #filled == 0 then | |||
return '' | |||
end | |||
local tabs = {} | |||
for _, section in ipairs(filled) do | |||
table.insert(tabs, { | |||
label = section.label, | |||
content = '<div class="ability-details-panel">\n' .. section.tab_wt .. '\n</div>', | |||
}) | |||
end | |||
if #filled >= 2 then | |||
local all_parts = {} | |||
for _, section in ipairs(filled) do | |||
table.insert(all_parts, | |||
'<div class="ability-details-section-header">' .. section.label .. '</div>' | |||
.. '<div class="ability-details-section-content">\n' .. section.all_wt .. '\n</div>' | |||
) | |||
end | |||
table.insert(tabs, { | |||
label = tab_label(SHOW_ALL_DICT_KEY), | |||
content = '<div class="ability-details-panel">' .. table.concat(all_parts) .. '</div>', | |||
}) | |||
end | |||
local rendered = mw.ext.tabber.render(tabs) | |||
if #filled == 1 then | |||
return '<div class="single-tabbed">' .. rendered .. '</div>' | |||
end | |||
return rendered | |||
end | end | ||
-- Entry point. Called via {{#invoke:AbilitySection|render}}. | -- Entry point. Called via {{#invoke:AbilitySection|render}}. | ||
function p.render(frame) | function p.render(frame) | ||
local args = frame.args | |||
local hero_name = trim(args.hero_name or '') | |||
local ability_num = trim(args.ability_num or '') | |||
local notes = trim(args.notes or '') | |||
local tips = trim(args.tips or '') | |||
local interactions = trim(args.interactions or '') | |||
local hero_key = get_hero_key(hero_name) | |||
local heading = '' | |||
local ability_key = nil | |||
if hero_key ~= nil then | |||
local ability = utils.get_ability_card_data(hero_key, ability_num) | |||
if ability ~= nil then | |||
ability_key = ability.Key | |||
heading = '<h3 class="ability-name | local ability_name = lang.get_string(ability.Key) | ||
-- Create a visually hidden H3 heading so the Table of Contents can parse | |||
-- the ability name without displaying a redundant title above the card. | |||
heading = '<h3 class="ability-name-toc">' .. ability_name .. '</h3>' | |||
end | end | ||
end | |||
local card = frame:expandTemplate{ | |||
title = 'Ability card v2', | |||
args = { hero_name = hero_name, ability_num = ability_num, link_name = 'false' } | |||
} | |||
local interactions_ided, manual = interactions, {} | |||
if interactions ~= '' then | |||
interactions_ided, manual = process_interactions(interactions, ability_num) | |||
end | |||
local wikitext_map = { | |||
notes = notes, | |||
tips = tips, | |||
interactions = interactions, | |||
} | |||
local tabber = build_tabber(wikitext_map, { interactions = interactions_ided }) | |||
local hints_col = '' | |||
if ability_key ~= nil or #manual > 0 then | |||
hints_col = AbilityHints.get_icons(ability_key, ability_num, manual) | |||
end | |||
local details_col = '' | |||
if tabber ~= '' then | |||
details_col = '<div class="ability-section-details">' .. tabber .. '</div>' | |||
end | |||
local card_block = '<div class="ability-section-card">' .. card .. '</div>' | |||
local left_col | |||
if hints_col ~= '' then | |||
left_col = '<div class="ability-section-main">' .. card_block .. hints_col .. '</div>' | |||
else | |||
left_col = card_block | |||
end | |||
local ability_section = '<div class="ability-section">' | |||
.. left_col | |||
.. details_col | |||
.. '</div>' | |||
return '<div class="ability-section-wrapper">' | |||
.. heading | |||
.. ability_section | |||
.. '</div>' | |||
end | end | ||
return p | return p | ||