Module:Talk archive/sandbox: Difference between revisions
Jump to navigation
Jump to search
(Created page with "------------------------------------------------------------------------------- -- -- Configuration for Module:Talk archive -- ------------------------------------------------------------------------------- local cfg = {} -- ---------------------------------------------------------------------------- -- i18n -- ---------------------------------------------------------------------------- cfg.i18n = {} cfg.i18n.archive_prefix = 'Archive ' cfg.i18n.ar...") |
No edit summary |
||
Line 1: | Line 1: | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- | -- | ||
-- | -- Module:Talk archive | ||
-- | -- | ||
-- This module implements Template:Talk archive. | |||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
local cfg = | require('Module:No globals') | ||
local m_util = require('Module:Util') | |||
local f_exp_search = require('Module:Exponential search') | |||
-- Should we use the sandbox version of our submodules? | |||
local use_sandbox = m_util.misc.maybe_sandbox('Talk archive') | |||
-- 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:Talk archive/config/sandbox') or mw.loadData('Module:Talk archive/config') | |||
local i18n = cfg.i18n | |||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
-- | -- Helper functions | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
local h = {} | |||
function h.escape_pattern(s) | |||
-- Escape punctuation in a string so it can be used in a Lua pattern. | |||
s = s:gsub('%p', '%%%0') | |||
return s | |||
end | |||
-- Checks whether a page exists, going through pcall | |||
-- in case we are over the expensive function limit. | |||
function h.check_page_exists(page) | |||
local success, exists = pcall(function() | |||
return mw.title.new(page).exists | |||
end) | |||
return success and exists | |||
end | |||
-- Return the highest archive number, using exponential search | |||
-- algorithm. | |||
function h.get_highest_archive_number(prefix, start) | |||
return f_exp_search(function (i) | |||
return h.check_page_exists(prefix .. tostring(i)) | |||
end, start) | |||
end | |||
-- ---------------------------------------------------------------------------- | |||
-- Banner_Nav class | |||
-- ---------------------------------------------------------------------------- | |||
local Banner_Nav = {} | |||
Banner_Nav.__index = Banner_Nav | |||
function Banner_Nav.new(args) | |||
-- Create a new Banner_Nav object | |||
local obj = setmetatable({}, Banner_Nav) | |||
obj.args = args | |||
obj.current_title = obj.args.page | |||
-- Decode HTML entities of user supplied prefix so that users can enter | |||
-- things like "Archive " from wikicode. The encoding is needed because | |||
-- trailing spaces are trimmed from template args. | |||
obj.prefix = obj.args.prefix and mw.text.decode(obj.args.prefix) or i18n.archive_prefix | |||
-- Get the current archive page number | |||
local pattern = string.format( | |||
'^%s([1-9][0-9]*)$', | |||
h.escape_pattern(obj.prefix) | |||
) | |||
obj.current_page = tonumber(obj.current_title.subpageText:match(pattern)) | |||
-- Find the highest archive page number | |||
obj.highest_page = h.get_highest_archive_number(string.format( | |||
'%s:%s/%s', | |||
obj.current_title.nsText, | |||
obj.current_title.baseText, | |||
obj.prefix | |||
)) | |||
return obj | |||
end | |||
function Banner_Nav:message_box() | |||
local title | |||
if self.args.period then | |||
title = string.format(i18n.Banner_Nav.title_blurb_period, self.args.period) | |||
else | |||
title = i18n.Banner_Nav.title_blurb_noperiod | |||
end | |||
local talk_page = string.format('%s:%s', self.current_title.nsText, self.current_title.baseText) | |||
local text = string.format(i18n.Banner_Nav.text_blurb, talk_page) | |||
return mw.getCurrentFrame():expandTemplate{ | |||
title = i18n.templates.message_box, | |||
args = { | |||
type = 'lock', | |||
image = i18n.archive_image, | |||
title = title, | |||
text = text, | |||
} | |||
} | |||
end | |||
function Banner_Nav:get_pages() | |||
-- Returns an array of archive page numbers | |||
if not self.current_page then | |||
return {} | |||
end | |||
cfg. | local range = self.args.range and tonumber(self.args.range) or cfg.nav_link_range | ||
range = math.floor(range) | |||
if range < 1 then | |||
return {self.current_page} | |||
end | |||
} | local pages = {} | ||
-- Pages numbered lower than current page | |||
for i = -range, -1 do | |||
local page = self.current_page + i | |||
if page >= 1 then | |||
table.insert(pages, page) | |||
end | |||
end | |||
-- Current page | |||
table.insert(pages, self.current_page) | |||
-- Pages numbered higher than current page | |||
for i = 1, range do | |||
local page = self.current_page + i | |||
if page <= self.highest_page then | |||
table.insert(pages, page) | |||
end | |||
end | |||
return pages | |||
end | |||
function Banner_Nav:navigation() | |||
local pages = self:get_pages() | |||
if #pages < 1 then | |||
return '' | |||
end | |||
local html = mw.html.create('div') | |||
:cssText('text-align:center;') | |||
local list = html:tag('ul') | |||
:addClass('hlist') | |||
:newline() | |||
for i, p in ipairs(pages) do | |||
local list_item = list:tag('li') | |||
if p then | |||
local subpage = self.prefix .. tostring(p) | |||
local display = p == self.current_page and string.format(i18n.Banner_Nav.link_text, p) or tostring(p) | |||
local link = m_util.html.wikilink('../' .. subpage, display) | |||
if i == 1 and p ~= self.current_page then | |||
list_item:wikitext(string.format(i18n.Banner_Nav.before_fmt, link)) | |||
elseif i == #pages and p ~= self.current_page then | |||
list_item:wikitext(string.format(i18n.Banner_Nav.after_fmt, link)) | |||
else | |||
list_item:wikitext(link) | |||
end | |||
end | |||
list:newline() | |||
end | |||
return tostring(html) | |||
end | |||
function Banner_Nav:__tostring() | |||
return table.concat({ | |||
self:message_box(), | |||
'\n', | |||
self:navigation(), | |||
' __NONEWSECTIONLINK__ __NOEDITSECTION__', | |||
}) | |||
end | |||
-- ---------------------------------------------------------------------------- | |||
-- Main functions | |||
-- ---------------------------------------------------------------------------- | |||
local function _talk_archive(args) | |||
args.page = args.page and mw.title.new(args.page) or mw.title.getCurrentTitle() | |||
local t = Banner_Nav.new(args) | |||
return tostring(t) | |||
end | |||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
-- | -- Exported functions | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
local p = {} | |||
} | |||
-- | -- | ||
cfg. | -- Template:Talk archive | ||
-- | |||
p.talk_archive = m_util.misc.invoker_factory(_talk_archive, { | |||
wrappers = cfg.wrappers.talk_archive, | |||
}) | |||
return | return p |
Latest revision as of 22:27, 17 June 2023
![](https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Edit_In_Sandbox_Icon_-_Color.svg/45px-Edit_In_Sandbox_Icon_-_Color.svg.png)
This is the module sandbox page for Module:Talk archive (diff).
The above documentation is transcluded from Module:Talk archive/doc.
Editors can experiment in this module's sandbox and testcases pages.
Please add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Please add categories to the /doc subpage. Subpages of this module.
-------------------------------------------------------------------------------
--
-- Module:Talk archive
--
-- This module implements Template:Talk archive.
-------------------------------------------------------------------------------
require('Module:No globals')
local m_util = require('Module:Util')
local f_exp_search = require('Module:Exponential search')
-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Talk archive')
-- 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:Talk archive/config/sandbox') or mw.loadData('Module:Talk archive/config')
local i18n = cfg.i18n
-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------
local h = {}
function h.escape_pattern(s)
-- Escape punctuation in a string so it can be used in a Lua pattern.
s = s:gsub('%p', '%%%0')
return s
end
-- Checks whether a page exists, going through pcall
-- in case we are over the expensive function limit.
function h.check_page_exists(page)
local success, exists = pcall(function()
return mw.title.new(page).exists
end)
return success and exists
end
-- Return the highest archive number, using exponential search
-- algorithm.
function h.get_highest_archive_number(prefix, start)
return f_exp_search(function (i)
return h.check_page_exists(prefix .. tostring(i))
end, start)
end
-- ----------------------------------------------------------------------------
-- Banner_Nav class
-- ----------------------------------------------------------------------------
local Banner_Nav = {}
Banner_Nav.__index = Banner_Nav
function Banner_Nav.new(args)
-- Create a new Banner_Nav object
local obj = setmetatable({}, Banner_Nav)
obj.args = args
obj.current_title = obj.args.page
-- Decode HTML entities of user supplied prefix so that users can enter
-- things like "Archive " from wikicode. The encoding is needed because
-- trailing spaces are trimmed from template args.
obj.prefix = obj.args.prefix and mw.text.decode(obj.args.prefix) or i18n.archive_prefix
-- Get the current archive page number
local pattern = string.format(
'^%s([1-9][0-9]*)$',
h.escape_pattern(obj.prefix)
)
obj.current_page = tonumber(obj.current_title.subpageText:match(pattern))
-- Find the highest archive page number
obj.highest_page = h.get_highest_archive_number(string.format(
'%s:%s/%s',
obj.current_title.nsText,
obj.current_title.baseText,
obj.prefix
))
return obj
end
function Banner_Nav:message_box()
local title
if self.args.period then
title = string.format(i18n.Banner_Nav.title_blurb_period, self.args.period)
else
title = i18n.Banner_Nav.title_blurb_noperiod
end
local talk_page = string.format('%s:%s', self.current_title.nsText, self.current_title.baseText)
local text = string.format(i18n.Banner_Nav.text_blurb, talk_page)
return mw.getCurrentFrame():expandTemplate{
title = i18n.templates.message_box,
args = {
type = 'lock',
image = i18n.archive_image,
title = title,
text = text,
}
}
end
function Banner_Nav:get_pages()
-- Returns an array of archive page numbers
if not self.current_page then
return {}
end
local range = self.args.range and tonumber(self.args.range) or cfg.nav_link_range
range = math.floor(range)
if range < 1 then
return {self.current_page}
end
local pages = {}
-- Pages numbered lower than current page
for i = -range, -1 do
local page = self.current_page + i
if page >= 1 then
table.insert(pages, page)
end
end
-- Current page
table.insert(pages, self.current_page)
-- Pages numbered higher than current page
for i = 1, range do
local page = self.current_page + i
if page <= self.highest_page then
table.insert(pages, page)
end
end
return pages
end
function Banner_Nav:navigation()
local pages = self:get_pages()
if #pages < 1 then
return ''
end
local html = mw.html.create('div')
:cssText('text-align:center;')
local list = html:tag('ul')
:addClass('hlist')
:newline()
for i, p in ipairs(pages) do
local list_item = list:tag('li')
if p then
local subpage = self.prefix .. tostring(p)
local display = p == self.current_page and string.format(i18n.Banner_Nav.link_text, p) or tostring(p)
local link = m_util.html.wikilink('../' .. subpage, display)
if i == 1 and p ~= self.current_page then
list_item:wikitext(string.format(i18n.Banner_Nav.before_fmt, link))
elseif i == #pages and p ~= self.current_page then
list_item:wikitext(string.format(i18n.Banner_Nav.after_fmt, link))
else
list_item:wikitext(link)
end
end
list:newline()
end
return tostring(html)
end
function Banner_Nav:__tostring()
return table.concat({
self:message_box(),
'\n',
self:navigation(),
' __NONEWSECTIONLINK__ __NOEDITSECTION__',
})
end
-- ----------------------------------------------------------------------------
-- Main functions
-- ----------------------------------------------------------------------------
local function _talk_archive(args)
args.page = args.page and mw.title.new(args.page) or mw.title.getCurrentTitle()
local t = Banner_Nav.new(args)
return tostring(t)
end
-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------
local p = {}
--
-- Template:Talk archive
--
p.talk_archive = m_util.misc.invoker_factory(_talk_archive, {
wrappers = cfg.wrappers.talk_archive,
})
return p