Module:Archives
| This module is rated as pre-alpha. It is incomplete and may or may not be in active development. Do not use it in article namespace pages. A module remains in pre-alpha until its developer, or another editor who adopts it if it is abandoned for some time, considers the basic structure complete. |
| This module depends on the following other modules: |
| This module uses TemplateStyles: |
This module implements {{archives}}.
Usage
{{#invoke:Archives|function_name}}
local p = {}
local cfg = mw.loadData('Module:Archives/config')
local mbots = require('Module:Archives/bots/sandbox')
local function is_filled(var)
return var and var ~= ''
end
-- simple helper for simple cases
local function var_or_default(var, default)
if is_filled(var) then
return var
else
return default
end
end
local function wikilink(link, display)
if display then
return '[[' .. link .. '|' .. display .. ']]'
else
return '[[' .. link .. ']]'
end
end
local function talk_other(demospace, talk)
if is_filled(demospace) then return demospace end
if mw.title.getCurrentTitle().isTalkPage then return talk end
return nil -- just return nil rather than 'other' since we have no need
end
local function add_image(image)
return mw.html.create('div'):addClass('archives-image'):wikitext(
require('Module:Sandbox/Izno/InfoboxImage')._InfoboxImage({
[cfg.img_mod.image] = var_or_default(image.image, cfg.image),
[cfg.img_mod.alt] = var_or_default(image.alt, cfg.img_mod.alt_none),
[cfg.img_mod.link] = var_or_default(image.link, cfg.img_mod.link_none),
[cfg.img_mod.size] = var_or_default(image.size, nil),
[cfg.img_mod.sizedefault] = cfg.image_size
})
)
end
local function search_box(frame, is_banner, root, search)
if search.search and search.search == cfg.search_no then return nil end
local prefix = ''
if is_filled(search.prefix) then
prefix = search.prefix
-- this double-check elseif may move out to code-proper
elseif is_filled(root) then
prefix = root
else
prefix = mw.title.getCurrentTitle().prefixedText .. '/'
end
local sbreak
if search.sbreak and (search.sbreak == 'yes' or search.sbreak == 'no') then
sbreak = search.sbreak
end
if not sbreak then
if is_banner then
sbreak = 'no'
else
sbreak = 'yes'
end
end
local width = ''
if not is_banner then
width = var_or_default(search.width, cfg.search_width)
end
local label = var_or_default(search.label, cfg.search_label)
local placeholder = var_or_default(search.placeholder, cfg.search_placeholder)
local inputbox_options = {
['bgcolor'] = 'transparent',
['type'] = 'fulltext',
['prefix'] = prefix,
['break'] = sbreak,
['width'] = width,
['searchbuttonlabel'] = label,
['placeholder'] = placeholder
}
local inputbox_content = {}
for k, v in pairs(inputbox_options) do
table.insert(inputbox_content, k .. '=' .. v)
end
return mw.html.create('div'):addClass('archives-search'):wikitext(frame:extensionTag{
name = 'inputbox',
content = table.concat(inputbox_content, '\n')
})
end
local function note_auto(frame, auto)
local bot_disabled = var_or_default(auto.nobot, false)
if bot_disabled then return nil end
-- TODO: autodetection makes this line wrong
if not is_filled(auto.age) and not is_filled(auto.target) then return nil end
local age = var_or_default(auto.age, nil)
local target = var_or_default(auto.target, nil)
local target_text = ''
if target then
target_text = mw.ustring.format(
cfg.has_archives,
frame:callParserFunction( '#rel2abs', target ),
age and ' ' or ''
)
end
local age_text = ''
if age then
local units = var_or_default(auto.units, cfg.units)
-- there's probably a friendlier l10n way to do this check on units...
-- TODO make it friendlier. maybe split it to a separate function?
-- (borrowed from Module:String.endswith in the meantime)
if age ~= '1' and mw.ustring.sub(units, -1, -1) ~= 's' then
units = units .. 's'
end
-- TODO localize
local age_with_units = age .. ' ' .. units
local has_bot = is_filled(auto.bot)
local has_minthreads = is_filled(auto.minthreads)
if has_bot and has_minthreads then
age_text = mw.ustring.format(
cfg.age_bot_threads,
age_with_units,
wikilink('User:' .. auto.bot, auto.bot),
var_or_default(auto.minthreads, cfg.min_threads)
)
elseif has_bot then
age_text = mw.ustring.format(
cfg.age_bot,
age_with_units,
wikilink('User:' .. auto.bot, auto.bot)
)
elseif has_minthreads then
age_text = mw.ustring.format(
cfg.age_threads,
age_with_units,
var_or_default(auto.minthreads, cfg.min_threads)
)
else
age_text = mw.ustring.format(
cfg.age,
age_with_units
)
end
end
return mw.html.create('div'):addClass('archives-auto'):wikitext(target_text .. age_text)
end
local function edit_list(frame, auto, list1, archive_list, archive_list_exists, editbox)
local wants_editbox = editbox == 'yes' or editbox == nil or editbox == ''
-- bogus criteria? `and not is_filled(auto) and is_filled(list1)`
-- if you've got an archive list you should see the edit box unless you
-- deliberately disable it
if archive_list_exists and wants_editbox then
return mw.html.create('div'):addClass('archives-edit'):wikitext(mw.ustring.format(
cfg.edit_this_box,
archive_list:fullUrl('action=edit')
))
end
end
local function auto_list(root, is_banner, auto, prefix, start)
local list_args = {}
if root then list_args.root = root end
if prefix then list_args.prefix = prefix end
if start then list_args.start = start end
if is_banner then
list_args.nobr = 'yes'
else
list_args.auto = auto or 'long'
list_args.nobr = 'no'
end
return require('Module:Archive list').main(list_args)
end
local function make_title(is_banner, title, archives_disabled, inline_list, index_link, block_list)
if archives_disabled then return end
local title = var_or_default(title, cfg.default_title)
local rendered_title = mw.html.create()
if is_banner then
local needs_colon_space = false
if is_filled(inline_list) then needs_colon_space = true end
if index_link ~= '' then
index_link = mw.ustring.format(' (%s)', index_link)
end
rendered_title:tag('span')
:addClass('archives-title')
:tag('span'):attr('id', 'archives-heading'):wikitext(title):done()
:wikitext(index_link)
:wikitext(needs_colon_space and cfg.colon_space or nil)
-- these should be mutually exclusive
-- should is a famous last word
if inline_list then
rendered_title:tag('span')
:addClass('archives-title-inline-list')
:wikitext(inline_list)
end
if block_list then
rendered_title:tag('div')
:addClass('archives-title-block-list')
:wikitext(block_list)
end
else
if index_link ~= '' then
index_link = mw.ustring.format(' (%s)', index_link)
end
end
return rendered_title
end
local function foreign(auto, list1)
-- this logic is seriously fucking screwy
-- only hope is for the test cases to catch the insanity
local auto_default = true
if list1 then
auto_default = false
end
local is_foreign = true
if (auto and auto == cfg.auto_no) or (not auto and not auto_default) then
is_foreign = false
end
return is_foreign
end
local function make_index(index, auto, list1, list)
local link = ''
if list or not foreign(auto, list1) then return link end
if not index or (index and index == 'no') then return link end
local local_index = mw.getCurrentFrame():callParserFunction(
'#rel2abs',
var_or_default('./' .. index, './Archive index')
)
if mw.title.new(local_index).exists then
link = wikilink(local_index, cfg.default_index_title)
return link
end
local current_title = mw.title.getCurrentTitle()
local cluebot_index = 'User:ClueBot III/Master Detailed Indices/' .. current_title.fullText
if mw.title.new(cluebot_index).exists then
link = wikilink(cluebot_index, cfg.default_index_title)
end
return link
end
local function render_list(
root, auto, list1, archives_disabled, archive_list_title,
archive_list_exists, list, prefix, inline_list, list_start, is_banner
)
if archives_disabled then return nil, nil, nil, nil end
-- the logic continues to be screwy
local is_foreign = foreign(auto, list1)
local inline_title_list
local block_title_list
if not list and is_foreign then
local prefix = var_or_default(prefix, nil)
if archive_list_exists then
block_title_list = '\n' .. mw.getCurrentFrame():expandTemplate{
title = archive_list_title
}
else
inline_title_list = auto_list(root, is_banner, auto, prefix, list_start)
end
end
if is_filled(inline_list) then
inline_title_list = inline_list
end
-- the post title list is always displayed if list or list1 are present
local post_title_list = ''
if list or list1 then
post_title_list = '\n' .. (list or list1)
end
return inline_title_list, block_title_list, post_title_list
end
local function add_main_content(frame, is_banner, content)
local is_collapsible = nil
local is_collapsed = nil
if content.collapsible and content.collapsible == cfg.collapsible_yes then
is_collapsible = true
end
if content.collapsed and content.collapsed == cfg.collapsed_yes then
is_collapsed = true
is_collapsible = true
end
local archives_disabled = var_or_default(content.archives_disabled, false)
local root = var_or_default(content.root, nil)
local auto = var_or_default(content.auto, nil)
local list = var_or_default(content.list, nil)
local list1 = var_or_default(content.list1, nil)
local archive_list_name = frame:callParserFunction(
'#rel2abs',
var_or_default(content.archive_list, cfg.default_archive_list)
)
local archive_list_title = mw.title.new(archive_list_name)
local archive_list_exists = archive_list_title.exists
local inline_title_list, block_title_list, post_title_list = render_list(
root,
auto,
list1,
archives_disabled,
archive_list_title,
archive_list_exists,
list,
content.prefix,
content.inline_list,
content.list_start,
is_banner
)
local index_link = make_index(content.index, auto, list1, list)
local main_content = mw.html.create('div')
main_content
:addClass('archives-flex-child')
:addClass(is_collapsible and 'mw-collapsible')
:addClass(is_collapsed and 'mw-collapsed')
local title_group = make_title(
is_banner, content.title, archives_disabled, inline_title_list, index_link, block_title_list
)
local maybe_collapsed_content = mw.html.create()
:tag('div'):addClass('archives-block-list'):wikitext(post_title_list):done()
:node(search_box(frame, is_banner, root, content.search))
:node(note_auto(frame, content.auto_explanation))
:node(edit_list(
frame, auto, list1, archive_list_title, archive_list_exists, content.edit_box
))
if is_collapsible or is_collapsed then
main_content:tag('div')
:addClass('archives-collapsible-title')
:node(title_group)
main_content:tag('div')
:addClass('mw-collapsible-content')
:node(maybe_collapsed_content)
else
main_content:node(title_group)
main_content:node(maybe_collapsed_content)
end
return main_content
end
function p._main(args, frame)
local is_banner = false
if (args[cfg.arg.banner] and args[cfg.arg.banner] == cfg.banner_yes) or
(args[cfg.arg.large] and args[cfg.arg.large] == cfg.banner_yes) then
is_banner = true
end
local image = args[cfg.arg.image]
local has_image = true
if image and (image == 'none' or image == '') then has_image = false end
local archives = mw.html.create()
local rendered = archives:tag('div')
:addClass('archives plainlinks')
:addClass(is_banner and 'archives-banner' or 'archives-small')
:addClass(has_image and 'archives-with-image' or nil)
-- archives-talk has same-ish styles as tmbox tmbox-notice
-- base styles are same-ish as ombox ombox-notice
:addClass(talk_other(
var_or_default(args[cfg.arg.demospace], nil),
'archives-talk'
))
:css('width', var_or_default(args[cfg.arg.box_width], nil))
:cssText(var_or_default(args[cfg.arg.style], nil))
if has_image then
rendered:node(add_image({
image = image,
alt = args[cfg.arg.alt],
link = args[cfg.arg.link],
size = args[cfg.arg.image_size]
}))
end
rendered:node(add_main_content(frame, is_banner, {
archive_list = args[cfg.arg.archive_list],
archives_disabled = args[cfg.arg.noarchives],
auto = args[cfg.arg.auto],
collapsible = args[cfg.arg.collapsible],
collapsed = args[cfg.arg.collapsed],
edit_box = args[cfg.arg.edit_box],
index = args[cfg.arg.index],
inline_list = args[cfg.arg.inline_list],
list = args[cfg.arg.list],
list1 = args[cfg.arg.list1],
list_start = args[cfg.arg.start],
prefix = args[cfg.arg.prefix],
root = args[cfg.arg.root],
title = args[cfg.arg.title],
search = {
search = args[cfg.arg.search],
prefix = args[cfg.arg.search_prefix],
width = args[cfg.arg.search_width],
sbreak = args[cfg.arg.search_break],
label = args[cfg.arg.search_button_label],
placeholder = args[cfg.arg.search_placeholder]
},
auto_explanation = {
age = args[cfg.arg.age],
target = args[cfg.arg.target],
units = args[cfg.arg.units],
bot = args[cfg.arg.bot],
minthreads = args[cfg.arg.minthreads],
nobot = args[cfg.arg.nobot]
}
}))
return frame:extensionTag{
name = 'templatestyles', args = { src = cfg.templatestyles }
} .. tostring(archives)
end
function p.main(frame)
return p._main(require('Module:Arguments').getArgs(frame), frame)
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.