Module:Item link: Difference between revisions

From Path of Exile 2 Wiki
Jump to navigation Jump to search
>OmegaK2
(Moved here from Module:Item2)
 
m (46 revisions imported)
 
(45 intermediate revisions by 5 users not shown)
Line 1: Line 1:
-- Item link module
-------------------------------------------------------------------------------
--  
--  
-- This is separate from the main item module for small speed ups.
--                             Module:Item link
--  
--  
-- 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.
-- This module implements Template:Item link.
-- It should be noted those tests are difficult because of the large variance in page load times
-------------------------------------------------------------------------------


-- ----------------------------------------------------------------------------
require('Module:No globals')
-- Imports
-- ----------------------------------------------------------------------------
local m_util = require('Module:Util')
local m_util = require('Module:Util')
local getArgs = require('Module:Arguments').getArgs
local m_item_util = require('Module:Item util')


-- ----------------------------------------------------------------------------
-- Should we use the sandbox version of our submodules?
-- Strings
local use_sandbox = m_util.misc.maybe_sandbox('Item link')
-- ----------------------------------------------------------------------------
-- 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 = '[[Category:Pages with 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"',
    },
}


-- ----------------------------------------------------------------------------
-- The cfg table contains all localisable strings and configuration, to make it
-- Constants & Data
-- 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 c = {}
local i18n = cfg.i18n
c.image_size = 39
c.image_size_full = c.image_size * 2
c.parameters = {
    name = 'Has name',
    inventory_icon = 'Has inventory icon',
    html = 'Has infobox HTML',
}
c.selectors = {'page', 'item_name', 'item_name_exact'}


-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
-- Invokable code
-- Main functions
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------


--
local function _main(args)
-- Template:Item link & Template:Sl
     --[[
--
     Creates a link to the item and displays the item info box on hover
 
     on the link.
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]
     if tpl_args.item_name ~= nil then
        tpl_args.item_name = mw.ustring.lower(tpl_args.item_name)
     end
    tpl_args.name = tpl_args.name or tpl_args[2]
      
      
     if m_util.table.has_all_value(tpl_args, c.selectors) then
     Examples
        error(i18n.errors.invalid_args)
    --------
     end
    = p.item_link{'Multistrike'}
    = p.item_link{'Multistrike Support'}
     --]]
      
      
     tpl_args.large = m_util.cast.boolean(tpl_args.large)
     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 img
     local result
     local result
      
     local linked_page
     if m_util.table.has_one_value(tpl_args, c.selectors, nil) or tpl_args.item_name ~= nil then
     if m_util.cast.boolean(args.skip_query) then
         local query = {}
        result = {
          
            _pageName = args.page or args.name
         if tpl_args.page ~= nil then
        }
             -- TODO returns the result even if the + format is specified.  
        linked_page = args.link or result._pageName
             query[#query+1] = string.format('[[%s]]', tpl_args.page)
    else
        else
         local qargs = {}
             if tpl_args.item_name ~= nil then
         qargs.tables = {'main_pages'}
                query[#query+1] = string.format('[[Has lowercase names::%s]]', tpl_args.item_name)
        qargs.join = 'items._pageName = main_pages.data_page'
             elseif tpl_args.item_name_exact ~= nil then
         qargs.fields = {
                query[#query+1] = string.format('[[Has name::%s]]', tpl_args.item_name_exact)
             'items.name=name',
             end
             'items.inventory_icon=inventory_icon',
           
             'items.html=html',
            query[#query] = query[#query] .. ' [[Has inventory icon::+]] [[Has infobox HTML::+]]'
            'items.alternate_art_inventory_icons=alternate_art_inventory_icons',
           
             'items.size_x=size_x',
             if tpl_args.link_type == 'skill' then
            'items.size_y=size_y',
                 query[#query] = query[#query] .. ' [[Concept:Skill gems]]'
             'main_pages._pageName=main_page',
        }
        result = m_item_util.query_item(args, qargs)
        if result.error then
             if not m_util.cast.boolean(args.nocat) then
                 return result.error:get_html() .. m_util.misc.add_category({i18n.categories.broken_item_links})
             end
             end
            return result.error:get_html()
         end
         end
       
 
        query[#query+1] = '?Has name'
         -- If specifying an item by name, link to the main page; otherwise, link to where the item data lives.
        query[#query+1] = '?Has inventory icon'
         if result.main_page and m_util.table.has_any_key(args, {'item_name', 'item_name_exact'}) then
        query[#query+1] = '?Has infobox HTML'
             linked_page = result.main_page
        query[#query+1] = '?Has alternate inventory icons'
        else
        query[#query+1] = '?Has inventory width'
             linked_page = result._pageName
        query[#query+1] = '?Has inventory height'
       
         -- attributes
        result = m_util.smw.query(query, frame)
       
        local err
         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
             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
       
        if err ~= nil then
            return err .. i18n.categories.broken_item_links
         end
         end
       
        result = result[1]
    else
        result = {tpl_args.page or tpl_args.item_name_exact}
     end
     end
      
      
     for k, prop in pairs(c.parameters) do
    -- Overrides from template parameters
         if tpl_args[k] ~= nil then
     for k, prop in pairs(cfg.parameters) do
             result[prop] = tpl_args[k]
         if args[k] ~= nil then
             result[prop] = args[k]
         end
         end
     end
     end
      
      
     if tpl_args.image ~= nil then
     if args.image ~= nil then
         if result['Has alternate inventory icons'] == '' then
         if result.alternate_art_inventory_icons == nil then
             return m_util.misc.raise_error_or_return{raise_required=true, args=tpl_args, msg=string.format(
             local err = m_util.Error{
                i18n.errors.alt_art_undefined,
                message = string.format(
                result[1]
                    i18n.errors.alt_art_undefined,
            ) .. i18n.categories.broken_item_links}
                    result._pageName
                ),
                code = 'alt_art_undefined',
                issue = args.issue_all_errors or false,
                category = i18n.categories.broken_item_links,
            }:throw()
            return err:get_html() .. err:get_category()
         end
         end
          
          
         result['Has alternate inventory icons'] = m_util.string.split(result['Has alternate inventory icons'], '<MANY>')
         result.alternate_art_inventory_icons = m_util.string.split(
            result.alternate_art_inventory_icons,
            ',%s*'
        )
          
          
         local index = tonumber(tpl_args.image)
         local index = tonumber(args.image)
         if index ~= nil then
         if index ~= nil then
             img = result['Has alternate inventory icons'][index]
             img = result.alternate_art_inventory_icons[index]
         else
         else
             -- offset 1 is needed
             -- offset 1 is needed
             local suffix = string.len(' inventory icon.png') + 1  
             local suffix = string.len(' inventory icon.png') + 1  
             -- add an extra offset by 1 to account for the space  
             -- add an extra offset by 1 to account for the space  
             local prefix = string.len(string.sub(result['Has inventory icon'], 1, -suffix)) + 2
             local prefix = string.len(string.sub(result.inventory_icon, 1, -suffix)) + 2
              
              
             for _, filename in ipairs(result['Has alternate inventory icons']) do
             for _, filename in ipairs(result.alternate_art_inventory_icons) do
                 if string.sub(filename, prefix, -suffix) == tpl_args.image then
                 if string.sub(filename, prefix, -suffix) == args.image then
                     img = filename
                     img = filename
                     break
                     break
Line 172: Line 119:
          
          
         if img == nil then
         if img == nil then
             return m_util.misc.raise_error_or_return{raise_required=true, args=tpl_args, msg=string.format(
             local err = m_util.Error{
                i18n.errors.alt_art_invalid_index,
                message = string.format(
                tpl_args.image, result[1]
                    i18n.errors.alt_art_invalid_index,
            ) .. i18n.categories.broken_item_links}
                    args.image,
                    result._pageName
                ),
                code = 'alt_art_invalid_index',
                issue = args.issue_all_errors or false,
                category = i18n.categories.broken_item_links,
            }:throw()
            return err:get_html() .. err:get_category()
         end
         end
     elseif result['Has inventory icon'] ~= '' then
     elseif result.inventory_icon ~= nil then
         img = result['Has inventory icon']
         img = result.inventory_icon
     end
     end
      
      
    --
     -- output
     -- output
    --
      
      
     local container = mw.html.create('span')
     local container = mw.html.create('span')
     container:addClass('c-item-hoverbox')
     container:addClass('c-item-hoverbox')
    if args.large then
        container:addClass('c-item-hoverbox--large')
    end
      
      
     local activator = mw.html.create('span')
     local activator = mw.html.create('span')
     activator:addClass('c-item-hoverbox__activator')
     activator:addClass('c-item-hoverbox__activator')


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


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


     if tpl_args.large then
     if img and args.large then
         local width = tonumber(result['Has inventory width']) or tonumber(tpl_args.width)
         local width = tonumber(result.size_x) or tonumber(args.width)
         local height = tonumber(result['Has inventory height']) or tonumber(tpl_args.height)
         local height = tonumber(result.size_y) or tonumber(args.height)
         if width and height then
         if width and height then
             img = string.format('<br>[[%s|%sx%spx|link=%s|alt=]]', img, width*c.image_size, height*c.image_size, result[1])
             img = string.format(
                '[[%s|%sx%spx|link=%s|alt=]]',  
                img,  
                width*cfg.image_size,  
                height*cfg.image_size,  
                linked_page
            )
         elseif width then
         elseif width then
             img = string.format('<br>[[%s|%spx|link=%s|alt=]]', img, width*c.image_size, result[1])
             img = string.format(
                '[[%s|%spx|link=%s|alt=]]',  
                img,  
                width*cfg.image_size,  
                linked_page
            )
         elseif height then
         elseif height then
             img = string.format('<br>[[%s|x%spx|link=%s|alt=]]', img, height*c.image_size, result[1])
             img = string.format(
                '[[%s|x%spx|link=%s|alt=]]',  
                img,  
                height*cfg.image_size,  
                linked_page
            )
         else
         else
             img = string.format('<br>[[%s|link=%s|alt=]]', img, result[1])
             img = string.format(
                '[[%s|link=%s|alt=]]',  
                img,  
                linked_page
            )
         end
         end
         activator:wikitext(img)
         activator:wikitext(img)
Line 227: Line 215:
     return tostring(container)
     return tostring(container)
end
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
return p

Latest revision as of 16:46, 25 September 2024

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
    local linked_page
    if m_util.cast.boolean(args.skip_query) then
        result = {
            _pageName = args.page or args.name
        }
        linked_page = args.link or result._pageName
    else
        local qargs = {}
        qargs.tables = {'main_pages'}
        qargs.join = 'items._pageName = main_pages.data_page'
        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',
            'main_pages._pageName=main_page',
        }
        result = m_item_util.query_item(args, qargs)
        if result.error then
            if not m_util.cast.boolean(args.nocat) then
                return result.error:get_html() .. m_util.misc.add_category({i18n.categories.broken_item_links})
            end
            return result.error:get_html()
        end

        -- If specifying an item by name, link to the main page; otherwise, link to where the item data lives.
        if result.main_page and m_util.table.has_any_key(args, {'item_name', 'item_name_exact'}) then
            linked_page = result.main_page
        else
            linked_page = result._pageName
        end
    end
    
    -- Overrides from template parameters
    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
            local err = m_util.Error{
                message = string.format(
                    i18n.errors.alt_art_undefined,
                    result._pageName
                ),
                code = 'alt_art_undefined',
                issue = args.issue_all_errors or false,
                category = i18n.categories.broken_item_links,
            }:throw()
            return err:get_html() .. err:get_category()
        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
            local err = m_util.Error{
                message = string.format(
                    i18n.errors.alt_art_invalid_index,
                    args.image,
                    result._pageName
                ),
                code = 'alt_art_invalid_index',
                issue = args.issue_all_errors or false,
                category = i18n.categories.broken_item_links,
            }:throw()
            return err:get_html() .. err:get_category()
        end
    elseif result.inventory_icon ~= nil then
        img = result.inventory_icon
    end
    
    --
    -- output
    --
    
    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