Module:Item link

From Path of Exile 2 Wiki
Revision as of 14:43, 19 January 2022 by Vinifera7 (talk | contribs)
Jump to navigation Jump to search
Module documentation[view] [edit] [history] [purge]


Lua logo

This module depends on the following other modules:

This module implements {{item link}} and facilitates the creation of item links.

-------------------------------------------------------------------------------
-- 
--                             Module:Item link
-- 
-- This module implements Template:Item link.
-------------------------------------------------------------------------------

require('Module:No globals')
local m_util = require('Module:Util')
local m_item_util = require('Module:Item util')

-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Item link')

-- 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:Item link/config/sandbox') or mw.loadData('Module:Item link/config')

local i18n = cfg.i18n

-- ----------------------------------------------------------------------------
-- Main functions
-- ----------------------------------------------------------------------------

local function _main(args)
    --[[
    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'}
    --]]
    
    args.item_name = args.item_name or args[1]
    args.name = args.name or args[2]
    args.large = m_util.cast.boolean(args.large)
    
    local img
    local result
    if args.skip_query == nil then
        local qargs = {}
        qargs.fields = {
            'items.name=name',
            'items.inventory_icon=inventory_icon',
            'items.html=html',
            'items.alternate_art_inventory_icons=alternate_art_inventory_icons',
            'items.size_x=size_x',
            'items.size_y=size_y',
        }
        args.error_category = i18n.categories.broken_item_links
        result = m_item_util.query_item(args, qargs)
        if result.error then
            return result.error
        end
    else
        result = {
            ['_pageName'] = args.page or args.name
        }
    end
    
    for k, prop in pairs(cfg.parameters) do
        if args[k] ~= nil then
            result[prop] = args[k]
        end
    end
    
    if args.image ~= nil then
        if result['alternate_art_inventory_icons'] == nil then
            return m_util.misc.raise_error_or_return{
                raise_required = true, 
                args = args, 
                msg = string.format(
                    i18n.errors.alt_art_undefined,
                    result['_pageName']
                ) .. m_util.misc.add_category({i18n.categories.broken_item_links})
            }
        end
        
        result['alternate_art_inventory_icons'] = m_util.string.split(
            result['alternate_art_inventory_icons'], 
            ',%s*'
        )
        
        local index = tonumber(args.image)
        if index ~= nil then
            img = result['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['inventory_icon'], 1, -suffix)) + 2
            
            for _, filename in ipairs(result['alternate_art_inventory_icons']) do
                if string.sub(filename, prefix, -suffix) == 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 = args, 
                msg = string.format(
                    i18n.errors.alt_art_invalid_index,
                    args.image, result['_pageName']
                ) .. m_util.misc.add_category({i18n.categories.broken_item_links})
            }
        end
    elseif result['inventory_icon'] ~= nil then
        img = result['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 = args.link
    if result['class_id'] == 'Map' and m_util.table.has_any_key(args, {'item_name', 'item_name_exact'}) then
        linked_page = linked_page or args.item_name_exact or args.item_name
    else
        linked_page = linked_page or result['_pageName']
    end
    
    local container = mw.html.create('span')
    container:addClass('c-item-hoverbox')

    if 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 args.large then
        activator:wikitext(string.format('[[%s|16x16px|link=|alt=]]', img))
    end
    
    if #result['name'] > 0 then
        activator:wikitext(string.format(
            '[[%s|%s]]', 
            linked_page, 
            result['name'] or result['_pageName']
            )
        )
    end
    
    local display = mw.html.create('span')
    display:attr('class', 'c-item-hoverbox__display')

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

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

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

-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------

local p = {}

-- 
-- Template:Item link
-- 
p.main = m_util.misc.invoker_factory(_main, {
    parentFirst = true,
    removeBlanks = false,
})

p.item_link = p.main

return p