-- This module implements  and other similar templates, and -- also provides a mechanism to easily create new source-finding templates.  -- Define constants local ROOT_PAGE = 'মডিউল:উৎস খুঁজুন' local TEMPLATE_ROOT = ROOT_PAGE .. '/টেমপ্লেট/' -- for template config modules local LINK_ROOT = ROOT_PAGE .. '/সংযোগ/' -- for link config modules local CONFIG_PAGE = ROOT_PAGE .. '/কনফিগ' -- 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, ...) 	return mw.message.newRawMessage(msg, ...):plain() 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  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. 	local linkCfg = maybeLoadData(LINK_ROOT .. code) 	if not linkCfg then 		error(string.format( 			"অকার্যকর সংযোগ কোড '%s'; %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( 			"অকার্যকর টেমপ্লেটের নাম '%s'; %s-এ কোন টেমপ্লেট কনফিগ পাওয়া যায়নি", 			template, templateCfgPage 		)) 	end  	-- Namespace check. 	if not templateCfg.isUsedInMainspace and title.namespace == 0 then 		local formatString = '%s' 		if cfg['namespace-error-category'] then 			formatString = formatString .. '%s:%s' 		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 	if not searchTerms[1] then 		-- Use the current subpage name as the default search term, unless  		-- another title is provided. If the page uses a disambiguator like 		-- "Foo (bar)", make "Foo" the first term and "bar" the second. 		local searchTitle = args.title or title.subpageText 		local term, dab = searchTitle:match('^(.*) (%b())$') 		if dab then 			dab = dab:sub(2, -2) -- Remove parens 		end 		if term and dab then 			searchTerms[1] = term 			searchTerms[2] = dab 		else 			searchTerms[1] = searchTitle 		end 	end 	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 = 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  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. 	local tname = template 	if tname:sub(-8) == '/খেলাঘর' then 		-- This makes  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