This module depends on the following other modules: |
This module is used by a number of modules and templates, chiefly {{header}}. Check test results at Template:Header/testcases and Template:Translation header/testcases.
--[=[
This is a module to implement logic for [[Template:Header]] and [[Template:Translation header]]
TODO:
- centuries are defined as starting on XX01, but WS categorizes them as starting on XX00
-- check whether that's a considered policy choice
]=]
require('strict')
local p = {} --p stands for package
local yesno = require('Module:Yesno')
local getArgs = require('Module:Arguments').getArgs
local TableTools = require('Module:TableTools')
local ISO_639_language_name = require('Module:ISO 639').language_name
local parent_links = require('Module:Auto parents')._parent_links
local construct_header = require('Module:Header structure').construct_header
local headerAttributions = require('Module:Header/attribution')
local construct_defaultsort = require('Module:Header/sort')._construct_defaultsort
local construct_year = require('Module:Header/year').construct_year
local current_title = mw.title.getCurrentTitle()
--[=[
Wrap stylesheet in noexport div
]=]
local function get_noexport_stylesheet(template)
return tostring(mw.html.create('div'):addClass('ws-noexport'):wikitext(mw.getCurrentFrame():extensionTag('templatestyles', '', {src = template .. '/styles.css'})))
end
--[=[
Get badge if any
]=]
local function badge()
return ''
end
--[=[
Detect explicit formatting in fields like 'section' and 'title'
]=]
local function explicit_formatting(str)
return str and (string.match(str, "\'\'\'?") or string.match(str, '<%s*/?%s*[iIbB]%s*>'))
-- add more cases here or come up with a less silly way to do things
end
local function check_non_existent_author_pages(args, categories, checkArgs)
-- check for cases that aren't supposed to produce a valid link
local param = checkArgs.param
local tracking_cat = checkArgs.tracking_cat or 'Works with non-existent author pages'
if not param or not args[param] or yesno(args[param .. '-nolink']) then
return
end
local lower_arg = string.lower(args[param])
local attr_data = headerAttributions.attr_data[param] or headerAttributions.attr_data[string.gsub(param, 'section%-', '')]
if attr_data and attr_data['special_cases'] and attr_data['special_cases'][lower_arg] then
return
end
-- check if page exists
local target = mw.title.makeTitle('Author', args[param])
-- expensive function!
if not target or not target.exists then
table.insert(categories, tracking_cat)
end
return
end
--[=[
Dont make categories... we are not Wikisource!
]=]
local function construct_categories(args, argsWithBlanks)
return ""
end
--[=[
For debugging
]=]
--[=[
function p.construct_categories(args)
return construct_categories(args, args)
end
]=]
--[=[
Assemble the title
]=]
local function header_title(args)
local title = args.title or ''
local titleSpan = tostring(mw.html.create('span'):attr('id', 'header-title-text'):wikitext(title))
local year = construct_year(args)
local attr = headerAttributions.construct_attributions(args)
local section = headerAttributions.construct_section(args)
if attr ~= '' and title ~= '' then
attr = tostring(mw.html.create('br'):attr('id', 'header-title-break')) .. attr
end
return table.concat({titleSpan, year, attr, section})
end
local function get_languages(args, prefix)
prefix = (prefix and prefix .. '%-') or ''
-- language handling
local languages = {}
for k, v in pairs(args) do
local n
local nText = string.match(k, '^' .. prefix .. 'language%d*$')
if nText then
n = string.gsub(nText, 'language(%d*)$', '%1')
n = tonumber(n) or 1
languages[n] = v
end
end
languages = TableTools.compressSparseArray(languages)
if #languages == 0 then
return {}
end
local language_name
local language_names = {}
for i, lang in ipairs(languages) do
local name = ISO_639_language_name(lang)
if name then
table.insert(language_names, name)
end
end
if #language_names == 1 then
language_name = language_names[1]
elseif #language_names > 1 then
language_name = table.concat(language_names, ', ', 1, #language_names - 1) .. ' and ' .. language_names[#language_names]
end
return {
languages = languages,
language_name = language_name
}
end
--[=[
[[Template:Header]]
]=]
function p._header(args, argsWithBlanks)
argsWithBlanks = argsWithBlanks or args
-- aliases
local dup_cat
local newArgs = {}
local aliases = {
['section-author'] = 'contributor',
['section-translator'] = 'contributing%-translator'
}
for k, v in pairs(args) do
local newkey = string.lower(string.gsub(string.gsub(tostring(k), '_', '-'), ' ', '-'))
for arg, alias in pairs(aliases) do
newkey = string.gsub(newkey, alias, arg)
end
if newkey ~= tostring(k) then
if argsWithBlanks[newkey] then
dup_cat = 'Pages using duplicate arguments in template calls'
end
if not args[newkey] then
newArgs[newkey] = newArgs[newkey] or v
end
end
if newkey == 'testing' or newkey == 'nocat' or newkey == 'nolanguagecat' or newkey == 'language-required' or string.match(newkey, '%-nolink$') then
newArgs[newkey] = newArgs[newkey] or yesno(v)
end
end
for k, v in pairs(newArgs) do
args[k] = v
argsWithBlanks[k] = v
end
if dup_cat then
table.insert(categories, dup_cat)
end
args.sortkey = args.defaultsort or args.sortkey
-- default values
args.template_name = args.template_name or 'Header'
if args.testing == nil then
args.testing = current_title.fullText == 'Template:Header/testcases' or current_title.fullText == 'Template:Translation header/testcases'
end
-- noyearcat has different behavior for nil and false
args.noyearcat = args.nocat == true or nil
local language_res = get_languages(args)
args.languages = language_res.languages
args.language_name = language_res.language_name
local section_language_res = get_languages(args, 'section')
args.section_languages = section_language_res.languages
args.section_language_name = section_language_res.language_name
if not args['interwiki-prefix'] and args['languages'] then
if #(args['languages']) > 1 then
args['interwiki-prefix'] = 'mul'
else
args['interwiki-prefix'] = args['languages'][1]
end
end
-- add values to argsWithBlanks
for k, v in pairs(args) do
if not argsWithBlanks[k] then
argsWithBlanks[k] = v
end
end
-- default values for title and section (allow override by setting to blank)
if not argsWithBlanks['title'] then
args['title'] = parent_links({})
argsWithBlanks['title'] = args['title']
end
if not argsWithBlanks['section'] and current_title.isSubpage then
args['section'] = current_title.subpageText
argsWithBlanks['section'] = args['section']
end
-- header args
args.pre_container = badge()
args.header_class = 'wst-header ws-header ws-noexport noprint dynlayout-exempt ' .. (args.header_class or '')
args.main_class = 'headertemplate'
-- title
args.main_title = header_title(args)
-- FIXME: just use Wikidata instead of interwiki links?
local interwiki = ''
if args.template_name == 'Translation header' and args['interwiki-prefix'] then
interwiki = tostring(mw.html.create('span'):addClass('interwiki-info'):attr('id', args['interwiki-prefix']):attr('title', '(original)'))
if args.original and (args['interwiki-prefix'] == 'ang' or args['interwiki-prefix'] == 'enm' or args['interwiki-prefix'] == 'sco') then
-- cycle to mul.ws and back around to en.ws
interwiki = interwiki .. '[[' .. args['interwiki-prefix'] .. ':en:' .. args.original .. ']]'
elseif args.original then
-- general interwiki link
interwiki = interwiki .. '[[' .. args['interwiki-prefix'] .. ':' .. args.original .. ']]'
end
end
-- set defaultsort tracking categories
args.equalsortcat = '[[Category:' .. 'Headers with DefaultSort equal to page title' .. ']]'
args.diffsortcat = '[[Category:' .. 'Headers applying DefaultSort key' .. ']]'
args.post_notes = table.concat({
headerAttributions.construct_microformat(args),
construct_categories(args, argsWithBlanks),
construct_defaultsort(args),
interwiki
})
return get_noexport_stylesheet('Header') .. construct_header(args)
end
function p.header(frame)
return p._header(
getArgs(frame),
getArgs(frame, {removeBlanks = false})
)
end
--[=[
[[Template:Translation header]]
]=]
function p._translation_header(args, argsWithBlanks)
argsWithBlanks = argsWithBlanks or args
args.header_class = 'wst-translation-header'
args.template_name = 'Translation header'
args.notes_class = 'header-notes'
args['language-required'] = true
return get_noexport_stylesheet('Translation header') .. p._header(args, argsWithBlanks)
end
function p.translation_header(frame)
return p._translation_header(
getArgs(frame),
getArgs(frame, {removeBlanks = false})
)
end
return p