Module:Sandbox/Illviljan/Item link

-- Item link module -- -- This is separate from the main item module for small speed ups. -- -- Those speed ups are only sigificant if the module is called a lot of times (100+), in tests this amounted to only a ~10% difference in page load times at best. -- It should be noted those tests are difficult because of the large variance in page load times

-- -- Imports -- local m_util = require('Module:Util') local getArgs = require('Module:Arguments').getArgs

-- -- Strings -- -- This section contains strings used by this module. -- Add new strings here instead of in-code directly, this will help other -- people to correct spelling mistakes easier and help with translation to -- other PoE wikis. -- -- TODO: Maybe move this out to a separate sub-page module local i18n = { categories = { -- maintenance cats broken_item_links = '', },   errors = { invalid_args = 'Item link: page, item_name or item_name_exact must be specified', no_results = 'Item link: No results found for search parameter "%s".', too_many_results = 'Item link: Too many results for search parameter "%s". Consider using page parameter instead.', alt_art_undefined = 'Item link: Image parameter was specified, but there is no alternate art defined on page "%s"', alt_art_invalid_index = 'Item Link: Alternate art with index/name "%s" not found on page "%s"', }, }

-- -- Constants & Data --

local c = {} c.image_size = 39 c.image_size_full = c.image_size * 2 c.parameters = { name = 'items.name', inventory_icon = 'items.inventory_icon', html = 'items.html', width = 'items.size_x', height = 'items.size_y', }

c.selectors = {'page', 'item_name', 'item_name_exact'}

-- -- Invokable code --

-- -- Template:Item link & Template:Sl -- local p = {}

function p.item_link (frame) --   -- Args/Frame --   local tpl_args = getArgs(frame, {        parentFirst = true,        removeBlanks = false,    }) frame = m_util.misc.get_frame(frame) -- Backwards compability tpl_args.item_name = tpl_args.item_name or tpl_args[1] tpl_args.name = tpl_args.name or tpl_args[2] if m_util.table.has_all_value(tpl_args, c.selectors) and tpl_args.skip_query == nil then error(i18n.errors.invalid_args) end tpl_args.large = m_util.cast.boolean(tpl_args.large) local img local result if m_util.table.has_one_value(tpl_args, c.selectors, nil) and tpl_args.skip_query == nil then local query = { groupBy='items._pageID', }       if tpl_args.page ~= nil then -- TODO returns the result even if the + format is specified. query.where = string.format('items._pageName="%s"', tpl_args.page) else if tpl_args.item_name ~= nil then query.where = string.format('items.name_list HOLDS "%s"', tpl_args.item_name) elseif tpl_args.item_name_exact ~= nil then query.where = string.format('items.name = "%s"', tpl_args.item_name_exact) end end if tpl_args.link_type == 'skill' then query.where = string.format('%s AND (items.class = "Active Skill Gems" OR items.class = "Support Skill Gems")', query.where) end result = m_util.cargo.query(           {                'items'            },            {                'items._pageName',                'items.name',                'items.inventory_icon',                'items.html',                'items.alternate_art_inventory_icons',                'items.size_x',                'items.size_y',                'items.drop_enabled',            },            query        ) local err local j = 1 if #result == 0 then err = m_util.misc.raise_error_or_return{raise_required=true, args=tpl_args, msg=string.format(               i18n.errors.no_results,                 tpl_args.page or tpl_args.item_name or tpl_args.item_name_exact             )} elseif #result > 1 then -- If only one of the result is drop enabled then use that one: local n = 0 for i,v in ipairs(result) do                if m_util.cast.boolean(v['items.drop_enabled']) then j = i                   n = n+1 end end if n ~= 1 then err = m_util.misc.raise_error_or_return{raise_required=true, args=tpl_args, msg=string.format(                   i18n.errors.too_many_results,                    tpl_args.page or tpl_args.item_name or tpl_args.item_name_exact                )} end end if err ~= nil then return err .. i18n.categories.broken_item_links end result = result[j] else result = { ['items._pageName'] = tpl_args.page or tpl_args.name }   end for k, prop in pairs(c.parameters) do       if tpl_args[k] ~= nil then result[prop] = tpl_args[k] end end if tpl_args.image ~= nil then if result['items.alternate_art_inventory_icons'] == nil then return m_util.misc.raise_error_or_return{raise_required=true, args=tpl_args, msg=string.format(               i18n.errors.alt_art_undefined,                result['items._pageName']            ) .. i18n.categories.broken_item_links} end result['items.alternate_art_inventory_icons'] = m_util.string.split(result['items.alternate_art_inventory_icons'], ',%s*') local index = tonumber(tpl_args.image) if index ~= nil then img = result['items.alternate_art_inventory_icons'][index] else -- offset 1 is needed local suffix = string.len(' inventory icon.png') + 1 -- add an extra offset by 1 to account for the space local prefix = string.len(string.sub(result['items.inventory_icon'], 1, -suffix)) + 2 for _, filename in ipairs(result['items.alternate_art_inventory_icons']) do               if string.sub(filename, prefix, -suffix) == tpl_args.image then img = filename break end end end if img == nil then return m_util.misc.raise_error_or_return{raise_required=true, args=tpl_args, msg=string.format(                i18n.errors.alt_art_invalid_index,                tpl_args.image, result['items._pageName']            ) .. i18n.categories.broken_item_links} end elseif result['items.inventory_icon'] ~= nil then img = result['items.inventory_icon'] end -- output local container = mw.html.create('span') container:addClass('c-item-hoverbox') local activator = mw.html.create('span') activator:addClass('c-item-hoverbox__activator')

if img and not tpl_args.large then activator:wikitext(string.format('16x16px|link=|alt=', img)) end activator:wikitext(string.format('%s', result['items._pageName'], result['items.name'] or result['items._pageName'])) local display = mw.html.create('span') display:attr('class', 'c-item-hoverbox__display')

if result['items.html'] ~= nil then display:wikitext(result['items.html']) if img then display:wikitext(string.format('link=|alt=', img)) end end

if img and tpl_args.large then local width = tonumber(result['items.size_x']) or tonumber(tpl_args.width) local height = tonumber(result['items.size_y']) or tonumber(tpl_args.height) if width and height then img = string.format(' %sx%spx|link=%s|alt=', img, width*c.image_size, height*c.image_size, result['items._pageName']) elseif width then img = string.format(' %spx|link=%s|alt=', img, width*c.image_size, result['items._pageName']) elseif height then img = string.format(' x%spx|link=%s|alt=', img, height*c.image_size, result['items._pageName']) else img = string.format(' link=%s|alt=', img, result['items._pageName']) end activator:wikitext(img) end

container :node(activator) :node(display) :done return tostring(container) end

return p