Module:Find sources
From Zoophilia Wiki
Documentation for this module may be created at Module:Find sources/doc
-- This module implements {{find sources}} and other similar templates, and also -- provides a mechanism to easily create new source-finding templates. -- -- Template settings are found in subpages of [[Module:Find sources/templates]]. -- Link functions are defined in subpages of [[Module:Find sources/links]]. -- Functions shared between the link modules are stored at -- [[Module:Find sources/shared]]. local ROOT_PAGE = 'Module:Find sources' local TEMPLATE_ROOT = ROOT_PAGE .. '/templates/' local LINK_ROOT = ROOT_PAGE .. '/links/' local checkType = require('libraryUtil').checkType local p = {} local function maybeLoadData(page) local success, data = pcall(mw.loadData, page) if success then return data else return nil end end local function substituteParams(msg, ...) local params = {...} if params[1] then return mw.message.newRawMessage(msg):params(params):plain() else return msg end end local function renderSearchString(searchTerms, separator, transformFunc) local searchStrings = {} for i, s in ipairs(searchTerms) do searchStrings[i] = s end if transformFunc then for i, s in ipairs(searchStrings) do searchStrings[i] = transformFunc(s) end end return table.concat(searchStrings, separator) end local function renderLink(code, searchTerms, display) -- Get link config. local linkCfg = maybeLoadData(LINK_ROOT .. code) if not linkCfg then error(string.format( "invalid link code '%s'; no link config found at [[%s]]", code, LINK_ROOT .. code )) end -- Make URL. local url do local separator = linkCfg.separator or "+" local searchString = renderSearchString( searchTerms, separator, mw.uri.encode ) url = linkCfg.url or error(string.format( "no 'url' field found in the link config at [[%s]]", LINK_ROOT .. code )) url = substituteParams(url, searchString) end -- Fetch display. display = display or linkCfg.display or error(string.format( "no 'display' field found in the link config at [[%s]]", LINK_ROOT .. code )) return string.format('[%s %s]', url, display) end local function checkTemplateCfgLinkTable(cfgPage, key, t) if type(t) ~= 'table' then error(string.format( "invalid link table found in key '%s' of template config at [[%s]] " .. "(expected type table, got type %s)", key, cfgPage, type(t) )) elseif type(t[1]) ~= 'string' then error(string.format( "invalid link table found in key '%s' of template config at [[%s]] " .. "(the first table value must be a string)", key, cfgPage )) elseif t[2] and type(t[2]) ~= 'string' then error(string.format( "invalid link table found in key '%s' of template config at [[%s]] " .. "(if the second table value is specified, it must be a string)", key, cfgPage )) end end function p._main(template, args) checkType('_main', 1, template, 'string') checkType('_main', 2, args, 'table', true) args = args or {} local title = mw.title.getCurrentTitle() -- Get the template config. local templateCfgPage = TEMPLATE_ROOT .. template local templateCfg = maybeLoadData(templateCfgPage) if not templateCfg then error(string.format( "invalid template name '%s'; no template config found at [[%s]]", template, templateCfgPage )) end -- Template config sanity check. if templateCfg.introLink then checkTemplateCfgLinkTable(templateCfgPage, 'introLink', templateCfg.introLink) end if type(templateCfg.links) ~= 'table' then error(string.format( "type error in the 'links' field of the template config at [[%s]] " .. "(expected table, got %s)", templateCfgPage, type(templateCfg.links) )) end for _, t in ipairs(templateCfg.links) do checkTemplateCfgLinkTable(templateCfgPage, 'links', t) end if type(templateCfg.blurb) ~= 'string' then error(string.format( "type error in the 'blurb' field of the template config at [[%s]] " .. "(expected string, got %s)", templateCfgPage, type(templateCfg.blurb) )) end -- Namespace check. if not templateCfg.isUsedInMainspace and title.namespace == 0 then return '<strong class="error">' .. 'Error: Please do not use this template in articles.' .. '</strong>' .. '[[Category:Pages with templates in the wrong namespace]]' .. '[[Category:Find sources multi transclusions with errors]]' end -- Get the search terms from the arguments. local searchTerms = {} for i, s in ipairs(args) do searchTerms[i] = s end searchTerms[1] = searchTerms[1] or title.subpageText searchTerms[1] = '"' .. searchTerms[1] .. '"' -- Make the intro link local introLink if templateCfg.introLink then local code = templateCfg.introLink[1] local display = templateCfg.introLink[2] or renderSearchString( searchTerms, ' ' ) introLink = renderLink(code, searchTerms, display) else introLink = '' end -- Make the other links local links = {} for i, t in ipairs(templateCfg.links) do local code = t[1] local display = t[2] links[i] = renderLink(code, searchTerms, display) end local separator = templateCfg.separator or mw.message.new('Dot-separator'):plain() links = table.concat(links, separator) -- Make the blurb. local blurb = substituteParams(templateCfg.blurb, introLink, links) local span = mw.html.create('span') span :addClass('plainlinks') :addClass(templateCfg.class) :cssText(templateCfg.style) :wikitext(blurb) return tostring(span) end setmetatable(p, { __index = function(t, template) return function(frame) local args = require('Module:Arguments').getArgs(frame, { wrappers = mw.site.namespaces[10].name .. ':' .. template }) return t._main(template, args) end end}) return p