Module:Namespace detect
Documentation for this module may be created at Module:Namespace detect/doc
----------------------------------------------------------------------
-- --
-- NAMESPACE DETECT --
-- --
-- This module implements the {{namespace detect}} template --
-- in Lua, with a few improvements: all namespaces and all --
-- namespace aliases are supported, and namespace names are --
-- detected automatically for the local wiki. Function names --
-- can be configured for different wikis by altering the --
-- values in the "cfg" table. --
-- --
----------------------------------------------------------------------
----------------------------------------------------------------------
-- Configuration data --
-- Language-specific parameter names can be set here. --
----------------------------------------------------------------------
local cfg = {}
-- The name for the parameter to display content for the main namespace:
cfg.main = 'main'
-- The name for the parameter to display content in talk namespaces:
cfg.talk = 'talk'
-- The name for the parameter to display 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'
-- The name for the parameter to set a demonstration namespace:
cfg.demospace = 'demospace'
-- The name for the parameter to set 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 --
----------------------------------------------------------------------
-- Specify variables available to the whole module
local p = {}
local args = {}
-- Get the page object. This will return the page object for the page
-- specified, or nil if there are errors in the title or if the
-- expensive function count has been exceeded.
local function getPageObject()
-- Get the title object for args.page if it is specified. Otherwise
-- get the title object for the current page.
if args[cfg.page] then
-- Get the page object, passing the function through pcall
-- in case we are over the expensive function count limit.
local noError, pageObject = pcall(mw.title.new, args[cfg.page])
if not noError then
return nil
else
return pageObject
end
else
return mw.title.getCurrentTitle()
end
end
-- Detects the namespace for a page object.
local function detectNamespace(pageObject)
if pageObject.isTalkPage then
-- Returns the value of cfg.talk or the local "Talk" namespace name.
return cfg.talk or mw.site.namespaces[1].name
else
return pageObject.nsText
end
end
-- Gets the namespace name to compare to the arguments. The returned value
-- is lower-case.
local function getNamespace()
local ret
if args[cfg.demospace] then
-- Handle "demospace = main" properly.
if mw.ustring.lower( args[cfg.demospace] ) == cfg.main then
ret = mw.site.namespaces[0].name
else
ret = args[cfg.demospace]
end
else
local pageObject = getPageObject()
if pageObject then
ret = detectNamespace( getPageObject() )
else
return nil -- return nil if the page object doesn't exist.
end
end
return mw.ustring.lower(ret)
end
-- Compare the namespace found with the parameters that have been
-- specified, and return content of the appropriate parameter.
local function compare()
local namespace = getNamespace()
-- First, compare mainspace parameters.
if namespace == mw.site.namespaces[0].name and args[cfg.main] then
return args[cfg.main]
end
-- Next, compare parameters for non-main namespaces.
for nsid, ns in pairs( mw.site.namespaces ) do
local nsname = mw.ustring.lower( ns.name )
local canonicalName = mw.ustring.lower( ns.canonicalName )
-- Check the namespace, and ignore main namespace values.
if nsid ~= 0 and nsname == namespace then
-- Check local namespace name.
if args[nsname] then
return args[nsname]
-- Check canonical namespace name.
elseif args[canonicalName] then
return args[canonicalName]
else
-- Check alias names.
for _, alias in ipairs( ns.aliases ) do
local aliasArg = args[ mw.ustring.lower( alias ) ]
if aliasArg then
return aliasArg
end
end
end
end
end
-- Finally, 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.
if args[cfg.other] then
return args[cfg.other]
end
end
-- Process the arguments.
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
else
origArgs = frame
end
-- Trim whitespace and remove blank arguments for demospace and
-- page parameters.
for k, v in pairs(origArgs) do
v = mw.text.trim(v) -- Trim whitespace.
if k == cfg.demospace or k == cfg.page then
if v ~= '' then
args[k] = v
end
else
args[k] = v
end
end
return compare()
end
-- Create a wikitable of all possible namespace parameters.
function p.table()
-- Start the wikitable.
local ret = '{| class="wikitable"'
.. '\n|-'
.. '\n! ' .. cfg.wikitableNamespaceHeader
.. '\n! ' .. cfg.wikitableAliasesHeader
-- Generate the row for the main namespace.
ret = ret .. '\n|-'
.. '\n| ' .. cfg.main
.. '\n|'
-- Generate the other wikitable rows.
for nsid, ns in pairs( mw.site.subjectNamespaces ) do
if nsid ~= 0 then -- Ignore the main namespace, as it is set in cfg.
local name = '<code>' .. mw.ustring.lower( ns.name ) .. '</code>'
local aliases = {}
if ns.canonicalName ~= ns.name then
table.insert( aliases, '<code>' .. mw.ustring.lower( ns.canonicalName ) .. '</code>' )
end
for _, v in ipairs( ns.aliases ) do
table.insert( aliases, '<code>' .. mw.ustring.lower(v) .. '</code>' )
end
ret = ret .. '\n|-'
.. '\n| ' .. name
.. '\n| ' .. table.concat( aliases, ', ' )
end
end
-- End the wikitable.
ret = ret .. '\n|-'
.. '\n|}'
return ret
end
return p