14,061
edits
m (1 revision) |
No edit summary |
||
Line 1: | Line 1: | ||
-- | ---------------------------------------------------------------------------------------------------- | ||
-------------------------------------------------------------------------------- | -- -- | ||
-- | -- NAMESPACE DETECT -- | ||
-- | -- -- | ||
-- | -- This module implements the {{namespace detect}} template in Lua, with a few -- | ||
-- This module implements the {{namespace detect}} template in Lua, with a | -- improvements: all namespaces and all namespace aliases are supported, and namespace -- | ||
-- | -- names are detected automatically for the local wiki. The module can also use the -- | ||
-- | -- corresponding subject namespace value if it is used on a talk page. Parameter names -- | ||
-- | -- can be configured for different wikis by altering the values in the "cfg" table. -- | ||
-- -- | |||
---------------------------------------------------------------------------------------------------- | |||
-- | |||
-- | |||
-------------------------------------------------------------------------------- | |||
-- | |||
local | ---------------------------------------------------------------------------------------------------- | ||
-- Configuration data -- | |||
-- Language-specific parameter names can be set here. -- | |||
---------------------------------------------------------------------------------------------------- | |||
local cfg = {} | |||
-- This parameter displays content for the main namespace: | |||
cfg.main = 'main' | |||
-- This parameter displays in talk namespaces: | |||
cfg.talk = 'talk' | |||
-- This parameter displays content for "other" namespaces (namespaces for which | |||
-- parameters have not been specified, or for when cfg.demospace is set to cfg.other): | |||
cfg.other = 'other' | |||
-- This parameter makes talk pages behave as though they are the corresponding subject namespace. | |||
-- Note that this parameter is used with [[Module:Yesno]]. Edit that module to change | |||
-- the default values of "yes", "no", etc. | |||
cfg.subjectns = 'subjectns' | |||
-- This parameter sets a demonstration namespace: | |||
cfg.demospace = 'demospace' | |||
-- This parameter sets a specific page to compare: | |||
cfg.page = 'page' | |||
-- The header for the namespace column in the wikitable containing the list of possible subject-space parameters. | |||
cfg.wikitableNamespaceHeader = 'Namespace' | |||
-- The header for the wikitable containing the list of possible subject-space parameters. | |||
cfg.wikitableAliasesHeader = 'Aliases' | |||
---------------------------------------------------------------------------------------------------- | |||
-- End configuration data -- | |||
---------------------------------------------------------------------------------------------------- | |||
local yesno = require('Module:Yesno') | local yesno = require('Module:Yesno') | ||
local p = {} | local p = {} | ||
function p.getPageObject(page) | function p.getPageObject(page) | ||
-- Get the page object, passing the function through pcall in case | -- Get the page object, passing the function through pcall in case we are over the expensive function count limit. | ||
if page then | if page then | ||
local | local noError, pageObject = pcall(mw.title.new, page) | ||
if | if not noError then | ||
return nil | |||
else | |||
return pageObject | return pageObject | ||
end | end | ||
else | else | ||
Line 65: | Line 67: | ||
end | end | ||
function p.getParamMappings() | function p.getParamMappings() | ||
--[[ Returns a table of how parameter names map to namespace names. The keys are the actual namespace | |||
names, in lower case, and the values are the possible parameter names for that namespace, also in | |||
lower case. The table entries are structured like this: | |||
{ | |||
[''] = {'main'}, | |||
['wikipedia'] = {'wikipedia', 'project', 'wp'}, | |||
... | |||
} | |||
]] | |||
local mappings = {} | |||
mappings[mw.ustring.lower(mw.site.namespaces[0].name)] = {cfg.main} | |||
mappings[cfg.talk] = {cfg.talk} | |||
for nsid, ns in pairs(mw.site.subjectNamespaces) do | |||
if nsid ~= 0 then -- Exclude main namespace. | |||
local nsname = mw.ustring.lower(ns.name) | |||
local canonicalName = mw.ustring.lower(ns.canonicalName) | |||
mappings[nsname] = {nsname} | |||
if canonicalName ~= nsname then | |||
table.insert(mappings[nsname], canonicalName) | |||
end | |||
for _, alias in ipairs(ns.aliases) do | |||
table.insert(mappings[nsname], mw.ustring.lower(alias)) | |||
end | |||
end | |||
end | |||
return mappings | return mappings | ||
end | end | ||
local function getNamespace(args) | local function getNamespace(args) | ||
-- | -- Gets the namespace name from the page object. | ||
local page = | local page = args[cfg.page] | ||
local demospace = args[cfg.demospace] | |||
local subjectns = args[cfg.subjectns] | |||
local demospace = | |||
local subjectns = | |||
local ret | local ret | ||
if demospace then | if demospace then | ||
-- Handle "demospace = main" properly. | -- Handle "demospace = main" properly. | ||
if | if mw.ustring.lower(demospace) == cfg.main then | ||
ret = mw.site.namespaces[0].name | ret = mw.site.namespaces[0].name | ||
else | else | ||
Line 93: | Line 113: | ||
if pageObject then | if pageObject then | ||
if pageObject.isTalkPage then | if pageObject.isTalkPage then | ||
-- | -- If cfg.subjectns is set, get the subject namespace, otherwise use cfg.talk. | ||
if yesno(subjectns) then | if yesno(subjectns) then | ||
ret = mw.site.namespaces[pageObject.namespace].subject.name | ret = mw.site.namespaces[pageObject.namespace].subject.name | ||
else | else | ||
ret = | ret = cfg.talk | ||
end | end | ||
else | else | ||
Line 107: | Line 126: | ||
end | end | ||
end | end | ||
ret = | ret = mw.ustring.gsub(ret, '_', ' ') | ||
return | return mw.ustring.lower(ret) | ||
end | end | ||
function p._main(args) | function p._main(args) | ||
-- | -- Get the namespace to compare the parameters to, and the parameter mapping table. | ||
local namespace = getNamespace(args) | local namespace = getNamespace(args) | ||
local mappings = p.getParamMappings() | |||
-- Check for any matches in the namespace arguments. The order we check them doesn't matter, | |||
-- as there can only be one match. | |||
-- If there were no matches, return parameters for other namespaces. | for ns, params in pairs(mappings) do | ||
-- | if ns == namespace then | ||
-- Check all aliases for matches. The default local namespace is checked first, as | |||
-- {{namespace detect}} checked these before alias names. | |||
for _, param in ipairs(params) do | |||
if args[param] ~= nil then | |||
return args[param] | |||
end | |||
end | |||
end | |||
end | |||
-- If there were no matches, return parameters for other namespaces. This happens if there | |||
-- was no text specified for the namespace that was detected or if the demospace parameter | |||
-- is not a valid namespace. Note that the parameter for the detected namespace must be | |||
-- completely absent for this to happen, not merely blank. | -- completely absent for this to happen, not merely blank. | ||
if args[cfg.other] ~= nil then | |||
return args[cfg.other] | |||
end | end | ||
end | end | ||
function p.main(frame) | function p.main(frame) | ||
-- If called via #invoke, use the args passed into the invoking template, or the args | |||
-- passed to #invoke if any exist. Otherwise assume args are being passed directly in. | |||
local origArgs | |||
if frame == mw.getCurrentFrame() then | |||
origArgs = frame:getParent().args | |||
for k, v in pairs(frame.args) do | |||
origArgs = frame.args | |||
-- | break | ||
-- | |||
end | end | ||
else | |||
origArgs = frame | |||
end | end | ||
-- Trim whitespace and remove blank arguments for demospace and page parameters. | |||
local args = {} | |||
for k, v in pairs(origArgs) do | |||
-- | if type(v) == 'string' then | ||
local | v = mw.text.trim(v) -- Trim whitespace. | ||
for | end | ||
if | if k == cfg.demospace or k == cfg.page then | ||
if v ~= '' then | |||
args[k] = v | |||
end | |||
else | |||
args[k] = v | |||
end | end | ||
end | end | ||
return p._main(args) | |||
end | |||
-- | function p.table(frame) | ||
--[[ Create a wikitable of all subject namespace parameters, for documentation purposes. The talk | |||
parameter is optional, in case it needs to be excluded in the documentation. | |||
]] | |||
local useTalk = type(frame) == 'table' and type(frame.args) == 'table' and frame.args.talk == 'yes' -- Whether to use the talk parameter. | |||
local mappings = p.getParamMappings() | |||
-- Start the wikitable. | |||
local ret = '{| class="wikitable"' | local ret = '{| class="wikitable"' | ||
.. '\n|-' | .. '\n|-' | ||
.. '\n! ' .. | .. '\n! ' .. cfg.wikitableNamespaceHeader | ||
.. '\n! ' .. | .. '\n! ' .. cfg.wikitableAliasesHeader | ||
-- Generate the row for the main namespace, as we want this to be first in the list. | |||
ret = ret .. '\n|-' | |||
.. '\n| <code>' .. cfg.main .. '</code>' | |||
.. '\n|' | |||
if useTalk then | |||
ret = ret .. '\n|-' | |||
.. '\n| <code>' .. cfg.talk .. '</code>' | |||
.. '\n|' | |||
end | |||
-- Enclose all parameter names in <code> tags. | |||
for ns, params in pairs(mappings) do | |||
if ns ~= mw.site.namespaces[0].name then | |||
for i, param in ipairs(params) do | |||
mappings[ns][i] = '<code>' .. param .. '</code>' | |||
end | end | ||
end | end | ||
end | end | ||
-- Generate the other wikitable rows. | |||
for ns, params in pairs(mappings) do | |||
if ns ~= mw.site.namespaces[0].name then -- Ignore the main namespace. | |||
ret = ret .. '\n|-' | |||
.. '\n| ' .. params[1] | |||
.. '\n| ' .. table.concat(params, ', ', 2) | |||
end | |||
end | |||
-- End the wikitable. | |||
ret = ret .. '\n|-' | ret = ret .. '\n|-' | ||
.. '\n|}' | .. '\n|}' |