mNo edit summary |
(Adding support for items in timeline lists.) |
||
Line 1: | Line 1: | ||
local getArgs = require('Module:Arguments').getArgs |
local getArgs = require('Module:Arguments').getArgs |
||
− | local |
+ | local m_util = require('Module:Util') |
+ | local f_item_link = require('Module:Item link').item_link |
||
local cargo = mw.ext.cargo |
local cargo = mw.ext.cargo |
||
Line 28: | Line 29: | ||
function h.cargo_query(tpl_args) |
function h.cargo_query(tpl_args) |
||
--[[ |
--[[ |
||
− | Returns a Cargo query of all the results |
+ | Returns a Cargo query of all the results. |
− | results than the maximum query limit. It also adds popular fields. |
||
tpl_args should include these keys: |
tpl_args should include these keys: |
||
Line 38: | Line 38: | ||
]] |
]] |
||
− | local tables = |
+ | local tables = m_util.string.split(tpl_args.tables, ', ') |
− | local fields = |
+ | local fields = m_util.string.split(tpl_args.fields, ', ') |
-- Parse query arguments |
-- Parse query arguments |
||
⚫ | |||
local query = { |
local query = { |
||
− | -- Workaround: fix duplicates |
||
⚫ | |||
− | limit = query_limit, |
||
⚫ | |||
} |
} |
||
for key, value in pairs(tpl_args) do |
for key, value in pairs(tpl_args) do |
||
Line 55: | Line 50: | ||
end |
end |
||
− | -- |
+ | -- Query cargo rows: |
+ | local results = m_util.cargo.query(tables, fields, query, args) |
||
− | fields_base = { |
||
⚫ | |||
⚫ | |||
⚫ | |||
− | for _, tbl in ipairs(tables) do |
||
− | for _, fld in ipairs(fields_base) do |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | -- Query cargo table. If there are too many results then repeat, |
||
− | -- offset, query and add the remaining results: |
||
− | results = {} |
||
− | repeat |
||
− | local result = mw.ext.cargo.query( |
||
− | table.concat(tables, ', '), |
||
− | table.concat(fields, ', '), |
||
⚫ | |||
⚫ | |||
− | query.offset = query.offset + #result |
||
− | |||
− | for _,v in ipairs(result) do |
||
− | results[#results + 1] = v |
||
− | end |
||
− | until #result < query_limit |
||
return results |
return results |
||
end |
end |
||
− | |||
Line 96: | Line 66: | ||
return value |
return value |
||
else |
else |
||
− | return |
+ | return m_util.cast.version(value, {return_type='string'}) |
end |
end |
||
end |
end |
||
Line 162: | Line 132: | ||
} |
} |
||
− | p.table_versions = |
+ | p.table_versions = m_util.cargo.declare_factory{data=version_map} |
p.version = function(frame) |
p.version = function(frame) |
||
⚫ | |||
⚫ | |||
− | |||
--[[ |
--[[ |
||
+ | This function creates a infobox and stores the data in a cargo table. |
||
⚫ | |||
+ | Examples: |
||
= p.version({ |
= p.version({ |
||
before = '2.4.1a', |
before = '2.4.1a', |
||
Line 176: | Line 146: | ||
}) |
}) |
||
--]] |
--]] |
||
+ | |||
⚫ | |||
⚫ | |||
+ | |||
for k, data in pairs(version_map.fields) do |
for k, data in pairs(version_map.fields) do |
||
if data.validate ~= nil then |
if data.validate ~= nil then |
||
Line 186: | Line 160: | ||
end |
end |
||
− | local version_parts = |
+ | local version_parts = m_util.cast.version(args.patch, {return_type='table'}) |
args.major_part = tonumber(version_parts[1]) |
args.major_part = tonumber(version_parts[1]) |
||
args.minor_part = tonumber(version_parts[2]) |
args.minor_part = tonumber(version_parts[2]) |
||
Line 227: | Line 201: | ||
end |
end |
||
− | + | m_util.cargo.store(frame, _properties) |
|
Line 260: | Line 234: | ||
} |
} |
||
− | return tostring(tbl) .. |
+ | return tostring(tbl) .. m_util.misc.add_category(cats) |
end |
end |
||
Line 267: | Line 241: | ||
p.version_declare = function(frame) |
p.version_declare = function(frame) |
||
-- local args = getArgs(frame, {parentFirst = true}) |
-- local args = getArgs(frame, {parentFirst = true}) |
||
− | local frame = |
+ | local frame = m_util.misc.get_frame(frame) |
local props = { |
local props = { |
||
Line 285: | Line 259: | ||
--mw.logObject(props) |
--mw.logObject(props) |
||
− | return |
+ | return m_util.cargo.declare(frame, props) |
end |
end |
||
Line 295: | Line 269: | ||
p.version_history_list = function(frame) |
p.version_history_list = function(frame) |
||
local args = getArgs(frame, {parentFirst = true}) |
local args = getArgs(frame, {parentFirst = true}) |
||
− | local frame = |
+ | local frame = m_util.misc.get_frame(frame) |
-- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'}) |
-- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'}) |
||
Line 319: | Line 293: | ||
local results = {} |
local results = {} |
||
repeat |
repeat |
||
− | local result = |
+ | local result = m_util.smw.query(query, frame) |
local length = #result |
local length = #result |
||
query.offset = query.offset + length |
query.offset = query.offset + length |
||
Line 336: | Line 310: | ||
local version = result['Is version'] |
local version = result['Is version'] |
||
− | local v = |
+ | local v = m_util.cast.version(result['Is version']) |
local minor_version = table_concat({v[1], v[2], v[3]}, '.') -- todo: rework it |
local minor_version = table_concat({v[1], v[2], v[3]}, '.') -- todo: rework it |
||
Line 365: | Line 339: | ||
p.version_history_list_2 = function(frame) |
p.version_history_list_2 = function(frame) |
||
local args = getArgs(frame, {parentFirst = true}) |
local args = getArgs(frame, {parentFirst = true}) |
||
− | local frame = |
+ | local frame = m_util.misc.get_frame(frame) |
-- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'}) |
-- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'}) |
||
Line 393: | Line 367: | ||
local results = {} |
local results = {} |
||
repeat |
repeat |
||
− | local result = |
+ | local result = m_util.smw.query(query, frame) |
local length = #result |
local length = #result |
||
query.offset = query.offset + length |
query.offset = query.offset + length |
||
Line 439: | Line 413: | ||
function p.timeline(frame) |
function p.timeline(frame) |
||
--[[ |
--[[ |
||
− | + | Add a timeline when versions or items were added to the game. |
|
− | the game. |
||
− | TODO: |
||
− | * Support for different result formats ie table, plain text etc. |
||
− | * Make sure it works with items (and areas?) once item2 uses cargo. |
||
Examples: |
Examples: |
||
Line 451: | Line 421: | ||
q_where = 'versions.version <> ""', |
q_where = 'versions.version <> ""', |
||
q_orderBy = 'versions.version DESC, versions.release_date ASC' |
q_orderBy = 'versions.version DESC, versions.release_date ASC' |
||
⚫ | |||
⚫ | |||
+ | = p.timeline{ |
||
+ | tables = 'versions, items', |
||
+ | fields = 'versions.version, versions.release_date, versions._pageName, items.class, items._pageName, items.name, items.release_version, items.inventory_icon, items.html', |
||
+ | q_join = 'versions.version=items.release_version', |
||
+ | q_where = 'versions.version IS NOT NULL AND items.release_version IS NOT NULL AND items.rarity = "Unique"', |
||
+ | q_orderBy = 'versions.version DESC, versions.release_date ASC, items.name ASC', |
||
⚫ | |||
⚫ | |||
} |
} |
||
]] |
]] |
||
+ | -- Get args: |
||
− | local tpl_args = getArgs(frame, { |
||
− | parentFirst = true |
+ | local tpl_args = getArgs(frame, {parentFirst = true}) |
⚫ | |||
− | + | ||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
local results = h.cargo_query(tpl_args) |
local results = h.cargo_query(tpl_args) |
||
+ | -- Preallocate: |
||
local out = {} |
local out = {} |
||
local last_main_version |
local last_main_version |
||
Line 468: | Line 448: | ||
local current_version |
local current_version |
||
local result_list |
local result_list |
||
⚫ | |||
− | |||
+ | -- Loop through all the results from the query: |
||
for i, result in ipairs(results) do |
for i, result in ipairs(results) do |
||
− | release_version = result[ |
+ | release_version = result['versions.version'] |
− | if release_version == nil then |
||
− | release_version = result[tpl_args.tables .. '.version'] |
||
− | end |
||
− | local v = |
+ | local v = m_util.cast.version(release_version) |
local version_h2 = table.concat({v[1], v[2]}, '.') |
local version_h2 = table.concat({v[1], v[2]}, '.') |
||
⚫ | |||
− | |||
if release_version ~= last_minor_version then |
if release_version ~= last_minor_version then |
||
⚫ | |||
if version_h2 ~= last_main_version then |
if version_h2 ~= last_main_version then |
||
if current_version ~= nil then |
if current_version ~= nil then |
||
Line 496: | Line 475: | ||
:wikitext(string.format( |
:wikitext(string.format( |
||
'%s - [[%s %s]]', |
'%s - [[%s %s]]', |
||
− | result[ |
+ | result['versions.release_date'], |
i18n.timeline.version, |
i18n.timeline.version, |
||
release_version, |
release_version, |
||
− | result[ |
+ | result['versions.version']) |
) |
) |
||
result_list = current_version:tag('ol') |
result_list = current_version:tag('ol') |
||
end |
end |
||
− | + | ||
+ | -- If the result has an item class, then add another list with |
||
− | -- results. |
+ | -- the results. |
− | if result[tpl_args.tables .. 'version'] == '' then |
||
− | + | if result['items.class'] ~= nil then |
|
⚫ | |||
− | + | f_item_link{ |
|
− | if result[tpl_args.tables .. 'item_class'] ~= '' then |
||
⚫ | |||
− | result_list:tag('li'):wikitext(string.format('%s', |
||
− | + | name=result['items.name'], |
|
− | + | inventory_icon=result['items.inventory_icon'] or '', |
|
+ | html=result['items.html'] or '', |
||
⚫ | |||
⚫ | |||
) |
) |
||
⚫ | |||
− | else |
||
⚫ | |||
− | result_list:tag('li'):wikitext(string.format('[[%s]]', |
||
⚫ | |||
⚫ | |||
− | ) |
||
− | |||
− | end |
||
− | end |
||
− | -- Save the last list |
+ | -- Save the last list: |
if (i == #results) and (current_version ~= nil) then |
if (i == #results) and (current_version ~= nil) then |
||
out[#out + 1] = tostring(current_version) |
out[#out + 1] = tostring(current_version) |
||
Line 532: | Line 508: | ||
end |
end |
||
− | -- |
+ | -- Add categories: |
local cats = { |
local cats = { |
||
'Timelines', |
'Timelines', |
||
} |
} |
||
− | return table.concat(out, '\n') .. |
+ | return table.concat(out, '\n') .. m_util.misc.add_category(cats) |
end |
end |
||
Revision as of 20:17, 16 January 2018
This module depends on the following other modules: |
Templates
The above documentation is transcluded from Module:Version/doc.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
local getArgs = require('Module:Arguments').getArgs
local m_util = require('Module:Util')
local f_item_link = require('Module:Item link').item_link
local cargo = mw.ext.cargo
local string_format = string.format
local table_concat = table.concat
local mw_html = mw.html
local mw_language = mw.getLanguage('en')
local p = {}
local date_format = 'd F Y H:i:s'
local i18n = {
timeline = {
version = 'Version',
},
}
-- ---------------------------------------------------------------------
-- Helper
-- ---------------------------------------------------------------------
h = {}
function h.cargo_query(tpl_args)
--[[
Returns a Cargo query of all the results.
tpl_args should include these keys:
tpl_args.tables
tpl_args.fields
tpl_args.q_*
]]
local tables = m_util.string.split(tpl_args.tables, ', ')
local fields = m_util.string.split(tpl_args.fields, ', ')
-- Parse query arguments
local query = {
}
for key, value in pairs(tpl_args) do
if string.sub(key, 0, 2) == 'q_' then
query[string.sub(key, 3)] = value
end
end
-- Query cargo rows:
local results = m_util.cargo.query(tables, fields, query, args)
return results
end
-- ---------------------------------------------------------------------
-- Template: Version
-- ---------------------------------------------------------------------
function validate_version(value)
if value == nil then
return value
else
return m_util.cast.version(value, {return_type='string'})
end
end
function show_date(args)
return function(tpl_args, frame)
local version = tpl_args[args.key]
local date = tpl_args[string.format('%s_date', args.key)]
if version and date then
date = mw_language:formatDate(date_format, date)
if args.key == 'before' then
return string_format('← [[Version %s|%s]]<br>%s', version, version, date)
elseif args.key == 'after' then
return string_format('[[Version %s|%s]] →<br>%s', version, version, date)
end
else
return ''
end
end
end
local version_map = {
table = 'versions',
fields = {
patch = {
field = 'version',
type = 'String',
validate = validate_version,
},
patchdate = {
field = 'release_date',
type = 'Datetime',
validate = tostring,
},
major_part = {
field = 'major_part',
type = 'Integer',
},
minor_part = {
field = 'minor_part',
type = 'Integer',
},
patch_part = {
field = 'patch_part',
type = 'Integer',
},
revision_part = {
field = 'revision_part',
type = 'String',
},
before = {
field = 'before',
type = 'String',
validate = validate_version,
show = show_date{key='before'},
},
after = {
field = 'after',
type = 'String',
validate = validate_version,
show = show_date{key='after'},
},
},
}
p.table_versions = m_util.cargo.declare_factory{data=version_map}
p.version = function(frame)
--[[
This function creates a infobox and stores the data in a cargo table.
Examples:
= p.version({
before = '2.4.1a',
patch = '2.4.1b',
patchdate = 'October 18, 2016',
after = '2.4.2',
})
--]]
local args = getArgs(frame, {parentFirst = true})
local frame = m_util.misc.get_frame(frame)
for k, data in pairs(version_map.fields) do
if data.validate ~= nil then
args[k] = data.validate(args[k])
end
end
if not args.patch or not args.patchdate then
error('Arguments "patch" and "patchdate" are required')
end
local version_parts = m_util.cast.version(args.patch, {return_type='table'})
args.major_part = tonumber(version_parts[1])
args.minor_part = tonumber(version_parts[2])
args.patch_part = tonumber(version_parts[3])
if version_parts[4] then
args.revision_part = version_parts[4]
end
-- Check and set 'before' and 'after' args
local edge_names = {'before', 'after'}
for _, key in ipairs(edge_names) do
local v = args[key]
if v then
local results = cargo.query(
'versions',
'versions.release_date',
{
where=string.format('version="%s"', v),
-- Cargo bug work around
groupBy='versions._pageID',
}
)
if #results == 1 then
args[string.format('%s_date', key)] = results[1]['versions.release_date']
elseif #results > 1 then
error('There are multiple versions with the same name')
end
end
end
-- Set Cargo data
local _properties = {
_table = version_map.table,
}
for key, data in pairs(version_map.fields) do
if args[key] ~= nil then
_properties[data.field] = args[key]
end
end
m_util.cargo.store(frame, _properties)
-- Generate output
-- todo: rework it somehow
local release_date = mw_language:formatDate(date_format, args.patchdate)
local tbl = mw_html.create('table')
tbl
:addClass('wikitable successionbox')
:tag('tr')
:tag('th')
:attr('colspan', 3)
:wikitext('[[Version history|Version History]]')
:done()
:done()
:tag('tr')
:tag('td')
:cssText('width: 30%')
:wikitext(version_map.fields.before.show(args, frame))
:done()
:tag('td')
:cssText('width: 40%')
:wikitext(string_format('<b>%s</b><br>%s', args.patch, release_date))
:done()
:tag('td')
:cssText('width: 30%')
:wikitext(version_map.fields.after.show(args, frame))
local cats = {
'Versions',
}
return tostring(tbl) .. m_util.misc.add_category(cats)
end
-----
p.version_declare = function(frame)
-- local args = getArgs(frame, {parentFirst = true})
local frame = m_util.misc.get_frame(frame)
local props = {
_table = 'Versions',
}
-- for i, _ in pairs(version_map) do
-- props[i] = _.datatype
-- end
for i = 1, #temp_map_for_cargo do
local v = temp_map_for_cargo[i]
local _ = version_map[v]
props[v] = _.datatype
end
--mw.logObject(props)
return m_util.cargo.declare(frame, props)
end
-----
------------------------------------------------------------------------------------------------------
-- Template: Version history list
p.version_history_list = function(frame)
local args = getArgs(frame, {parentFirst = true})
local frame = m_util.misc.get_frame(frame)
-- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'})
-- = p.version_history_list({conditions='[[Is version::~0.9*]]'})
-- = p.version_history_list({conditions='[[Is version::~0.5*]]'})
if args.conditions then
args.conditions = args.conditions .. '[[Has release date::+]]'
else
args.conditions = '[[Is version::+]][[Has release date::+]]'
end
local query = {
args.conditions,
'?Is version',
'?Has release date',
sort = 'Has release date, Is version',
order = 'desc, desc',
link = 'none',
offset = 0,
}
local results = {}
repeat
local result = m_util.smw.query(query, frame)
local length = #result
query.offset = query.offset + length
for i = 1, length do
results[#results + 1] = result[i]
end
until length < 1000
local out = {}
local last_minor_version, current_list
for i = 1, #results do
local result = results[i]
local date = result['Has release date']
local version = result['Is version']
local v = m_util.cast.version(result['Is version'])
local minor_version = table_concat({v[1], v[2], v[3]}, '.') -- todo: rework it
if minor_version ~= last_minor_version then
if current_list ~= nil then
out[#out + 1] = tostring(current_list)
end
out[#out + 1] = string_format('===Version %s===', minor_version)
current_list = mw_html.create('ul')
end
current_list:tag('li'):wikitext(string_format('%s – [[Version %s]]', date, version))
-- save the last list
if i == #results and current_list ~= nil then
out[#out + 1] = tostring(current_list)
end
last_minor_version = minor_version
end
return table_concat(out, '\n')
end
-----
p.version_history_list_2 = function(frame)
local args = getArgs(frame, {parentFirst = true})
local frame = m_util.misc.get_frame(frame)
-- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'})
-- = p.version_history_list({conditions='[[Is version::~0.9*]]'})
-- = p.version_history_list({conditions='[[Is version::~0.5*]]'})
if args.conditions then
args.conditions = args.conditions .. '[[Has release date::+]]'
else
args.conditions = '[[Is version::+]] [[Has release date::+]]'
end
local query = {
args.conditions,
'?Is version',
'?Has release date',
'?Has major version part',
'?Has minor version part',
'?Has patch version part',
-- '?Has revision version part',
sort = 'Has major version part, Has minor version part, Has patch version part, Is version',
order = 'desc, desc, desc, desc',
link = 'none',
offset = 0,
}
local results = {}
repeat
local result = m_util.smw.query(query, frame)
local length = #result
query.offset = query.offset + length
for i = 1, length do
results[#results + 1] = result[i]
end
until length < 1000
-- mw.logObject(results)
local out = {}
local last_minor_version, current_list
for i = 1, #results do
local result = results[i]
local date = result['Has release date']
local version = result['Is version']
local patch_version = string_format('%s.%s.%s',
result['Has major version part'], result['Has minor version part'], result['Has patch version part'])
if patch_version ~= last_minor_version then
if current_list ~= nil then
out[#out + 1] = tostring(current_list)
end
out[#out + 1] = string_format('===Version %s===', patch_version)
current_list = mw_html.create('ul')
end
current_list:tag('li'):wikitext(string_format('%s – [[Version %s]]', date, version))
-- save the last list
if i == #results and current_list ~= nil then
out[#out + 1] = tostring(current_list)
end
last_minor_version = patch_version
end
return table_concat(out, '\n')
end
function p.timeline(frame)
--[[
Add a timeline when versions or items were added to the game.
Examples:
= p.timeline{
tables = 'versions',
fields = 'versions.version, versions.release_date',
q_where = 'versions.version <> ""',
q_orderBy = 'versions.version DESC, versions.release_date ASC'
}
= p.timeline{
tables = 'versions, items',
fields = 'versions.version, versions.release_date, versions._pageName, items.class, items._pageName, items.name, items.release_version, items.inventory_icon, items.html',
q_join = 'versions.version=items.release_version',
q_where = 'versions.version IS NOT NULL AND items.release_version IS NOT NULL AND items.rarity = "Unique"',
q_orderBy = 'versions.version DESC, versions.release_date ASC, items.name ASC',
q_groupBy = 'versions._pageID, items.name',
q_limit = 5000,
}
]]
-- Get args:
local tpl_args = getArgs(frame, {parentFirst = true})
local frame = m_util.misc.get_frame(frame)
-- Query results:
local results = h.cargo_query(tpl_args)
-- Preallocate:
local out = {}
local last_main_version
local last_minor_version
local current_version
local result_list
-- Loop through all the results from the query:
for i, result in ipairs(results) do
release_version = result['versions.version']
local v = m_util.cast.version(release_version)
local version_h2 = table.concat({v[1], v[2]}, '.')
if release_version ~= last_minor_version then
if version_h2 ~= last_main_version then
if current_version ~= nil then
out[#out + 1] = tostring(current_version)
end
out[#out+1] = string.format(
'===%s %s===',
i18n.timeline.version,
table.concat({v[1], v[2], 0}, '.')
)
current_version = mw.html.create('ul')
end
current_version
:tag('li')
:wikitext(string.format(
'%s - [[%s %s]]',
result['versions.release_date'],
i18n.timeline.version,
release_version,
result['versions.version'])
)
result_list = current_version:tag('ol')
end
-- If the result has an item class, then add another list with
-- the results.
if result['items.class'] ~= nil then
result_list:tag('li'):wikitext(string.format('%s',
f_item_link{
page=result['items._pageName'],
name=result['items.name'],
inventory_icon=result['items.inventory_icon'] or '',
html=result['items.html'] or '',
skip_query=true
}
)
)
end
-- Save the last list:
if (i == #results) and (current_version ~= nil) then
out[#out + 1] = tostring(current_version)
end
last_main_version = version_h2
last_minor_version = release_version
end
-- Add categories:
local cats = {
'Timelines',
}
return table.concat(out, '\n') .. m_util.misc.add_category(cats)
end
-----
return p