Module:Skill link

-- -- Module for skill linking --

local m_util = require('Module:Util') local getArgs = require('Module:Arguments').getArgs local m_cargo = require('Module:cargo')

local p = {}

-- -- Strings --

local i18n = { errors = { missing_id_parameter = 'id parameter must be specified, please choose only one of these ids: %s', multiple_results = 'Too many skills found with q_where = %s. Please choose only one of the following ids: %s', no_results = 'No results found.', category = 'Pages with skill infobox errors',

-- Skill link: invalid_args = 'id, page or name must be specified', no_results_found = 'No skills found with q_where = %s', invalid_format = 'Invalid return format specified: %s', broken_skill_links = 'Pages with broken skill links', }, }

-- -- Constants & Data --

local c = {} -- c.image_size = 39 -- c.image_size_full = c.image_size * 2 c.parameters = { name = 'skill.active_skill_name', icon = 'skill.icon', html = 'skill.html', }

c.selectors = {'id', 'page', 'skill_name'}

-- -- Helper functions and globals --

h = {}

function h.disambiguate_skill(results) --       Disambiguates results from a skill query. local str = {} for i,v in pairs(results) do       str[#str+1] = string.format(            '%s - %s (page)',            v['skill.skill_id'] or v['skill._pageName'] or '',            string.gsub( v['skill.stat_text'] or 'N/A', ' ',               ', '            ) or ,            v['skill._pageName'] or         ) end return table.concat(str, ' ') 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(           'link=%s',            skill['skill.skill_icon'],            tpl_args.main_page        ) else -- Inline size out = string.format(           '14px|link=%s',            skill['skill.skill_icon'],            tpl_args.main_page        ) end return out end

-- -- Page functions --

local p = {}

function p.skill_infobox_link(frame) --[[   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"'}

]]

-- Get args tpl_args = getArgs(frame, {       parentFirst = true    }) frame = m_util.misc.get_frame(frame)

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, },   }    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 :attr('class', '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: m_cargo.store(           frame,            {                _table='main_pages',                id=v['skill.skill_id'],            }        ) end

return tostring(container) .. table.concat(out, '') .. m_util.misc.add_category(cats) end

function p.skill_link(frame) --[[   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, }   ]]

-- Get args local tpl_args = getArgs(frame, {       parentFirst = true    }) frame = m_util.misc.get_frame(frame)

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, c.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, c.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.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 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)                    ) }       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)                ) }       end

skill = results[1] else skill = { ['skill.main_page']=tpl_args.page or tpl_args.name }   end

-- Add allowed parameters: for k, prop in pairs(c.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('c-item-hoverbox')

if tpl_args.large then container:addClass('c-item-hoverbox--large') end

local activator = mw.html.create('span') activator:addClass('c-item-hoverbox__activator')

if img and not tpl_args.large then activator:wikitext(img) end

activator:wikitext(string.format( '%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:attr('class', '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) :done

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 -- -- End --

return p