Path of Exile Wiki

Wiki поддерживается сообществом, поэтому подумайте над тем, чтобы внести свой вклад.

ПОДРОБНЕЕ

Path of Exile Wiki
мНет описания правки
Нет описания правки
(не показано 16 промежуточных версий 2 участников)
Строка 1: Строка 1:
 
-------------------------------------------------------------------------------
-- Item link module
 
 
--
 
--
  +
-- Module:Item link
-- This is separate from the main item module for small speed ups.
 
 
--
 
--
  +
-- This module implements Template: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.
 
 
--
-- It should be noted those tests are difficult because of the large variance in page load times
 
 
-- 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')
-- Imports
 
  +
local m_cargo = require('Module:Cargo')
-- ----------------------------------------------------------------------------
 
local m_util = require('Модуль:Util')
+
local m_item_util = require('Module:Item util')
local getArgs = require('Модуль:Arguments').getArgs
 
   
  +
-- Should we use the sandbox version of our submodules?
-- ----------------------------------------------------------------------------
 
  +
local use_sandbox = m_util.misc.maybe_sandbox('Item link')
-- 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 или item_name_exact',
 
no_results = 'Item link: Не найдено результатов для параметра поиска "%s".',
 
too_many_results = 'Item link: Слишком много результатов для параметра поиска "%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
-- ----------------------------------------------------------------------------
 
  +
-- easier to port this module to another wiki.
-- Constants & Data
 
  +
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 = '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'}
 
   
 
-- ----------------------------------------------------------------------------
 
-- ----------------------------------------------------------------------------
  +
-- Exported functions
-- Invokable code
 
 
-- ----------------------------------------------------------------------------
 
-- ----------------------------------------------------------------------------
  +
 
local p = {}
   
 
--
 
--
 
-- Template:Item link
 
-- Template:Item link
 
--
 
--
local p = {}
 
 
 
function p.item_link (frame)
 
function p.item_link (frame)
 
--[[
 
--[[
Строка 80: Строка 54:
 
frame = m_util.misc.get_frame(frame)
 
frame = m_util.misc.get_frame(frame)
 
 
-- Backwards compability
 
 
tpl_args.item_name = tpl_args.item_name or tpl_args[1]
 
tpl_args.item_name = tpl_args.item_name or tpl_args[1]
 
tpl_args.name = tpl_args.name or tpl_args[2]
 
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
+
if m_util.table.has_all_value(tpl_args, cfg.selectors) and tpl_args.skip_query == nil then
 
error(i18n.errors.invalid_args)
 
error(i18n.errors.invalid_args)
 
end
 
end
Строка 93: Строка 66:
 
local result
 
local result
 
 
if m_util.table.has_one_value(tpl_args, c.selectors, nil) and tpl_args.skip_query == nil then
+
if m_util.table.has_one_value(tpl_args, cfg.selectors, nil) and tpl_args.skip_query == nil then
 
local tables = {'items'}
 
local fields = {
 
'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',
 
}
 
local query = {
 
local query = {
 
groupBy='items._pageID',
 
groupBy='items._pageID',
 
}
 
}
+
if tpl_args.metadata_id then
if tpl_args.page ~= nil then
+
query.where = string.format(
 
'items.metadata_id="%s"',
-- TODO returns the result even if the + format is specified.
 
query.where = string.format('items._pageName="%s"', tpl_args.page)
+
tpl_args.metadata_id
 
)
 
elseif tpl_args.page then
  +
-- Join with _pageData in order to check for page redirect
  +
tables[#tables+1] = '_pageData'
  +
fields[#fields+1] = '_pageData._pageNameOrRedirect'
  +
query.where = string.format(
 
'_pageData._pageName="%s"',
 
tpl_args.page
 
)
  +
query.join = 'items._pageName = _pageData._pageNameOrRedirect'
 
elseif tpl_args.item_name_exact then
  +
query.where = string.format(
  +
'items.name = "%s" AND items._pageNamespace IN (%s)',
  +
m_cargo.addslashes(tpl_args.item_name_exact),
  +
m_item_util.get_item_namespaces{format = 'list'}
 
)
 
else
 
else
  +
-- Explicitly join name_list child table instead of using HOLDS
if tpl_args.item_name ~= nil then
 
  +
tables[#tables+1] = 'items__name_list'
-- HOLDS is unreliable, using __FULL and REGEXP instead:
 
query.where = string.format('items.name_list__FULL REGEXP "(�|^)%s(�|$)"', tpl_args.item_name)
+
query.where = string.format(
  +
'items__name_list._value="%s" AND items._pageNamespace IN (%s)',
elseif tpl_args.item_name_exact ~= nil then
 
query.where = string.format('items.name = "%s"', tpl_args.item_name_exact)
+
m_cargo.addslashes(tpl_args.item_name),
  +
m_item_util.get_item_namespaces{format = 'list'}
end
 
 
)
  +
query.join = 'items._ID = items__name_list._rowID'
 
end
 
end
 
 
if tpl_args.link_type == 'skill' then
+
result = m_cargo.query(
 
tables,
query.where = string.format('%s AND (items.class = "Active Skill Gems" OR items.class = "Support Skill Gems")', query.where)
 
end
+
fields,
 
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
 
query
 
)
 
)
Строка 134: Строка 122:
 
local j = 1
 
local j = 1
 
if #result == 0 then
 
if #result == 0 then
err = m_util.misc.raise_error_or_return{raise_required=true, args=tpl_args, msg=string.format(
+
err = m_util.misc.raise_error_or_return{
i18n.errors.no_results,
+
raise_required=true,
tpl_args.page or tpl_args.item_name or tpl_args.item_name_exact
+
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
 
elseif #result > 1 then
 
-- If only one of the results is drop enabled then use that one:
 
-- If only one of the results is drop enabled then use that one:
Строка 149: Строка 141:
 
 
 
if n ~= 1 then
 
if n ~= 1 then
err = m_util.misc.raise_error_or_return{raise_required=true, args=tpl_args, msg=string.format(
+
err = m_util.misc.raise_error_or_return{
i18n.errors.too_many_results,
+
raise_required=true,
tpl_args.page or tpl_args.item_name or tpl_args.item_name_exact
+
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
 
end
 
end
 
 
 
if err ~= nil then
 
if err ~= nil then
return err .. i18n.categories.broken_item_links
+
return err .. m_util.misc.add_category({i18n.categories.broken_item_links})
 
end
 
end
 
 
Строка 167: Строка 163:
 
end
 
end
 
 
for k, prop in pairs(c.parameters) do
+
for k, prop in pairs(cfg.parameters) do
 
if tpl_args[k] ~= nil then
 
if tpl_args[k] ~= nil then
 
result[prop] = tpl_args[k]
 
result[prop] = tpl_args[k]
Строка 175: Строка 171:
 
if tpl_args.image ~= nil then
 
if tpl_args.image ~= nil then
 
if result['items.alternate_art_inventory_icons'] == 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(
+
return m_util.misc.raise_error_or_return{
i18n.errors.alt_art_undefined,
+
raise_required=true,
result['items._pageName']
+
args=tpl_args,
) .. i18n.categories.broken_item_links}
+
msg=string.format(
  +
i18n.errors.alt_art_undefined,
  +
result['items._pageName']
  +
) .. m_util.misc.add_category({i18n.categories.broken_item_links})
  +
}
 
end
 
end
 
 
result['items.alternate_art_inventory_icons'] = m_util.string.split(result['items.alternate_art_inventory_icons'], ',%s*')
+
result['items.alternate_art_inventory_icons'] = m_util.string.split(
  +
result['items.alternate_art_inventory_icons'],
  +
',%s*'
  +
)
 
 
 
local index = tonumber(tpl_args.image)
 
local index = tonumber(tpl_args.image)
Строка 201: Строка 204:
 
 
 
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(
+
return m_util.misc.raise_error_or_return{
i18n.errors.alt_art_invalid_index,
+
raise_required=true,
tpl_args.image, result['items._pageName']
+
args=tpl_args,
) .. i18n.categories.broken_item_links}
+
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
 
end
 
elseif result['items.inventory_icon'] ~= nil then
 
elseif result['items.inventory_icon'] ~= nil then
Строка 210: Строка 217:
 
end
 
end
 
 
 
--
 
-- output
 
-- 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')
 
local container = mw.html.create('span')
 
container:addClass('c-item-hoverbox')
 
container:addClass('c-item-hoverbox')
  +
  +
if tpl_args.large then
  +
container:addClass('c-item-hoverbox--large')
  +
end
 
 
 
local activator = mw.html.create('span')
 
local activator = mw.html.create('span')
Строка 221: Строка 243:
 
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['items._pageName'], result['items.name'] or result['items._pageName']))
+
if #result['items.name'] > 0 then
  +
activator:wikitext(string.format(
  +
'[[%s|%s]]',
  +
linked_page,
  +
result['items.name'] or result['items._pageName']
  +
)
  +
)
  +
end
 
 
 
local display = mw.html.create('span')
 
local display = mw.html.create('span')
Строка 239: Строка 268:
 
local height = tonumber(result['items.size_y']) or tonumber(tpl_args.height)
 
local height = tonumber(result['items.size_y']) or tonumber(tpl_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['items._pageName'])
+
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['items._pageName'])
+
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['items._pageName'])
+
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['items._pageName'])
+
img = string.format(
  +
'[[%s|link=%s|alt=]]',
  +
img,
  +
linked_page
  +
)
 
end
 
end
 
activator:wikitext(img)
 
activator:wikitext(img)

Версия от 19:39, 7 ноября 2021

Template info icon Документация модуля[просмотр] [править] [история] [очистить]

Модуль предоставляет функциональные возможности для ссылок на предметы.

Описание

Этот модуль отвечает за {{Item link}} (({{Il}}), которые создают ссылки на предметы с помощью cargo через Модуль:Item2.

Шаблоны Item

Модуль:Item2

Все шаблоны, определенные в Модуль:Item2:

Модуль:Item table

Все шаблоны, определенные в Модуль:Item table:

Модуль:Item link

Все шаблоны, определенные в Модуль:Item link:

Модуль:Item acquisition

-------------------------------------------------------------------------------
-- 
--                             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')
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

-- ----------------------------------------------------------------------------
-- Exported 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 fields = {
            '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',
        }
        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
            -- Join with _pageData in order to check for page redirect
            tables[#tables+1] = '_pageData'
            fields[#fields+1] = '_pageData._pageNameOrRedirect'
            query.where = string.format(
                '_pageData._pageName="%s"',
                tpl_args.page
            )
            query.join = 'items._pageName = _pageData._pageNameOrRedirect'
        elseif tpl_args.item_name_exact then
            query.where = string.format(
                'items.name = "%s" AND items._pageNamespace IN (%s)',
                m_cargo.addslashes(tpl_args.item_name_exact),
                m_item_util.get_item_namespaces{format = 'list'}
            )
        else
            -- Explicitly join name_list child table instead of using HOLDS
            tables[#tables+1] = 'items__name_list'
            query.where = string.format(
                'items__name_list._value="%s" AND items._pageNamespace IN (%s)',
                m_cargo.addslashes(tpl_args.item_name),
                m_item_util.get_item_namespaces{format = 'list'}
            )
            query.join = 'items._ID = items__name_list._rowID'
        end
        
        result = m_cargo.query(
            tables,
            fields,
            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('[[%s|16x16px|link=|alt=]]', img))
    end
    
    if #result['items.name'] > 0 then
        activator:wikitext(string.format(
            '[[%s|%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('[[%s|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(
                '[[%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

return p