Modul:Namespace detect: Unterschied zwischen den Versionen
allow access to the p._main() function from other modules, add an option to use the cfg.talk parameter in p.table(), and whitespace tweaks
(Die Seite wurde neu angelegt: „---------------------------------------------------------------------- -- -- -- …“) |
(allow access to the p._main() function from other modules, add an option to use the cfg.talk parameter in p.table(), and whitespace tweaks) |
||
| Zeile 1: | Zeile 1: | ||
---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ||
-- | -- -- | ||
-- | -- NAMESPACE DETECT -- | ||
-- | -- -- | ||
-- This module implements the {{namespace detect}} template | -- 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 -- | |||
-- detected automatically for the local wiki. Function names | -- for different wikis by altering the values in the "cfg" table. -- | ||
-- | -- -- | ||
---------------------------------------------------------------------------------------------------- | |||
-- | |||
---------------------------------------------------------------------- | |||
---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ||
-- | -- Configuration data -- | ||
-- Language-specific parameter names can be set here. | -- Language-specific parameter names can be set here. -- | ||
---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ||
local cfg = {} | local cfg = {} | ||
| Zeile 23: | Zeile 21: | ||
-- The name for the parameter to display content in talk namespaces: | -- The name for the parameter to display content in talk namespaces: | ||
cfg.talk = ' | cfg.talk = 'talk' | ||
-- The name for the parameter to display content for "other" namespaces | -- 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' | cfg.other = 'other' | ||
| Zeile 34: | Zeile 31: | ||
-- The name for the parameter to set a specific page to compare: | -- The name for the parameter to set a specific page to compare: | ||
cfg.page = ' | cfg.page = 'page' | ||
-- The header for the namespace column in the wikitable containing the | -- The header for the namespace column in the wikitable containing the list of possible | ||
-- | -- subject-space parameters. | ||
cfg.wikitableNamespaceHeader = 'Namespace' | cfg.wikitableNamespaceHeader = 'Namespace' | ||
-- The header for the wikitable containing the list of possible | -- The header for the wikitable containing the list of possible subject-space parameters. | ||
cfg.wikitableAliasesHeader = 'Aliases' | cfg.wikitableAliasesHeader = 'Aliases' | ||
---------------------------------- | ---------------------------------------------------------------------------------------------------- | ||
-- End configuration data -- | |||
---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ||
---------------------------------------------------------------------- | |||
-- Declare the table of functions to return. | -- Declare the table of functions to return. | ||
local p = {} | local p = {} | ||
-- Get the page object. This will return the page object for the page | -- 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. | |||
function p.getPageObject(page) | |||
function p.getPageObject( page ) | |||
if page then | if page then | ||
-- Get the page object, passing the function through pcall | -- 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, page) | local noError, pageObject = pcall(mw.title.new, page) | ||
if not noError then | if not noError then | ||
| Zeile 78: | Zeile 64: | ||
end | end | ||
--[[ Returns a table of how parameter names map to namespace names. | --[[ Returns a table of how parameter names map to namespace names. The keys are the actual namespace | ||
The keys are the actual namespace names, in lower case, and the | names, in lower case, and the values are the possible parameter names for that namespace, also in | ||
values are the possible parameter names for that namespace, also | lower case. The table entries are structured like this: | ||
[''] = { | [''] = { | ||
{'main'}, | {'main'}, | ||
}, | }, | ||
['wikipedia'] = { | ['wikipedia'] = { | ||
{'wikipedia', 'project', 'wp' } | {'wikipedia', 'project', 'wp'} | ||
} | } | ||
]] | ]] | ||
function p.getParamMappings() | function p.getParamMappings() | ||
local mappings = {} | local mappings = {} | ||
mappings[mw.ustring.lower( mw.site.namespaces[0].name )] = { cfg.main } | mappings[mw.ustring.lower(mw.site.namespaces[0].name)] = {cfg.main} | ||
mappings[cfg.talk] = { cfg.talk } | mappings[cfg.talk] = {cfg.talk} | ||
for nsid, ns in pairs( mw.site.subjectNamespaces ) do | for nsid, ns in pairs(mw.site.subjectNamespaces) do | ||
if nsid ~= 0 then -- Exclude main namespace. | if nsid ~= 0 then -- Exclude main namespace. | ||
local nsname = mw.ustring.lower( ns.name ) | local nsname = mw.ustring.lower(ns.name) | ||
local canonicalName = mw.ustring.lower( ns.canonicalName ) | local canonicalName = mw.ustring.lower(ns.canonicalName) | ||
mappings[nsname] = { nsname } | mappings[nsname] = {nsname} | ||
if canonicalName ~= nsname then | if canonicalName ~= nsname then | ||
table.insert( mappings[nsname], canonicalName ) | table.insert(mappings[nsname], canonicalName) | ||
end | end | ||
for _, alias in ipairs( ns.aliases ) do | for _, alias in ipairs(ns.aliases) do | ||
table.insert( mappings[nsname], mw.ustring.lower( alias ) ) | table.insert(mappings[nsname], mw.ustring.lower(alias)) | ||
end | end | ||
end | end | ||
| Zeile 109: | Zeile 94: | ||
end | end | ||
--[[ Create a wikitable of all subject namespace parameters, for documentation | --[[ 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. | |||
]] | ]] | ||
function p.table() | function p.table(frame) | ||
-- Find whether to use the talk link or not. | |||
local useTalk = type(frame) == 'table' and type(frame.args) == 'table' and frame.args.talk == 'yes' | |||
-- Get the parameter mappings. | -- Get the parameter mappings. | ||
local mappings = p.getParamMappings() | local mappings = p.getParamMappings() | ||
| Zeile 128: | Zeile 115: | ||
.. '\n| <code>' .. cfg.main .. '</code>' | .. '\n| <code>' .. cfg.main .. '</code>' | ||
.. '\n|' | .. '\n|' | ||
if useTalk then | |||
ret = ret .. '\n|-' | |||
.. '\n| <code>' .. cfg.talk .. '</code>' | |||
.. '\n|' | |||
end | |||
-- Enclose all parameter names in <code> tags. | -- Enclose all parameter names in <code> tags. | ||
for ns, params in pairs( mappings ) do | for ns, params in pairs(mappings) do | ||
if ns ~= mw.site.namespaces[0].name then | if ns ~= mw.site.namespaces[0].name then | ||
for i, param in ipairs( params ) do | for i, param in ipairs(params) do | ||
mappings[ns][i] = '<code>' .. param .. '</code>' | mappings[ns][i] = '<code>' .. param .. '</code>' | ||
end | end | ||
| Zeile 139: | Zeile 132: | ||
-- Generate the other wikitable rows. | -- Generate the other wikitable rows. | ||
for ns, params in pairs( mappings ) do | for ns, params in pairs(mappings) do | ||
if ns ~= mw.site.namespaces[0].name then -- Ignore the main namespace. | if ns ~= mw.site.namespaces[0].name then -- Ignore the main namespace. | ||
ret = ret .. '\n|-' | ret = ret .. '\n|-' | ||
.. '\n| ' .. params[1] | .. '\n| ' .. params[1] | ||
.. '\n| ' .. table.concat( params, ', ', 2 ) | .. '\n| ' .. table.concat(params, ', ', 2) | ||
end | end | ||
end | end | ||
| Zeile 154: | Zeile 147: | ||
end | end | ||
-- Gets the namespace name to compare to the arguments. The returned value is lower-case. | |||
local function getNamespace(page, demospace) | |||
-- Gets the namespace name to compare to the arguments. The returned value | |||
local function getNamespace( page, demospace ) | |||
local ret | local ret | ||
if demospace then | if demospace then | ||
-- Handle "demospace = main" properly. | -- Handle "demospace = main" properly. | ||
if mw.ustring.lower( demospace ) == cfg.main then | if mw.ustring.lower(demospace) == cfg.main then | ||
ret = mw.site.namespaces[0].name | ret = mw.site.namespaces[0].name | ||
else | else | ||
| Zeile 172: | Zeile 158: | ||
end | end | ||
else | else | ||
local pageObject = p.getPageObject( page ) | local pageObject = p.getPageObject(page) | ||
if pageObject then | if pageObject then | ||
if pageObject.isTalkPage then | if pageObject.isTalkPage then | ||
-- {{namespace detect}} uses the same value for all talk | -- {{namespace detect}} uses the same value for all talk namespaces, so that's what | ||
-- the module should do too. | |||
ret = cfg.talk | ret = cfg.talk | ||
else | else | ||
| Zeile 188: | Zeile 174: | ||
end | end | ||
-- Compare the namespace found with the parameters that have been | -- Compare the namespace found with the parameters that have been specified, and return content of | ||
-- the appropriate parameter. | |||
function p._main(args) | |||
-- Get the namespace to compare the parameters to, and the parameter | -- Get the namespace to compare the parameters to, and the parameter mapping table. | ||
local namespace = getNamespace(args[cfg.page], args[cfg.demospace]) | |||
local namespace = getNamespace( args[cfg.page], args[cfg.demospace] ) | |||
local mappings = p.getParamMappings() | local mappings = p.getParamMappings() | ||
-- Check for any matches in the namespace arguments. The order we check | -- Check for any matches in the namespace arguments. The order we check them doesn't matter, | ||
-- as there can only be one match. | |||
for ns, params in pairs( mappings ) do | for ns, params in pairs(mappings) do | ||
if ns == namespace then | if ns == namespace then | ||
-- Check all aliases for matches. The default local namespace is | -- 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 | |||
for _, param in ipairs( params ) do | |||
if args[param] then | if args[param] then | ||
return args[param] | return args[param] | ||
| Zeile 211: | Zeile 195: | ||
end | end | ||
-- If there were no matches, return parameters for other namespaces. | -- 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. | |||
if args[cfg.other] then | if args[cfg.other] then | ||
return args[cfg.other] | 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 | -- 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 | local origArgs | ||
if frame == mw.getCurrentFrame() then | if frame == mw.getCurrentFrame() then | ||
origArgs = frame:getParent().args | origArgs = frame:getParent().args | ||
for k, v in pairs( frame.args ) do | for k, v in pairs(frame.args) do | ||
origArgs = frame.args | origArgs = frame.args | ||
break | break | ||
| Zeile 244: | Zeile 218: | ||
end | end | ||
-- Trim whitespace and remove blank arguments for demospace and | -- Trim whitespace and remove blank arguments for demospace and page parameters. | ||
local args = {} | local args = {} | ||
for k, v in pairs(origArgs) do | for k, v in pairs(origArgs) do | ||
v = mw.text.trim(v) -- Trim whitespace. | if type(v) == 'string' then | ||
v = mw.text.trim(v) -- Trim whitespace. | |||
end | |||
if k == cfg.demospace or k == cfg.page then | if k == cfg.demospace or k == cfg.page then | ||
if v ~= '' then | if v ~= '' then | ||
| Zeile 258: | Zeile 233: | ||
end | end | ||
return | return p._main(args) | ||
end | end | ||
return p | return p | ||