Нет описания правки |
Нет описания правки |
||
Строка 23: | Строка 23: | ||
local m = {} |
local m = {} |
||
+ | |||
+ | function m.format_value(tpl_args, value, options) |
||
+ | -- value: table |
||
+ | -- min: |
||
+ | -- max: |
||
+ | -- options: table |
||
+ | -- func: Function to transform the value retrieved from the database |
||
+ | -- fmt: Format string (or function that returns format string) to use for the value. Default: '%s' |
||
+ | -- fmt_range: Format string to use for the value range. Default: '(%s-%s)' |
||
+ | -- color: poe_color code to use for the value range. False for no color. Default: 'mod' |
||
+ | -- class: Additional css class added to color tag |
||
+ | -- inline: Format string to use for the output |
||
+ | -- inline_color: poe_color code to use for the output. False for no color. Default: 'default' |
||
+ | -- inline_class: Additional css class added to inline color tag |
||
+ | -- no_color: (Deprecated; use color=false instead) |
||
+ | -- return_color: (Deprecated; returns both value.out and value without this) |
||
+ | if options.color ~= false and options.no_color == nil then |
||
+ | local base = { |
||
+ | min = value.base_min or value.base, |
||
+ | max = value.base_max or value.base, |
||
+ | } |
||
+ | if options.color then |
||
+ | value.color = options.color |
||
+ | elseif value.min ~= base.min or value.max ~= base.max then |
||
+ | value.color = 'mod' |
||
+ | else |
||
+ | value.color = 'value' |
||
+ | end |
||
+ | end |
||
+ | if options.func then |
||
+ | value.min = options.func(tpl_args, value.min) |
||
+ | value.max = options.func(tpl_args, value.max) |
||
+ | end |
||
+ | options.fmt = options.fmt or '%s' |
||
+ | if type(options.fmt) == 'function' then -- Function that returns the format string |
||
+ | options.fmt = options.fmt(tpl_args, value) |
||
+ | end |
||
+ | if value.min == value.max then -- Static value |
||
+ | value.out = string.format(options.fmt, value.min) |
||
+ | else -- Range value |
||
+ | options.fmt_range = options.fmt_range or i18n.range |
||
+ | value.out = string.format( |
||
+ | string.format(options.fmt_range, options.fmt, options.fmt), |
||
+ | value.min, |
||
+ | value.max |
||
+ | ) |
||
+ | end |
||
+ | if value.color then |
||
+ | value.out = m_util.html.poe_color(value.color, value.out, options.class) |
||
+ | end |
||
+ | if type(options.inline) == 'function' then |
||
+ | options.inline = options.inline(tpl_args, value) |
||
+ | end |
||
+ | if options.inline and options.inline ~= '' then |
||
+ | value.out = string.format(options.inline, value.out) |
||
+ | if options.inline_color ~= false then |
||
+ | options.inline_color = options.inline_color or 'default' |
||
+ | value.out = m_util.html.poe_color(options.inline_color, value.out, options.inline_class) |
||
+ | end |
||
+ | end |
||
+ | local return_color = options.return_color and value.color or nil |
||
+ | if return_color then |
||
+ | return value.out, return_color |
||
+ | end |
||
+ | return value.out, value |
||
+ | end |
||
function m.get_item_namespaces(args) |
function m.get_item_namespaces(args) |
Версия от 18:52, 22 января 2022
Это мета-модуль, который предназначен для использования только другими модулями. Он не должен вызываться в викитексте. |
Этот модуль зависит от следующих других модулей: |
Этот мета-модуль предоставляет служебные функции для модулей, которые имеют дело с предметами.
Использование
Этот модуль должен быть загружен с помощью require()
.
Вышеприведенная документация извлекается из Модуль:Item util/doc.
Редакторы могут экспериментировать в sandbox этого модуля и в testcases страницах.
Подстраницы этого модуля.
Редакторы могут экспериментировать в sandbox этого модуля и в testcases страницах.
Подстраницы этого модуля.
-------------------------------------------------------------------------------
--
-- Module:Item util
--
-- This meta module contains utility functions for modules that deal with items
-------------------------------------------------------------------------------
local m_util = require('Module:Util')
local m_cargo -- Lazy load require('Module:Cargo')
-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Item util')
-- 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 util/config/sandbox') or mw.loadData('Module:Item util/config')
local i18n = cfg.i18n
-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------
local m = {}
function m.format_value(tpl_args, value, options)
-- value: table
-- min:
-- max:
-- options: table
-- func: Function to transform the value retrieved from the database
-- fmt: Format string (or function that returns format string) to use for the value. Default: '%s'
-- fmt_range: Format string to use for the value range. Default: '(%s-%s)'
-- color: poe_color code to use for the value range. False for no color. Default: 'mod'
-- class: Additional css class added to color tag
-- inline: Format string to use for the output
-- inline_color: poe_color code to use for the output. False for no color. Default: 'default'
-- inline_class: Additional css class added to inline color tag
-- no_color: (Deprecated; use color=false instead)
-- return_color: (Deprecated; returns both value.out and value without this)
if options.color ~= false and options.no_color == nil then
local base = {
min = value.base_min or value.base,
max = value.base_max or value.base,
}
if options.color then
value.color = options.color
elseif value.min ~= base.min or value.max ~= base.max then
value.color = 'mod'
else
value.color = 'value'
end
end
if options.func then
value.min = options.func(tpl_args, value.min)
value.max = options.func(tpl_args, value.max)
end
options.fmt = options.fmt or '%s'
if type(options.fmt) == 'function' then -- Function that returns the format string
options.fmt = options.fmt(tpl_args, value)
end
if value.min == value.max then -- Static value
value.out = string.format(options.fmt, value.min)
else -- Range value
options.fmt_range = options.fmt_range or i18n.range
value.out = string.format(
string.format(options.fmt_range, options.fmt, options.fmt),
value.min,
value.max
)
end
if value.color then
value.out = m_util.html.poe_color(value.color, value.out, options.class)
end
if type(options.inline) == 'function' then
options.inline = options.inline(tpl_args, value)
end
if options.inline and options.inline ~= '' then
value.out = string.format(options.inline, value.out)
if options.inline_color ~= false then
options.inline_color = options.inline_color or 'default'
value.out = m_util.html.poe_color(options.inline_color, value.out, options.inline_class)
end
end
local return_color = options.return_color and value.color or nil
if return_color then
return value.out, return_color
end
return value.out, value
end
function m.get_item_namespaces(args)
-- Returns item namespaces from config as a table or as a comma-separated string
args.format = args.format or 'table'
if args.format == 'list' then
return cfg.item_namespaces_list
end
return cfg.item_namespaces
end
function m.query_item(args, qargs)
qargs = qargs or {}
m_cargo = m_cargo or require('Module:Cargo')
if not m_util.table.has_any_key(args, cfg.search_terms) then
error(i18n.errors.missing_search_term)
end
local tables = {'items'}
local fields = {
'items._pageName=_pageName',
'items.drop_enabled=drop_enabled',
'items.class_id=class_id',
}
local query = {
groupBy = 'items._pageID',
orderBy = 'items.drop_enabled DESC',
}
local search_param
local results
if args.metadata_id then
query.where = string.format(
'items.metadata_id = "%s"',
args.metadata_id
)
search_param = 'metadata_id'
elseif args.page then
-- Join with _pageData in order to check for page redirect
tables[#tables+1] = '_pageData'
query.join = 'items._pageName = _pageData._pageNameOrRedirect'
query.where = string.format(
'_pageData._pageName = "%s"',
m_cargo.addslashes(args.page)
)
search_param = 'page'
else
tables[#tables+1] = 'maps'
tables[#tables+1] = 'map_series'
query.join = 'items._pageID = maps._pageID, maps.series = map_series.name'
query.where = string.format(
'items._pageNamespace IN (%s)',
m.get_item_namespaces{format = 'list'}
)
query.orderBy = 'map_series.ordinal DESC, ' .. query.orderBy
if args.item_name_exact then
query.where = query.where .. string.format(
' AND items.name = "%s"',
m_cargo.addslashes(args.item_name_exact)
)
search_param = 'item_name_exact'
else
query.where = query.where .. string.format(
' AND items.name_list HOLDS "%s"',
m_cargo.addslashes(args.item_name)
)
search_param = 'item_name'
end
end
-- Append additional tables and fields
if type(qargs.tables) == 'table' and #qargs.tables > 0 then
tables = m_util.table.merge(tables, qargs.tables)
end
if type(qargs.fields) == 'table' and #qargs.fields > 0 then
fields = m_util.table.merge(fields, qargs.fields)
end
-- Append to join, where and orderBy clauses
if qargs.join then
query.join = table.concat({query.join, qargs.join}, ', ')
end
if qargs.where then
query.where = table.concat({query.where, qargs.where}, ' AND ')
end
if qargs.orderBy then
query.orderBy = table.concat({qargs.orderBy, query.orderBy}, ', ')
end
results = m_cargo.query(tables, fields, query)
local err
if #results == 0 then
-- No results found
err = m_util.misc.raise_error_or_return{
raise_required = true,
args = args,
msg = string.format(
i18n.errors.no_results_found,
search_param,
args[search_param]
)
}
elseif #results > 1 then
-- More than one result found
--
-- If results are all maps, use the one from the most recent map
-- series, regardless of whether it's drop enabled. Otherwise,
-- if only one of the results is drop enabled then use that one.
local map_count = 0
local drop_enabled_count = 0
for i, v in ipairs(results) do
if v['class_id'] == 'Map' then
map_count = map_count + 1
end
if m_util.cast.boolean(v['items.drop_enabled']) then
drop_enabled_count = drop_enabled_count + 1
end
end
if (map_count == 0 or map_count ~= #results) and drop_enabled_count ~= 1 then
err = m_util.misc.raise_error_or_return{
raise_required = true,
args = args,
msg = string.format(
i18n.errors.many_results_found,
search_param,
args[search_param]
)
}
end
end
if err ~= nil then
if not m_util.cast.boolean(args.nocat) then
err = err .. m_util.misc.add_category({args.error_category or i18n.categories.failed_query})
end
return {error = err}
end
return results[1] -- orderBy ensures that the first result is the one we want
end
return m