Module:Pagetype
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Pagetype/doc
-------------------------------------------------------------------------------- -- -- -- This meta-module which automatically detects namespaces, and allows -- -- for a great deal of customisation. It can easily be ported to other -- -- wikis by changing the values in the [[Module:Pagetype/config]]. -- -- -- -------------------------------------------------------------------------------- -- Load config. local cfg = mw.loadData('Module:Pagetype/config') -- Load required modules. local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} -- Look up a namespace argument in the args table. local function lookUpNamespaceArg(args, key) local arg = args[key] -- Convert "yes", "1" etc. to true, "no", "0" etc. to false, and leave -- other values the same. return yesno(arg, arg) end -- Append multiple values to an array local function appendMultiple(target, source) for _, value in ipairs(source) do table.insert(target, value) end end -- Get argument keys for a title's namespace local function getNamespaceArgKeys(title, cfg) local nsInfo = mw.site.namespaces[title.namespace] local customAliases = cfg.customNamespaceAliases[title.namespace] or {} local keys = {} if nsInfo.name ~= '' then table.insert(keys, nsInfo.name) end if nsInfo.canonicalName ~= nsInfo.name and nsInfo.canonicalName ~= '' then table.insert(keys, nsInfo.canonicalName) end appendMultiple(keys, nsInfo.aliases) appendMultiple(keys, customAliases) return keys end -- Get the argument for a title's namespace, if it was specified in the args table. local function getNamespaceArg(title, args, cfg) if title.isTalkPage then return lookUpNamespaceArg(args, cfg.talk) end for _, key in ipairs(getNamespaceArgKeys(title, cfg)) do local arg = lookUpNamespaceArg(args, mw.ustring.lower(key)) if arg ~= nil then return arg end end return nil end -- Look up a page type specific to the title's namespace local function getExplicitPageType(title, cfg) if title.isTalkPage then return cfg.talkDefault else return cfg.pagetypes[title.namespace] end end -- Get a default page type that is not specific to the title's namespace local function getDefaultPageType(args, cfg) local other = lookUpNamespaceArg(args, cfg.other) if type(other) == 'string' then return other else return cfg.otherDefault end end local function detectRedirects(title, args) local redirect = lookUpNamespaceArg(args, cfg.redirect) if redirect == false then -- Don't detect redirects if they have been specifically disallowed. return nil end -- Allow custom values for redirects. if not title.isRedirect then return nil elseif type(redirect) == 'string' then return redirect else return cfg.redirectDefault end end local function capitalize(pageType) local first = mw.ustring.sub(pageType, 1, 1) local rest = mw.ustring.sub(pageType, 2) return mw.ustring.upper(first) .. rest end local function pluralize(pageType, cfg) if cfg.irregularPlurals[pageType] then return cfg.irregularPlurals[pageType] else return pageType .. cfg.plural -- often 's' end end local function parseContent(title, args, optionsList) if title.namespace==828 and title.subpageText~='doc' -- don't detect modules or not title.exists -- can't check unless page exists then return nil end local content = title:getContent() if content == nil then return nil end local templates -- lazily evaluated for _, options in next, optionsList do local list, parameter, default, articleOnly = unpack(options, 1, 4) if not articleOnly or title.namespace==0 then -- only check for templates if we should... local out = lookUpNamespaceArg(args, parameter) if type(out) == "string" or (out ~= false and default) then -- ...and if we actually have anything to say about them if not templates then templates = {} -- do our delayed evaluation now that we are required to content = require('Module:Wikitext Parsing').PrepareText(content) -- disregard templates which do not have any affect for template in string.gmatch(content, "{{%s*([^|}]-)%s*[|}]") do templates[#templates+1] = capitalize(template) end end local wantedTemplates = mw.loadData('Module:Pagetype/' .. list) local templateFound = false for _, template in next, templates do if wantedTemplates[template] then templateFound = true break end end if templateFound then if type(out)=='string' then return out elseif out ~= false and default then return default end end end end end end -- Gets the pagetype from a class specified from the first positional parameter. local function getPageTypeFromClass(args, class, key, aliasTable, default) local arg = lookUpNamespaceArg(args, key) if arg == false then -- Don't check for this class if it is specifically disallowed. return nil end if aliasTable[class] then if type(arg) == 'string' then return arg else return default end end return nil end -- Get page types for mainspaces pages with an explicit class specified local function getMainNamespaceClassPageType(title, args, cfg) if title.namespace ~= 0 then return nil end local class = args[1] if type(class) == 'string' then -- Put in lower case so e.g. "na" and "NA" will both match. class = mw.ustring.lower(class) end return getPageTypeFromClass( args, class, cfg.na, cfg.naAliases, cfg.naDefault ) end -- Get page type specified by an explicit namespace argument. local function getNamespaceArgPageType(title, args, cfg) local namespaceArg = getNamespaceArg(title, args, cfg) if namespaceArg == true then -- Namespace has been explicitly enabled, so return the default for -- this namespace return getExplicitPageType(title, cfg) elseif namespaceArg == false then -- Namespace has been explicitly disabled return getDefaultPageType(args, cfg) elseif namespaceArg then -- This namespaces uses custom text return namespaceArg else return nil end end -- Whether the title is in the set of default active namespaces which are looked up in cfg.pagetypes. local function isInDefaultActiveNamespace(title, args, cfg) local defaultNamespacesKey = args[cfg.defaultns] if defaultNamespacesKey == cfg.defaultnsAll then return true end local defaultNamespaces if defaultNamespacesKey == cfg.defaultnsExtended then defaultNamespaces = cfg.extendedNamespaces elseif defaultNamespacesKey == cfg.defaultnsNone then defaultNamespaces = {} else defaultNamespaces = cfg.defaultNamespaces end return defaultNamespaces[title.namespace] or false end -- Get page type not specified or detected by other means local function getOtherPageType(title, args, cfg) if isInDefaultActiveNamespace(title, args, cfg) then return getExplicitPageType(title, cfg) else return getDefaultPageType(args, cfg) end end local function getPageType(title, args, cfg) return ( detectRedirects(title, args, cfg) or parseContent(title, args, { {'softredirect', cfg.softRedirect, cfg.softRedirectDefault}, {'setindex', cfg.sia, cfg.siaDefault, true}, {'disambiguation', cfg.dab, cfg.dabDefault, true}, }) or getMainNamespaceClassPageType(title, args, cfg) or getNamespaceArgPageType(title, args, cfg) or getOtherPageType(title, args, cfg) ) end local function shouldUseSubjectTitle(args, cfg) return not yesno(args.talk, true) and args[cfg.defaultns] ~= cfg.defaultnsAll end -- Get the Scribunto title object to fetch the page type of local function getTitle(args, cfg) local title if args.page then title = mw.title.new(args.page) if not title then return nil end else title = mw.title.getCurrentTitle() end if shouldUseSubjectTitle(args, cfg) then return title.subjectPageTitle else return title end end function p._main(args) local title = getTitle(args, cfg) local pageType = getPageType(title, args, cfg) if yesno(args.plural, false) then pageType = pluralize(pageType, cfg) end if yesno(args.caps, false) then pageType = capitalize(pageType) end return pageType end function p.main(frame) local args = getArgs(frame) return p._main(args) end return p