Module:Find sources: Difference between revisions

From Wikitia
Jump to navigation Jump to search
No edit summary
Tag: Manual revert
No edit summary
Tag: Reverted
Line 1: Line 1:
-- This module implements {{find sources}} and other similar templates, and
-- Module:Find sources
-- also provides a mechanism to easily create new source-finding templates.
-- Simple implementation for find sources functionality
 
-- 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 p = {}


local function maybeLoadData(page)
-- Link configurations
local success, data = pcall(mw.loadData, page)
local links = {
return success and data
news = {
end
url = 'https://www.google.com/search?tbm=nws&q={{{1}}}',
 
display = 'news',
local function substituteParams(msg, ...)
},
return mw.message.newRawMessage(msg, ...):plain()
newspapers = {
end
url = 'https://www.google.com/search?tbm=nws&q={{{1}}}',
 
display = 'newspapers',
local function renderSearchString(searchTerms, separator, transformFunc)
},
-- This takes a table of search terms and turns it into a search string
books = {
-- that can be used in a URL or in a display value. The transformFunc
url = 'https://www.google.com/search?tbm=bks&q={{{1}}}',
-- parameter can be used to transform each search term in some way (for
display = 'books',
-- example, URL-encoding them).
},
local searchStrings = {}
scholar = {
for i, s in ipairs(searchTerms) do
url = 'https://scholar.google.com/scholar?q={{{1}}}',
searchStrings[i] = s
display = 'scholar',
end
},
if transformFunc then
jstor = {
for i, s in ipairs(searchStrings) do
url = 'https://www.jstor.org/action/doBasicSearch?Query={{{1}}}',
searchStrings[i] = transformFunc(s)
display = 'JSTOR',
end
},
end
}
return table.concat(searchStrings, separator)
end
 
function p._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.
function p._renderLink(code, args)
local linkCfg = maybeLoadData(LINK_ROOT .. code)
local linkCfg = links[code]
if not linkCfg then
if not linkCfg then
error(string.format(
return string.format('[%s]', code)
"invalid link code '%s'; no link config found at [[%s]]",
code,
LINK_ROOT .. code
))
end
end
 
-- Make URL.
local query = table.concat(args, '+')
local url
local url = string.gsub(linkCfg.url, '{{{1}}}', query)
do
url = string.gsub(url, '{{{q}}}', query)
local separator = linkCfg.separator or "+"
local searchString = renderSearchString(
return string.format('[%s %s]', url, linkCfg.display)
searchTerms,
separator,
mw.uri.encode
)
url = substituteParams(linkCfg.url, searchString)
end
 
return string.format('[%s %s]', url, display or linkCfg.display)
end
end


function p._main(template, args)
function p._main(template, args)
-- The main access point from Lua.
local templateCfgs = {
checkType('_main', 1, template, 'string')
mainspace = {
checkType('_main', 2, args, 'table', true)
blurb = 'Find sources',
args = args or {}
introLink = nil,
local title = mw.title.getCurrentTitle()
links = {
 
{code = 'news'},
-- Get the template config.
{code = 'newspapers'},
local templateCfgPage = TEMPLATE_ROOT .. template
{code = 'books'},
local templateCfg = maybeLoadData(templateCfgPage)
{code = 'scholar'},
if not templateCfg then
{code = 'jstor'},
error(string.format(
},
"invalid template name '%s'; no template config found at [[%s]]",
separator = ' ⧼Dot-separator⧽ ',
template, templateCfgPage
},
))
}
local templateCfg = templateCfgs[template] or templateCfgs.mainspace
local links_output = {}
for i, linkCfg in ipairs(templateCfg.links) do
links_output[#links_output + 1] = p._renderLink(linkCfg.code, args)
end
end
return table.concat(links_output, templateCfg.separator)
end


-- Namespace check.
function p.main(frame)
if not templateCfg.isUsedInMainspace and title.namespace == 0 then
local args = {}
local formatString = '<strong class="error">%s</strong>'
local parentArgs = frame:getParent().args
if cfg['namespace-error-category'] then
formatString = formatString .. '[[%s:%s]]'
-- Collect numbered arguments
for i = 1, 20 do
if parentArgs[i] and parentArgs[i] ~= '' then
args[#args + 1] = parentArgs[i]
end
end
return string.format(
formatString,
cfg['namespace-error'],
mw.site.namespaces[14].name,
cfg['namespace-error-category']
)
end
-- Get the search terms from the arguments.
local searchTerms = {}
for i, s in ipairs(args) do
searchTerms[i] = s
end
end
if not searchTerms[1] then
-- Use the current subpage name as the default search term, unless
-- If no arguments, use the page name as default search term
-- another title is provided. If the page uses a disambiguator like
if #args == 0 then
-- "Foo (bar)", make "Foo" the first term and "bar" the second.
local title = mw.title.getCurrentTitle()
local searchTitle = args.title or title.subpageText
if title and title.namespace == 0 then
local term, dab = searchTitle:match('^(.*) (%b())$')
args[1] = title.text
if dab then
dab = dab:sub(2, -2) -- Remove parens
end
if term and dab then
searchTerms[1] = term
searchTerms[2] = dab
else
else
searchTerms[1] = searchTitle
args[1] = 'example'
end
end
end
end
searchTerms[1] = '"' .. searchTerms[1] .. '"'
 
local template = frame.args[1] or 'mainspace'
-- Make the intro link
local introLink
return p._main(template, args)
if templateCfg.introLink then
local code = templateCfg.introLink.code
local display = templateCfg.introLink.display or renderSearchString(
searchTerms,
'&nbsp;'
)
introLink = p._renderLink(code, searchTerms, display)
else
introLink = ''
end
 
-- Make the other links
local links = {}
local separator = templateCfg.separator or cfg['default-separator']
local sep = ''
for i, t in ipairs(templateCfg.links) do
links[i] = sep .. p._renderLink(t.code, searchTerms, t.display) ..
(t.afterDisplay or '')
sep = t.separator or separator
end
links = table.concat(links)
 
-- 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
end


setmetatable(p, { __index = function(t, template)
-- Create the function that the template is looking for
-- The main access point from #invoke.
p['Find sources mainspace'] = p.main
-- Invocations will look like {{#invoke:Find sources|template name}},
-- where "template name" is a subpage of [[Module:Find sources/templates]].
local tname = template
if tname:sub(-8) == '/sandbox' then
-- This makes {{Find sources/sandbox|Albert Einstein}} work.
tname = tname:sub(1, -9)
end
return function(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = mw.site.namespaces[10].name .. ':' .. tname
})
return t._main(template, args)
end
end})


return p
return p

Revision as of 11:39, 5 May 2026

Documentation for this module may be created at Module:Find sources/doc

-- Module:Find sources
-- Simple implementation for find sources functionality

local p = {}

-- Link configurations
local links = {
	news = {
		url = 'https://www.google.com/search?tbm=nws&q={{{1}}}',
		display = 'news',
	},
	newspapers = {
		url = 'https://www.google.com/search?tbm=nws&q={{{1}}}',
		display = 'newspapers',
	},
	books = {
		url = 'https://www.google.com/search?tbm=bks&q={{{1}}}',
		display = 'books',
	},
	scholar = {
		url = 'https://scholar.google.com/scholar?q={{{1}}}',
		display = 'scholar',
	},
	jstor = {
		url = 'https://www.jstor.org/action/doBasicSearch?Query={{{1}}}',
		display = 'JSTOR',
	},
}

function p._renderLink(code, args)
	local linkCfg = links[code]
	if not linkCfg then
		return string.format('[%s]', code)
	end
	
	local query = table.concat(args, '+')
	local url = string.gsub(linkCfg.url, '{{{1}}}', query)
	url = string.gsub(url, '{{{q}}}', query)
	
	return string.format('[%s %s]', url, linkCfg.display)
end

function p._main(template, args)
	local templateCfgs = {
		mainspace = {
			blurb = 'Find sources',
			introLink = nil,
			links = {
				{code = 'news'},
				{code = 'newspapers'},
				{code = 'books'},
				{code = 'scholar'},
				{code = 'jstor'},
			},
			separator = ' ⧼Dot-separator⧽ ',
		},
	}
	
	local templateCfg = templateCfgs[template] or templateCfgs.mainspace
	local links_output = {}
	
	for i, linkCfg in ipairs(templateCfg.links) do
		links_output[#links_output + 1] = p._renderLink(linkCfg.code, args)
	end
	
	return table.concat(links_output, templateCfg.separator)
end

function p.main(frame)
	local args = {}
	local parentArgs = frame:getParent().args
	
	-- Collect numbered arguments
	for i = 1, 20 do
		if parentArgs[i] and parentArgs[i] ~= '' then
			args[#args + 1] = parentArgs[i]
		end
	end
	
	-- If no arguments, use the page name as default search term
	if #args == 0 then
		local title = mw.title.getCurrentTitle()
		if title and title.namespace == 0 then
			args[1] = title.text
		else
			args[1] = 'example'
		end
	end
	
	local template = frame.args[1] or 'mainspace'
	
	return p._main(template, args)
end

-- Create the function that the template is looking for
p['Find sources mainspace'] = p.main

return p