Module:Item link

--- -- --                            Module:Item link -- -- This module implements Template:Item link. -- -- 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. ---

local getArgs = require('Module:Arguments').getArgs local m_util = require('Module:Util') local m_cargo = 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 = mw.loadData('Module:Item link/config')

local i18n = cfg.i18n

-- -- Invokable functions --

local p = {}

-- -- Template:Item link -- function p.item_link (frame) --   Creates a link to the item and displays the item info box on hover     on the link.    Examples    = p.item_link{'Multistrike'}    = p.item_link{'Multistrike Support'} -- Get arguments: local tpl_args = getArgs(frame, {       parentFirst = true,        removeBlanks = false,    }) frame = m_util.misc.get_frame(frame) 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, cfg.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, cfg.selectors, nil) and tpl_args.skip_query == nil then local tables = {'items'} local query = { groupBy='items._pageID', }       if tpl_args.metadata_id then query.where = string.format(               'items.metadata_id="%s"',                 tpl_args.metadata_id            ) elseif tpl_args.page then -- TODO returns the result even if the + format is specified. query.where = string.format(               'items._pageName="%s"',                 tpl_args.page            ) elseif tpl_args.item_name_exact then query.where = string.format(               'items.name = "%s" AND items._pageNamespace = %i',                 tpl_args.item_name_exact,                cfg.primary_namespace            ) else -- explicitly join a copy of the list child's table to the parent -- instead of using HOLDS; we have to add one table & a join condition here tables[#tables+1] = 'items__name_list' query.where = string.format(               'items__name_list._value="%s" AND items._pageNamespace = %i',                 tpl_args.item_name,                cfg.primary_namespace            ) query.join = 'items._ID = items__name_list._rowID' 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_cargo.query(           tables,            {                'items._pageName',                'items.name',                'items.inventory_icon',                'items.html',                'items.alternate_art_inventory_icons',                'items.size_x',                'items.size_y',                'items.drop_enabled',                'items.class_id',            },            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 results 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 .. m_util.misc.add_category({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(cfg.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']                ) .. m_util.misc.add_category({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']                ) .. m_util.misc.add_category({i18n.categories.broken_item_links}) }       end elseif result['items.inventory_icon'] ~= nil then img = result['items.inventory_icon'] end --   -- output --   -- Maps have their main page on the item name now, link there instead. -- Hopefully there are no maps with identical names besides the series. local linked_page if result['items.class_id'] == 'Map' and tpl_args.page == nil then linked_page = tpl_args.link or tpl_args.item_name else linked_page = tpl_args.link or result['items._pageName'] end 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(string.format('16x16px|link=|alt=', img)) end if #result['items.name'] > 0 then activator:wikitext(string.format( '%s', linked_page, result['items.name'] or result['items._pageName'] )       )    end 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*cfg.image_size,                 height*cfg.image_size,                 linked_page            ) elseif width then img = string.format(               '%spx|link=%s|alt=',                 img,                 width*cfg.image_size,                 linked_page            ) elseif height then img = string.format(               'x%spx|link=%s|alt=',                 img,                 height*cfg.image_size,                 linked_page            ) else img = string.format(               'link=%s|alt=',                 img,                 linked_page            ) end activator:wikitext(img) end

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

return p