[dismiss]
The wiki is currently a work in progress. If you'd like to help out, please check the Community Portal and our getting started guide. Also, check out our sister project on poewiki.net.
Module:Skill link: Difference between revisions
Jump to navigation
Jump to search
>Illviljan mNo edit summary |
(No globals. Use invoker factory from Module:Util.) |
||
(10 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
-- | ------------------------------------------------------------------------------- | ||
-- Module | -- | ||
-- | -- Module:Skill link | ||
-- | |||
-- This module implements [[Template:Skill link]] and | |||
-- [[Template:Query skill infobox]] | |||
------------------------------------------------------------------------------- | |||
require('Module:No globals') | |||
local m_util = require('Module:Util') | local m_util = require('Module:Util') | ||
-- Should we use the sandbox version of our submodules? | |||
local use_sandbox = m_util.misc.maybe_sandbox('Skill link') | |||
local | |||
local | local m_cargo = use_sandbox and require('Module:Cargo/sandbox') or require('Module:Cargo') | ||
-- The cfg table contains all localisable strings and configuration, to make it | |||
-- easier to port this module to another wiki. | |||
local cfg = use_sandbox and mw.loadData('Module:Skill link/config/sandbox') or mw.loadData('Module:Skill link/config') | |||
local i18n = cfg.i18n | |||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
-- Helper functions | -- Helper functions | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
h = {} | local h = {} | ||
function h.disambiguate_skill(results) | function h.disambiguate_skill(results) | ||
Line 56: | Line 32: | ||
]] | ]] | ||
local str = {} | local str = {} | ||
for | for _, v in pairs(results) do | ||
str[#str+1] = string.format( | str[#str+1] = string.format( | ||
'%s - %s ([[%s|page]])', | '%s - %s ([[%s|page]])', | ||
Line 73: | Line 49: | ||
function h.format_skill_icon(skill, tpl_args) | function h.format_skill_icon(skill, tpl_args) | ||
--[[ | --[[ | ||
Add a skill image. | |||
]] | ]] | ||
if tpl_args.icon ~= nil then | if tpl_args.icon ~= nil then | ||
skill['skill.skill_icon'] = tpl_args.icon | skill['skill.skill_icon'] = tpl_args.icon | ||
Line 104: | Line 78: | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
-- | -- Main functions | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
local | local function _query_skill_infobox(tpl_args) | ||
function | |||
--[[ | --[[ | ||
Finds and shows the infobox of a skill. | Finds and shows the infobox of a skill. | ||
Line 117: | Line 89: | ||
= p.skill_infobox_link{"Icestorm"} | = p.skill_infobox_link{"Icestorm"} | ||
= p.skill_infobox_link{q_where = 'skill.active_skill_name="Icestorm"'} | = p.skill_infobox_link{q_where = 'skill.active_skill_name="Icestorm"'} | ||
]] | ]] | ||
if tpl_args.id and (tpl_args.q_where == nil) then | if tpl_args.id and (tpl_args.q_where == nil) then | ||
Line 195: | Line 160: | ||
}, | }, | ||
} | } | ||
out = {} | local out = {} | ||
local cats = {} | local cats = {} | ||
for _,v in ipairs(err_tbl) do | for _,v in ipairs(err_tbl) do | ||
Line 208: | Line 173: | ||
for _,v in ipairs(results) do | for _,v in ipairs(results) do | ||
container | container | ||
: | :addClass('skill-box-page-container') | ||
:wikitext(v['skill.html']) | :wikitext(v['skill.html']) | ||
if v['skill.skill_screenshot'] then | if v['skill.skill_screenshot'] then | ||
Line 219: | Line 184: | ||
end | end | ||
-- Store as main page: | -- Store as main page | ||
m_cargo.store( | tpl_args.main = tpl_args.main and m_util.cast.boolean(tpl_args.main) or mw.title.getCurrentTitle():inNamespace(0) | ||
if tpl_args.main then | |||
m_cargo.store( | |||
{ | |||
_table='main_pages', | |||
} | data_page = v['skill._pageName'], | ||
id = v['skill.skill_id'], | |||
name = v['skill.active_skill_name'], | |||
} | |||
) | |||
mw.getCurrentFrame():expandTemplate{title = cfg.attach_template} | |||
end | |||
end | end | ||
Line 232: | Line 202: | ||
end | end | ||
local function _skill_link(tpl_args) | |||
function | |||
--[[ | --[[ | ||
Links a skill | Links a skill | ||
Line 248: | Line 217: | ||
} | } | ||
]] | ]] | ||
tpl_args.skill_name = tpl_args.skill_name or tpl_args[1] | tpl_args.skill_name = tpl_args.skill_name or tpl_args[1] | ||
Line 259: | Line 222: | ||
-- Check if the correct parameters have been set: | -- Check if the correct parameters have been set: | ||
if m_util.table.has_all_value(tpl_args, | if m_util.table.has_all_value(tpl_args, cfg.selectors) and tpl_args.skip_query == nil then | ||
return m_util.html.error{msg=i18n.errors.invalid_args .. m_util.misc.add_category(i18n.errors.broken_skill_links)} | return m_util.html.error{ | ||
msg=i18n.errors.invalid_args .. m_util.misc.add_category(i18n.errors.broken_skill_links) | |||
} | |||
end | end | ||
-- | -- | ||
local skill | local skill | ||
if m_util.table.has_one_value(tpl_args, | if m_util.table.has_one_value(tpl_args, cfg.selectors, nil) and tpl_args.skip_query == nil then | ||
-- Create q_where depending on the input: | -- Create q_where depending on the input: | ||
if tpl_args.skill_name then | if tpl_args.skill_name then | ||
Line 284: | Line 249: | ||
{ | { | ||
'skill._pageName', | 'skill._pageName', | ||
'skill._pageNamespace', | |||
'skill.skill_id', | 'skill.skill_id', | ||
'skill.stat_text', | 'skill.stat_text', | ||
Line 305: | Line 271: | ||
-- Check number of results, there should only be one result: | -- Check number of results, there should only be one result: | ||
if #results > 1 then | if #results > 1 then | ||
return m_util.html.error{ | local found = false | ||
for _,v in ipairs(results) do | |||
-- if there is only one result in the main namespace, use that | |||
if tonumber(v['skill._pageNamespace']) == 0 then | |||
if found then | |||
found = false | |||
break | |||
else | |||
found = true | |||
skill = v | |||
end | |||
end | |||
end | |||
if not found then | |||
return m_util.html.error{ | |||
msg=string.format( | |||
i18n.errors.multiple_results, | |||
tpl_args.q_where, | |||
h.disambiguate_skill(results) .. m_util.misc.add_category(i18n.errors.broken_skill_links) | |||
) | |||
} | |||
end | |||
elseif #results < 1 then | elseif #results < 1 then | ||
return m_util.html.error{ | return m_util.html.error{ | ||
Line 319: | Line 300: | ||
) | ) | ||
} | } | ||
else | |||
skill = results[1] | |||
end | end | ||
else | else | ||
skill = { | skill = { | ||
Line 329: | Line 311: | ||
-- Add allowed parameters: | -- Add allowed parameters: | ||
for k, prop in pairs( | for k, prop in pairs(cfg.parameters) do | ||
if tpl_args[k] ~= nil then | if tpl_args[k] ~= nil then | ||
skill[prop] = tpl_args[k] | skill[prop] = tpl_args[k] | ||
Line 350: | Line 332: | ||
if tpl_args.format == nil then | if tpl_args.format == nil then | ||
local container = mw.html.create('span') | local container = mw.html.create('span') | ||
container:addClass('c- | container:addClass('hoverbox c-skill-hoverbox') | ||
if tpl_args.large then | if tpl_args.large then | ||
container:addClass('c- | container:addClass('c-skill-hoverbox--large') | ||
end | end | ||
local activator = mw.html.create('span') | local activator = mw.html.create('span') | ||
activator:addClass('c- | activator:addClass('hoverbox__activator c-skill-hoverbox__activator') | ||
if img and not tpl_args.large then | if img and not tpl_args.large then | ||
Line 371: | Line 353: | ||
local display = mw.html.create('span') | local display = mw.html.create('span') | ||
display: | display:addClass('hoverbox__display c-item-hoverbox__display') | ||
if skill['skill.html'] ~= nil then | -- TODO: Disable this until a nice solution for keeping the html table | ||
-- inline has been added: | |||
if false then -- skill['skill.html'] ~= nil then | |||
display:wikitext(skill['skill.html']) | display:wikitext(skill['skill.html']) | ||
Line 388: | Line 372: | ||
:node(activator) | :node(activator) | ||
:node(display) | :node(display) | ||
return tostring(container) | return tostring(container) | ||
Line 395: | Line 378: | ||
msg=string.format( | msg=string.format( | ||
i18n.error.invalid_format, | i18n.error.invalid_format, | ||
tpl_args.format .. m_util.misc.add_category(i18n.errors. | tpl_args.format .. m_util.misc.add_category(i18n.errors.broken_skill_links) | ||
) | ) | ||
} | } | ||
end | end | ||
end | end | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
-- | -- Exported functions | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
local p = {} | |||
-- | |||
-- [[Template:Skill link]] | |||
-- | |||
p.skill_link = m_util.misc.invoker_factory(_skill_link, { | |||
wrappers = cfg.wrappers.skill_link, | |||
}) | |||
-- | |||
-- [[Template:Query skill infobox]] | |||
-- | |||
p.query_skill_infobox = m_util.misc.invoker_factory(_query_skill_infobox, { | |||
wrappers = cfg.wrappers.query_skill_infobox, | |||
}) | |||
return p | return p |
Latest revision as of 19:21, 19 April 2025
Module for creating links to skills via cargo.
Implemented templates
- {{Skill link}}
- {{Query skill infobox}}
The above documentation is transcluded from Module:Skill link/doc.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
-------------------------------------------------------------------------------
--
-- Module:Skill link
--
-- This module implements [[Template:Skill link]] and
-- [[Template:Query skill infobox]]
-------------------------------------------------------------------------------
require('Module:No globals')
local m_util = require('Module:Util')
-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Skill link')
local m_cargo = use_sandbox and require('Module:Cargo/sandbox') or require('Module:Cargo')
-- The cfg table contains all localisable strings and configuration, to make it
-- easier to port this module to another wiki.
local cfg = use_sandbox and mw.loadData('Module:Skill link/config/sandbox') or mw.loadData('Module:Skill link/config')
local i18n = cfg.i18n
-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------
local h = {}
function h.disambiguate_skill(results)
--[[
Disambiguates results from a skill query.
]]
local str = {}
for _, v in pairs(results) do
str[#str+1] = string.format(
'%s - %s ([[%s|page]])',
v['skill.skill_id'] or v['skill._pageName'] or '',
string.gsub(
v['skill.stat_text'] or 'N/A',
'<br>',
', '
) or '',
v['skill._pageName'] or ''
)
end
return table.concat(str, '<br>')
end
function h.format_skill_icon(skill, tpl_args)
--[[
Add a skill image.
]]
if tpl_args.icon ~= nil then
skill['skill.skill_icon'] = tpl_args.icon
end
if skill['skill.skill_icon'] == nil then
return ''
end
local out
if tpl_args.large then
out = string.format(
'[[%s|link=%s]]',
skill['skill.skill_icon'],
tpl_args.main_page
)
else
-- Inline size
out = string.format(
'[[%s|14px|link=%s]]',
skill['skill.skill_icon'],
tpl_args.main_page
)
end
return out
end
-- ----------------------------------------------------------------------------
-- Main functions
-- ----------------------------------------------------------------------------
local function _query_skill_infobox(tpl_args)
--[[
Finds and shows the infobox of a skill.
Examples:
= p.skill_infobox_link{id="IcestormUniqueStaff12"}
= p.skill_infobox_link{"Icestorm"}
= p.skill_infobox_link{q_where = 'skill.active_skill_name="Icestorm"'}
]]
if tpl_args.id and (tpl_args.q_where == nil) then
tpl_args.q_where = string.format(
'skill.skill_id = "%s"',
tpl_args.id
)
elseif tpl_args[1] and (tpl_args.q_where == nil) then
tpl_args.q_where = string.format(
[[
skill.skill_id = "%s"
OR skill.active_skill_name LIKE "%%%s%%"
OR skill.stat_text LIKE "%%%s%%"
]],
tpl_args[1],
tpl_args[1],
tpl_args[1]
)
elseif (tpl_args.id == nil) and (tpl_args.q_where == nil) then
error(i18n.errors.missing_id_parameter)
end
local results = m_cargo.query(
{'skill'},
{
'skill.html',
'skill.skill_screenshot',
'skill.active_skill_name',
'skill.skill_id',
'skill.stat_text',
'skill._pageName',
},
{
where=tpl_args.q_where,
}
)
-- Helpful error handling:
local err_tbl = {
{
bool = function()
return #results == 0
end,
display = function()
return i18n.errors.no_results
end,
},
{
bool = function()
return #results > 1
end,
display = function()
return string.format(
i18n.errors.multiple_results,
tpl_args.q_where,
h.disambiguate_skill(results)
)
end,
},
{
bool = function()
return tpl_args.id == nil
end,
display = function()
return string.format(
i18n.errors.missing_id_parameter,
h.disambiguate_skill(results)
)
end,
},
}
local out = {}
local cats = {}
for _,v in ipairs(err_tbl) do
if v.bool() then
cats[#cats+1] = i18n.errors.category
out[#out+1] = m_util.html.error({msg = v.display()})
break
end
end
local container = mw.html.create('span')
for _,v in ipairs(results) do
container
:addClass('skill-box-page-container')
:wikitext(v['skill.html'])
if v['skill.skill_screenshot'] then
container
:wikitext(string.format(
'[[%s]]',
v['skill.skill_screenshot']
)
)
end
-- Store as main page
tpl_args.main = tpl_args.main and m_util.cast.boolean(tpl_args.main) or mw.title.getCurrentTitle():inNamespace(0)
if tpl_args.main then
m_cargo.store(
{
_table='main_pages',
data_page = v['skill._pageName'],
id = v['skill.skill_id'],
name = v['skill.active_skill_name'],
}
)
mw.getCurrentFrame():expandTemplate{title = cfg.attach_template}
end
end
return tostring(container) .. table.concat(out, '') .. m_util.misc.add_category(cats)
end
local function _skill_link(tpl_args)
--[[
Links a skill
Examples
--------
= p.skill_link{id="IcestormUniqueStaff12"}
= p.skill_link{
skip_query=true,
page='Skill:IcestormUniqueStaff12',
name='test',
icon='Icestorm skill icon.png',
large=1,
}
]]
tpl_args.skill_name = tpl_args.skill_name or tpl_args[1]
tpl_args.name = tpl_args.name or tpl_args[2]
-- Check if the correct parameters have been set:
if m_util.table.has_all_value(tpl_args, cfg.selectors) and tpl_args.skip_query == nil then
return m_util.html.error{
msg=i18n.errors.invalid_args .. m_util.misc.add_category(i18n.errors.broken_skill_links)
}
end
--
local skill
if m_util.table.has_one_value(tpl_args, cfg.selectors, nil) and tpl_args.skip_query == nil then
-- Create q_where depending on the input:
if tpl_args.skill_name then
tpl_args.q_where = string.format('skill.active_skill_name="%s"', tpl_args.skill_name)
elseif tpl_args.id then
tpl_args.q_where = string.format('skill.skill_id="%s"', tpl_args.id)
elseif tpl_args.q_where then
-- Use tpl_args.q_where.
else
return m_util.html.error{
msg=i18n.errors.invalid_args .. m_util.misc.add_category(i18n.errors.broken_skill_links)
}
end
-- Query cargo:
local results = m_cargo.query(
{'skill', 'main_pages'},
{
'skill._pageName',
'skill._pageNamespace',
'skill.skill_id',
'skill.stat_text',
-- 'skill.main_page',
'skill.active_skill_name',
'skill.skill_icon',
'skill.html',
'main_pages._pageName',
},
{
join='skill.skill_id=main_pages.id',
where=string.format(
'(%s)',
tpl_args.q_where
),
orderBy='skill.stat_text',
limit=2,
}
)
-- Check number of results, there should only be one result:
if #results > 1 then
local found = false
for _,v in ipairs(results) do
-- if there is only one result in the main namespace, use that
if tonumber(v['skill._pageNamespace']) == 0 then
if found then
found = false
break
else
found = true
skill = v
end
end
end
if not found then
return m_util.html.error{
msg=string.format(
i18n.errors.multiple_results,
tpl_args.q_where,
h.disambiguate_skill(results) .. m_util.misc.add_category(i18n.errors.broken_skill_links)
)
}
end
elseif #results < 1 then
return m_util.html.error{
msg=string.format(
i18n.errors.no_results_found,
tostring(tpl_args.q_where) .. m_util.misc.add_category(i18n.errors.broken_skill_links)
)
}
else
skill = results[1]
end
else
skill = {
['skill.main_page']=tpl_args.page or tpl_args.name
}
end
-- Add allowed parameters:
for k, prop in pairs(cfg.parameters) do
if tpl_args[k] ~= nil then
skill[prop] = tpl_args[k]
end
end
-- Set the link to the main page:
tpl_args.main_page = skill['skill.main_page']
or skill['main_pages._pageName']
or skill['skill._pageName']
-- Format the skill icon:
local img = h.format_skill_icon(skill, tpl_args)
---------------------------------------------------------------------------
-- Output
---------------------------------------------------------------------------
-- Normal inline link:
if tpl_args.format == nil then
local container = mw.html.create('span')
container:addClass('hoverbox c-skill-hoverbox')
if tpl_args.large then
container:addClass('c-skill-hoverbox--large')
end
local activator = mw.html.create('span')
activator:addClass('hoverbox__activator c-skill-hoverbox__activator')
if img and not tpl_args.large then
activator:wikitext(img)
end
activator:wikitext(string.format(
'[[%s|%s]]',
tpl_args.main_page,
tpl_args.name or skill['skill.active_skill_name'] or tpl_args.main_page
)
)
local display = mw.html.create('span')
display:addClass('hoverbox__display c-item-hoverbox__display')
-- TODO: Disable this until a nice solution for keeping the html table
-- inline has been added:
if false then -- skill['skill.html'] ~= nil then
display:wikitext(skill['skill.html'])
if img then
display:wikitext(img)
end
end
if img and tpl_args.large then
activator:wikitext(img)
end
container
:node(activator)
:node(display)
return tostring(container)
else
return m_util.html.error{
msg=string.format(
i18n.error.invalid_format,
tpl_args.format .. m_util.misc.add_category(i18n.errors.broken_skill_links)
)
}
end
end
-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------
local p = {}
--
-- [[Template:Skill link]]
--
p.skill_link = m_util.misc.invoker_factory(_skill_link, {
wrappers = cfg.wrappers.skill_link,
})
--
-- [[Template:Query skill infobox]]
--
p.query_skill_infobox = m_util.misc.invoker_factory(_query_skill_infobox, {
wrappers = cfg.wrappers.query_skill_infobox,
})
return p