This submodule implements the following templates:

See the documentation of each template for usage details.

This submodule is specific to the English Wikipedia and is not designed to be reused on other wikis. For the general, abstract, cross-wiki excerpt functionality, see the Module:Excerpt.

Developers

Before saving changes to this module, please preview with:


-- Invocation functions for English Wikipedia templates
-- May not work properly or at all on other wikis

local e = require("Module:Excerpt")
local p = {}

-- Shared invocation function used by templates meant for portals
local function portal(frame, template)
	local args = e.parseArgs(frame)

	errors = args['errors'] or false -- disable error reporting unless requested

	-- There should be at least one argument except with selected=Foo and Foo=Somepage
	if #args < 1 and not (template == "selected" and args[template] and args[args[template]]) then
		return e.wikiError("noPage")
	end

	-- Figure out the page to excerpt
	local page
	local candidates = {}

	if template == "lead" then
		page = args[1]
		page = mw.text.trim(page)
		if not page or page == "" then return e.wikiError("noPage") end
		candidates = { page }

	elseif template == "selected" then
		local key = args[template]
		local count = #args
		if tonumber(key) then -- normalise article number into the range 1..#args
			key = key % count
			if key == 0 then key = count end
		end
		page = args[key]
		page = mw.text.trim(page)
		if not page or page == "" then return e.wikiError("noPage") end
		candidates = { page }

	elseif template == "linked" or template == "listitem" then
		local source = args[1]
		local text, source = e.getContent(source)
		if not source then
			return e.wikiError("noPage")
		elseif not text then
			return e.wikiError("noPage")
		end
		local section = args.section
		if section then -- check relevant section only
			text = e.getSection(text, section)
			if not text then return e.wikiError("sectionNotFound", section) end
		end
		-- Replace annotated links with real links
		text = mw.ustring.gsub(text, "{{%s*[Aa]nnotated[ _]link%s*|%s*(.-)%s*}}", "[[%1]]")
		if template == "linked" then
			for candidate in mw.ustring.gmatch(text, "%[%[%s*([^%]|\n]*)") do table.insert(candidates, candidate) end
		else -- listitem: first wikilink on a line beginning *, :#, etc. except in "See also" or later section
			text = mw.ustring.gsub(text, "\n== *See also.*", "")
			for candidate in mw.ustring.gmatch(text, "\n:*[%*#][^\n]-%[%[%s*([^%]|\n]*)") do table.insert(candidates, candidate) end
		end

	elseif template == "random" then
		for key, value in pairs(args) do
			if value and type(key) == "number" then table.insert(candidates, value) end
		end
	end

	-- Build an options array for the Excerpt module out of the arguments and the desired defaults
	local options = {
		errors = args['errors'] or false,
		fileargs = args['fileargs'],
		fileflags = e.numberFlags( args['files'] ),
		paraflags = e.numberFlags( args['paragraphs'] )
	}

	-- Select a random candidate and make sure its valid
	local text
	local candidateCount = #candidates
	if candidateCount > 0 then
		local candidateKey = 1
		local candidateString
		local candidateArgs
		if candidateCount > 1 then math.randomseed(os.time()) end
		while (not text or text == "") and candidateCount > 0 do
			if candidateCount > 1 then candidateKey = math.random(candidateCount) end -- pick a random candidate
			candidateString = candidates[candidateKey]
			if candidateString and candidateString ~= "" then
				-- We have page or [[page]] or [[page|text]], possibly followed by |opt1|opt2...
				page, candidateArgs = mw.ustring.match(candidateString, "^%s*(%[%b[]%])%s*|?(.*)")
				if page and page ~= "" then
					page = mw.ustring.match(page, "%[%[([^|%]]*)") -- turn [[page|text]] into page, discarding text
				else -- we have page or page|opt...
					page, candidateArgs = mw.ustring.match(candidateString, "%s*([^|]*[^|%s])%s*|?(.*)")
				end
				-- candidate arguments (even if value is "") have priority over global arguments
				if candidateArgs and candidateArgs ~= "" then
					for _, t in pairs(mw.text.split(candidateArgs, "|")) do
						local k, v = mw.ustring.match(t, "%s*([^=]-)%s*=(.-)%s*$")
						if k == 'files' then options.fileflags = e.numberFlags(v)
						elseif k == 'paragraphs' then options.paraflags = e.numberFlags(v)
						elseif k == 'more' then args.more = v
						else options[k] = v end
					end
				end
				if page and page ~= "" then
					local section = mw.ustring.match(page, "[^#]+#?([^#]*)") -- save the section
					text, page = e.getContent(page) -- make sure the page exists
					if page and page ~= "" and text and text ~= "" then
						if args.nostubs then
							local isStub = mw.ustring.find(text, "%s*{{[^{|}]*%-[Ss]tub%s*}}")
							if isStub then text = nil end
						end
						page = page .. '#' .. section -- restore the section
						text = e.get(page, options)
					end
				end
			end
			table.remove(candidates, candidateKey) -- candidate processed
			candidateCount = candidateCount - 1 -- ensure that we exit the loop after all candidates are done
		end
	end
	if not text or text == "" then return e.wikiError("No valid pages found") end

	if args.showall then
		local separator = args.showall
		if separator == "" then separator = "{{clear}}{{hr}}" end
		for _, candidate in pairs(candidates) do
			local t = e.get(candidate, options)
			if t ~= "" then
				text = text .. separator .. t
			end
		end
	end

	-- If more= then append a link to article for more info
	if args.more then
		local more = "Read more..." -- default text
		if args.more ~= "" then more = args.more end -- use the given text
		text = text .. " '''[[" .. page .. "|" .. more .. "]]'''"
	end

	-- Add a collapsed list of pages which might appear
	if args.list and not args.showall then
		local list = args.list
		if list == "" then list = "Other articles" end
		text = text .. "{{collapse top|title={{resize|85%|" ..list .. "}}|bg=fff}}{{hlist"
		for _, candidate in pairs(candidates) do
			if mw.ustring.match(candidate, "%S") then text = text .. "|[[" .. mw.text.trim(candidate) .. "]]" end
		end
		text = text .. "}}\n{{collapse bottom}}"
	end

	return frame:preprocess(text)
end

-- Invocation function used by {{Excerpt}}
local function excerpt(frame)
	local args = e.parseArgs(frame)

	-- Make sure the requested page exists
	local page = args[1] or args.article or args.source or args.page
	if not page then return e.wikiError("noPage") end
	local title = mw.title.new(page)
	if not title then return e.wikiError("noPage") end
	if title.isRedirect then title = title.redirectTarget end
	if not title.exists then return e.wikiError("pageNotFound", page) end
	page = title.prefixedText

	-- Define some useful variables
	local section = args[2] or args.section or mw.ustring.match(args[1], "[^#]+#([^#]+)")
	local tag = args.tag or 'div'

	-- Define the HTML elements
	local block = mw.html.create(tag):addClass('excerpt-block')
	if e.is(args.indicator) then block:addClass('excerpt-indicator') end

	local style = frame:extensionTag{ name = 'templatestyles', args = { src = 'Excerpt/styles.css' } }

	local hatnote
	if not args.nohat then
		if args.this then
			hatnote = args.this
		elseif args.indicator then
			hatnote = 'This is'
		elseif args.only == 'file' then
			hatnote = 'This file is'
		elseif args.only == 'file' then
			hatnote = 'These files are'
		elseif args.only == 'list' then
			hatnote = 'This list is'
		elseif args.only == 'lists' then
			hatnote = 'These lists are'
		elseif args.only == 'table' then
			hatnote = 'This table is'
		elseif args.only == 'tables' then
			hatnote = 'These tables are'
		else
			hatnote = 'This section is'
		end
		hatnote = hatnote .. ' an excerpt from '
		if section then
			hatnote = hatnote .. '[[' .. page .. '#' .. section .. '|' .. page .. ' § ' .. section .. ']]'
		else
			hatnote = hatnote .. '[[' .. page .. ']]'
		end
		hatnote = hatnote .. "''" .. '<span class="mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span>['
		hatnote = hatnote .. title:fullUrl('action=edit') .. ' edit'
		hatnote = hatnote .. ']<span class="mw-editsection-bracket">]</span></span>' .. "''"
		hatnote = require('Module:Hatnote')._hatnote(hatnote, {selfref=true}) or e.wikiError('Error generating hatnote')
	end

	-- Build the module options out of the template arguments and the desired defaults
	local options = {
		fileflags = e.numberFlags( args['files'] or 1 ),
		paraflags = e.numberFlags( args['paragraphs'] ),
		filesOnly = e.is( args['only'] == 'file' or args['only'] == 'files' ),
		listsOnly = e.is( args['only'] == 'list' or args['only'] == 'lists'),
		tablesOnly = e.is( args['only'] == 'table' or args['only'] == 'tables' ),
		keepTables = e.is( args['tables'] or true ),
		keepRefs = e.is( args['references']  or true ),
		keepSubsections = e.is( args['subsections'] ),
		nobold = not e.is( args['bold'] ),
		fragment = args['fragment']
	}

	-- Get the excerpt itself
	if section then page = page .. '#' .. section end
	local ok, excerpt = pcall(e.get, page, options)
	if not ok then return e.wikiError(excerpt) end
	excerpt = "\n" .. excerpt -- line break is necessary to prevent broken tables and lists
	if mw.title.getCurrentTitle().isContentPage then excerpt = excerpt .. '[[Category:Articles with excerpts]]' end
	excerpt = frame:preprocess(excerpt)
	excerpt = mw.html.create(tag):addClass('excerpt'):wikitext(excerpt)

	-- Combine and return the elements
	return block:node(style):node(hatnote):node(excerpt)
end

-- Entry points for English Wikipedia templates
function p.lead(frame) return portal(frame, "lead") end -- {{Transclude lead excerpt}} reads a randomly selected article linked from the given page
function p.linked(frame) return portal(frame, "linked") end -- {{Transclude linked excerpt}} reads a randomly selected article linked from the given page
function p.listitem(frame) return portal(frame, "listitem") end -- {{Transclude list item excerpt}} reads a randomly selected article listed on the given page
function p.random(frame) return portal(frame, "random") end -- {{Transclude random excerpt}} reads any article (default for invoke with one argument)
function p.selected(frame) return portal(frame, "selected") end -- {{Transclude selected excerpt}} reads the article whose key is in the selected= parameter
function p.excerpt(frame) return excerpt(frame) end -- {{Excerpt}} transcludes part of an article into another article

return p