Module:Find sources

-- This module implements and other similar templates, and -- also provides a mechanism to easily create new source-finding templates.

-- Define constants local ROOT_PAGE = 'Module:Find sources' local TEMPLATE_ROOT = ROOT_PAGE .. '/templates/' -- for template config modules local LINK_ROOT = ROOT_PAGE .. '/links/' -- for link config modules local CONFIG_PAGE = ROOT_PAGE .. '/config' -- for global config

-- Load required modules local checkType = require('libraryUtil').checkType local cfg = mw.loadData(CONFIG_PAGE)

local p = {}

local function maybeLoadData(page) local success, data = pcall(mw.loadData, page) return success and data 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) -- This takes a table of search terms and turns it into a search string -- that can be used in a URL or in a display value. The transformFunc -- parameter can be used to transform each search term in some way (for	-- example, URL-encoding them). 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) -- Renders the external link wikicode for one link, given the link code, -- a table of search terms, and an optional display value.

-- 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 = substituteParams(linkCfg.url, searchString) end return string.format('[%s %s]', url, display or linkCfg.display) end

function p._main(template, args) -- The main access point from Lua. 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

-- Namespace check. if not templateCfg.isUsedInMainspace and title.namespace == 0 then local formatString = ' %s ' if cfg.namespaceErrorCategory then formatString = formatString .. '%s:%s' end return string.format(			formatString,			cfg.namespaceError,			mw.site.namespaces[14].name,			cfg.namespaceErrorCategory		) 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.code local display = templateCfg.introLink.display 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		links[i] = renderLink(t.code, searchTerms, t.display) end local separator = templateCfg.separator or cfg.defaultSeparator 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)	-- The main access point from #invoke.	-- Invocations will look like ,	-- where "template name" is a subpage of Module:Find sources/templates.	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