Module:DM Fusion display
Revision as of 00:55, 21 May 2024 by JustGian (talk | contribs) (The Fusion display for DOR cards works, but the lists were slowing down the articles, likely due to the superfluous queries for each material's properties. Creating a module which uses 1 query, hopefully to increase the speed, and as a learning experience)
-- <pre>
-- @name DM Fusion display
-- @description A module used to display Fusion combinations in their respective card articles
-- @author [[User:JustGian]]
-- @contact [[User talk:JustGian]]
----------------
-- Load modules:
----------------
local DATA = require( 'Module:Data' );
local UTIL = require( 'Module:Util' );
--------------------
-- Module variables:
--------------------
-- Parser state:
local
PAGENAME,
NAMESPACE,
_frame,
_args
;
-- Stores properties for cards to avoid making a new query each time they are needed
local CARD_INFO = {}
---------------------
-- Utility functions:
---------------------
-- mw functions:
local HTML = mw.html.create;
--------------------
-- Module functions:
--------------------
--# Local functions
--[[Doc
@function U unlink
@description (From Module:Card type) If a string is passed, unlinks
and returns the page name (not the label, unless «getLabel»).
If a table is passed, unlinks every instance of it
and returns the table with the page names for each respective entry.
@parameter {*} v Any value to unlink.
@parameter {boolean} getLabel Makes the function return the label instead.
@return {*} The unlinked value.
]]
local function unlink( v, getLabel )
local function __unlink( v, getLabel )
return _trim( v ) and (getLabel and v:match( '%[%[:?.-|(.-)]]' ) or v:match( '%[%[:?(.-)[|%]]' )) or _trim( v );
end
if type( v ) == 'string' then
return __unlink( v, getLabel );
elseif type( v ) == 'table' then
local t = {};
for key, value in ipairs( v ) do
table.insert( t, __unlink( value, getLabel ) );
end
return t;
else
return v; -- @@@ error()
end
end
-- @name format_cards_to_display
-- @description Receives a table with card page names and returns the expected strings to be displayed
local function format_cards_to_display(cards)
local display_table = {}
for i, card in pairs(cards) do
attr = CARD_INFO[card]
display_table[i] = string.format("#%s: %s\"[[%s|%s]]\"", attr["number"], attr["level"] and ( attr["level"] .. " [[File:CG Star.svg|15px|alt=|class=noviewer]] " ), unlink(card), attr["name"])
end
return display_table
end
-- @name run_fusion_combination_query
-- @description Gets the required attributes for a Fusion query by running the provided conditions.
-- By running the query only once, the module saves a considerable amount of time that would be spent querying each card's name every time it is required
local function process_fusion_combination_query(conditions)
-- The attributes that should be returned
local required_attributes = {
"Fusion Material 1", "Fusion Material 2", "Description", "Columns", -- Attributes about the Fusion combination
"Fusion Material 1.English name = English name 1", "Fusion Material 1.Level = Level 1", "Fusion Material 1.Card number = Card number 1", -- Attributes about each card listed as Material 1
"Fusion Material 2.English name = English name 2", "Fusion Material 2.Level = Level 2", "Fusion Material 2.Card number = Card number 2" -- Attributes about each card listed as Material 2
}
local query = mw.smw.ask( conditions .. "|?" .. table.concat(required_attributes, "|?"))
-- Iterates over both Fusion Material lists, and adds each card to the table
for _, combination in pairs(query) do
mw.logObject(combination)
for _, combi_index in pairs({"1", "2"}) do
-- Pre-processing on the multi-value attributes
materials = combination["Fusion Material " .. combi_index]
materials = type(materials) == "table" and materials or { materials }
en_names = combination["English name " .. combi_index]
en_names = type(en_names) == "table" and en_names or { en_names }
levels = combination["Level " .. combi_index]
levels = type(levels) == "table" and levels or { levels }
number = combination["Card number " .. combi_index]
number = type(number) == "table" and number or { number }
for i, fm in pairs(materials) do
if not CARD_INFO[fm] then
CARD_INFO[fm] = {}
CARD_INFO[fm]["name"] = en_names[i]
CARD_INFO[fm]["level"] = levels[i]
CARD_INFO[fm]["number"] = number[i]
end
end
end
end
return query
end
-- @name fill_fusion_materials_table
-- @description Appends the row with the materials belonging to the current combination to a table
local function fill_fusion_materials_table( cur_table, mats1, mats2, columns )
local mats_row = cur_table:tag("tr")
mats_row:tag("td"):wikitext("\n* " .. table.concat(format_cards_to_display(mats1), "\n* "))
mats_row:tag("td"):tag("div"):attr("style", "column-width: 13em; column-count: " .. columns):wikitext("\n* " .. table.concat(format_cards_to_display(mats2), "\n* "))
return cur_table
end
-- @name fusion_result
-- @description Generates the materials lists for fusion result. To be called through #invoke.
local function fusion_result( frame )
_frame = frame;
_args = UTIL.getArgs( frame, {
trim = true,
removeBlanks = true,
parentOnly = true
} );
if not mw.smw then
return "mw.smw module not found"
end
local fusion_frame = HTML()
local page_name = _args[1] or "Bracchio-raidus (DOR)"
local query = process_fusion_combination_query( string.format("[[Fusion result::%s]]", page_name ))
local prev_description, cur_table
for i, combination in pairs(query) do
local mats1, mats2, description, columns = combination["Fusion Material 1"], combination["Fusion Material 2"], combination["Description"], combination["Columns"] or 1
-- MW attributes don't return a table if there is only 1 value. Converting both to tables to facilitate future processing
mats1 = type(mats1) ~= 'table' and { mats1 } or mats1
mats2 = type(mats2) ~= 'table' and { mats2 } or mats2
-- Creates a new table on the first itteration, and when a description changes
if not cur_table or description ~= prev_description then
cur_table = fusion_frame:tag("table"):attr("class", "wikitable")
cur_table:wikitext(description)
local header = cur_table:tag("tr")
header:tag("th"):attr("scope", "col"):wikitext("Material 1")
header:tag("th"):attr("scope", "col"):wikitext("Material 2")
end
-- Appends materials to the table
cur_table = fill_fusion_materials_table(cur_table, mats1, mats2, columns)
prev_description = description or prev_description
end
return tostring(fusion_frame)
end
----------
-- Return:
----------
-- @exports
return {
['fusion_result'] = fusion_result
};
-- </pre>