14,061
edits
m (1 revision) |
m (1 revision) |
||
(One intermediate revision by the same user not shown) | |||
Line 5: | Line 5: | ||
-- This module implements the {{namespace detect}} template in Lua, with a few -- | -- This module implements the {{namespace detect}} template in Lua, with a few -- | ||
-- improvements: all namespaces and all namespace aliases are supported, and namespace -- | -- improvements: all namespaces and all namespace aliases are supported, and namespace -- | ||
-- names are detected automatically for the local wiki. | -- names are detected automatically for the local wiki. The module can also use the -- | ||
-- for different wikis by altering the values in the "cfg" table. | -- 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. -- | |||
-- -- | -- -- | ||
---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ||
Line 17: | Line 18: | ||
local cfg = {} | local cfg = {} | ||
-- | -- This parameter displays content for the main namespace: | ||
cfg.main = 'main' | cfg.main = 'main' | ||
-- | -- This parameter displays in talk namespaces: | ||
cfg.talk = 'talk' | 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): | -- parameters have not been specified, or for when cfg.demospace is set to cfg.other): | ||
cfg.other = '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' | cfg.demospace = 'demospace' | ||
-- | -- This parameter sets a specific page to compare: | ||
cfg.page = 'page' | cfg.page = 'page' | ||
-- The header for the namespace column in the wikitable containing the list of possible | -- The header for the namespace column in the wikitable containing the list of possible subject-space parameters. | ||
cfg.wikitableNamespaceHeader = 'Namespace' | cfg.wikitableNamespaceHeader = 'Namespace' | ||
Line 44: | Line 49: | ||
---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ||
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 we are over the expensive function count limit. | |||
if page then | |||
local noError, pageObject = pcall(mw.title.new, page) | |||
if not noError then | |||
return nil | |||
else | |||
return pageObject | |||
end | |||
else | |||
return mw.title.getCurrentTitle() | |||
end | |||
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 | |||
end | end | ||
-- Gets the namespace name | local function getNamespace(args) | ||
local | -- Gets the namespace name from the page object. | ||
local page = args[cfg.page] | |||
local demospace = args[cfg.demospace] | |||
local subjectns = args[cfg.subjectns] | |||
local ret | |||
if demospace then | |||
-- Handle "demospace = main" properly. | |||
if mw.ustring.lower(demospace) == cfg.main then | |||
ret = mw.site.namespaces[0].name | |||
else | |||
ret = demospace | |||
end | |||
else | |||
local pageObject = p.getPageObject(page) | |||
if pageObject then | |||
if pageObject.isTalkPage then | |||
-- If cfg.subjectns is set, get the subject namespace, otherwise use cfg.talk. | |||
if yesno(subjectns) then | |||
ret = mw.site.namespaces[pageObject.namespace].subject.name | |||
else | |||
ret = cfg.talk | |||
end | |||
else | |||
ret = pageObject.nsText | |||
end | |||
else | |||
return nil -- return nil if the page object doesn't exist. | |||
end | |||
end | |||
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 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. | -- as there can only be one match. | ||
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. | -- {{namespace detect}} checked these before alias names. | ||
for _, param in ipairs(params) do | |||
if args[param] 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 | -- 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 | -- 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] then | |||
return args[cfg.other] | |||
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. | -- 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 | |||
else | |||
origArgs = frame | |||
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 | |||
v = mw.text.trim(v) -- Trim whitespace. | |||
end | |||
if k == cfg.demospace or k == cfg.page then | |||
if v ~= '' then | |||
args[k] = v | |||
end | |||
else | |||
args[k] = v | |||
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"' | |||
.. '\n|-' | |||
.. '\n! ' .. cfg.wikitableNamespaceHeader | |||
.. '\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 | |||
-- 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|-' | |||
.. '\n|}' | |||
return ret | |||
end | end | ||
return p | return p |