Difference between revisions of "Module:Category see also"

From blackwiki
Jump to navigation Jump to search
blackwiki>Mr. Stradivarius
(create replacement for Template:Category see also)
 
m (6 revisions imported)
 
(5 intermediate revisions by one other user not shown)
Line 12: Line 12:
 
end
 
end
  
-- Given a project string, returns a function that formats categories for that
+
-- Gets the length of the sequence seq. Usually this should be done with the #
-- project. The project can be nil, in which case it formats the category for
+
-- operator, but we need to work with tables that get their values through an
-- the current project.
+
-- __index metamethod.
 +
local function getSequenceLength(seq)
 +
local length = 0
 +
for i in ipairs(seq) do
 +
length = i
 +
end
 +
return length
 +
end
 +
 
 +
-- Given a table of options, returns a function that formats categories for
 +
-- those options.
 +
--
 +
-- Options:
 +
-- project - a project code such as "fr" (for the French Wikipedia)
 +
-- showPrefix - a boolean value for whether to show the "Category:" prefix
 +
--             (and the project prefix if specified)
 
--
 
--
 
-- This is implemented as a function generator rather than a simple function
 
-- This is implemented as a function generator rather than a simple function
-- so that we can just process the project name once, instead of every time
+
-- so that we can just process the options once, instead of every time we
-- we generate a category.
+
-- generate a category.
local function generateCategoryLinkMaker(project)
+
local function newCategoryLinker(options)
 
local formatString
 
local formatString
if project then
+
if options.project then
formatString = '[[:' .. project .. ':Category:%s|%s]]'
+
if options.showPrefix then
 +
formatString = '[[:' .. options.project .. ':Category:%s]]'
 +
else
 +
formatString = '[[:' .. options.project .. ':Category:%s|%s]]'
 +
end
 
else
 
else
formatString = '[[:Category:%s|%s]]'
+
if options.showPrefix then
 +
formatString = '[[:Category:%s]]'
 +
else
 +
formatString = '[[:Category:%s|%s]]'
 +
end
 
end
 
end
 
return function (category)
 
return function (category)
return formatString:format(category, category)
+
local title = mw.title.new(category)
 +
local pageName, display
 +
if not title then
 +
-- category is not a valid title, usually because of invalid
 +
-- characters like < or [. Raise an error and suppress the stack
 +
-- level information so that we can catch it and format the error
 +
-- message as wikitext.
 +
error(string.format(
 +
"'%s' is not a valid category name",
 +
category
 +
), 0)
 +
elseif title.namespace == 14 then -- Category namespace
 +
pageName = title.text
 +
display = title.text
 +
else
 +
pageName = title.prefixedText
 +
display = category
 +
end
 +
-- We can get away with using two arguments even when
 +
-- options.showDisplay is false, as string.format ignores extra
 +
-- arguments as long as there is an argument for each flag in the
 +
-- format string.
 +
return formatString:format(pageName, display)
 
end
 
end
 
end
 
end
  
 
function p._main(args)
 
function p._main(args)
if not args[1] then
+
local nLinks = getSequenceLength(args)
 +
 
 +
if nLinks < 1 then
 
return makeWikitextError('at least one parameter required')
 
return makeWikitextError('at least one parameter required')
 
end
 
end
local makeCategoryLink = generateCategoryLinkMaker(args.project)
+
 
 +
local makeCategoryLink = newCategoryLinker{
 +
project = args.project,
 +
showPrefix = nLinks == 1,
 +
}
 +
 
 
local links = {}
 
local links = {}
 
for i, cat in ipairs(args) do
 
for i, cat in ipairs(args) do
links[i] = makeCategoryLink(cat)
+
local success, categoryLink = pcall(makeCategoryLink, cat)
 +
if success then
 +
links[i] = categoryLink
 +
else
 +
-- If there was an error, then categoryLink is the error message.
 +
return makeWikitextError(categoryLink)
 +
end
 
end
 
end
local hatnoteText = string.format(
+
 
'%s: %s.',
+
local formatString
 +
if nLinks == 1 then
 +
formatString = '%s: %s.'
 +
else
 +
formatString = '%s: the categories %s.'
 +
end
 +
 
 +
-- Don't output a comma before the "and" if we have only two links.
 +
local conjunction
 +
if nLinks == 2 then
 +
conjunction = ' and '
 +
else
 +
conjunction = ', and '
 +
end
 +
 
 +
local hatnoteText = formatString:format(
 
args.LABEL or 'See also',
 
args.LABEL or 'See also',
mw.text.listToText(links, ', ', ', and ')
+
mw.text.listToText(links, ', ', conjunction)
 
)
 
)
 
return mHatnote._hatnote(hatnoteText, {selfref = true})
 
return mHatnote._hatnote(hatnoteText, {selfref = true})

Latest revision as of 13:32, 26 September 2020


This module implements {{Category see also}}. It produces see also links to categories which look something like this:

For full documentation, see Template:Category see also.


-- This module implements {{Category see also}}

local mHatnote = require('Module:Hatnote')

local p = {}

local function makeWikitextError(msg)
	return string.format(
		'<strong class="error">Error: %s ([[Template:Category see also]])</strong>',
		msg
	)
end

-- Gets the length of the sequence seq. Usually this should be done with the #
-- operator, but we need to work with tables that get their values through an
-- __index metamethod.
local function getSequenceLength(seq)
	local length = 0
	for i in ipairs(seq) do
		length = i
	end
	return length
end

-- Given a table of options, returns a function that formats categories for
-- those options.
--
-- Options:
-- project - a project code such as "fr" (for the French Wikipedia)
-- showPrefix - a boolean value for whether to show the "Category:" prefix
--              (and the project prefix if specified)
--
-- This is implemented as a function generator rather than a simple function
-- so that we can just process the options once, instead of every time we
-- generate a category.
local function newCategoryLinker(options)
	local formatString
	if options.project then
		if options.showPrefix then
			formatString = '[[:' .. options.project .. ':Category:%s]]'
		else
			formatString = '[[:' .. options.project .. ':Category:%s|%s]]'
		end
	else
		if options.showPrefix then
			formatString = '[[:Category:%s]]'
		else
			formatString = '[[:Category:%s|%s]]'
		end
	end
	return function (category)
		local title = mw.title.new(category)
		local pageName, display
		if not title then
			-- category is not a valid title, usually because of invalid
			-- characters like < or [. Raise an error and suppress the stack
			-- level information so that we can catch it and format the error
			-- message as wikitext.
			error(string.format(
				"'%s' is not a valid category name",
				category
			), 0)
		elseif title.namespace == 14 then -- Category namespace
			pageName = title.text
			display = title.text
		else
			pageName = title.prefixedText
			display = category
		end
		-- We can get away with using two arguments even when
		-- options.showDisplay is false, as string.format ignores extra
		-- arguments as long as there is an argument for each flag in the
		-- format string.
		return formatString:format(pageName, display)
	end
end

function p._main(args)
	local nLinks = getSequenceLength(args)

	if nLinks < 1 then
		return makeWikitextError('at least one parameter required')
	end

	local makeCategoryLink = newCategoryLinker{
		project = args.project,
		showPrefix = nLinks == 1,
	}

	local links = {}
	for i, cat in ipairs(args) do
		local success, categoryLink = pcall(makeCategoryLink, cat)
		if success then
			links[i] = categoryLink
		else
			-- If there was an error, then categoryLink is the error message.
			return makeWikitextError(categoryLink)
		end
	end

	local formatString
	if nLinks == 1 then
		formatString = '%s: %s.'
	else
		formatString = '%s: the categories %s.'
	end

	-- Don't output a comma before the "and" if we have only two links.
	local conjunction
	if nLinks == 2 then
		conjunction = ' and '
	else
		conjunction = ', and '
	end

	local hatnoteText = formatString:format(
		args.LABEL or 'See also',
		mw.text.listToText(links, ', ', conjunction)
	)
	return mHatnote._hatnote(hatnoteText, {selfref = true})
end

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		wrappers = 'Template:Category see also',
	})
	return p._main(args)
end

return p