Jump to content

Module:GetShortDescription

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Fred Gandt (talk | contribs) at 11:32, 28 January 2023 (easy fix?). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local p = {}

local mLang = require( 'Module:Lang' )

local function errorMessage( message )
	return '<strong class="error">ERROR with invocation of [[Module:GetShortDescription]]: ' .. message .. '</strong>'
end

local function previewWarning( message )
	mw.addWarning( '<span style="color:#d33">[[Module:GetShortDescription]] has detected that ' .. message .. '</span>' )
end

local function pipedLink( name )
	return '[[:' .. name ..  '|' .. name .. ']]'
end

local function isEmpty( value )
	return value == nil or value == ''
end

local function notEmpty( value )
	return not isEmpty( value )
end

local function getWikidataDescription( name, lang )
	local wikidata_id = mw.wikibase.getEntityIdForTitle( name )
	if isEmpty( wikidata_id ) then
		return nil
	end
	local wikidata_description, wikidata_description_lang = mw.wikibase.getDescriptionWithLang( wikidata_id )
	if isEmpty( wikidata_description ) then
		return nil
	end
	-- Do as little as possible; return wikidata_description immediately if no more processing is required.
	if notEmpty( lang.no ) or wikidata_description_lang == 'en' then
		return wikidata_description
	end
	if isEmpty( wikidata_description_lang ) then
		return nil
	end
	return  mLang._lang {
		wikidata_description_lang,
		wikidata_description,
		italic = lang.italic or '',
		nocat = lang.nocat or '',
		size = lang.size or '',
		cat = lang.cat or '',
		rtl = lang.rtl or ''
	}
end

local function getExplicitDescription( name )
	local page_content = mw.title.new( name ):getContent()
	if isEmpty( page_content ) then
		return errorMessage( 'could not getContent of ' .. pipedLink( name ) )
	end
	-- Search for a short description template and grab the parameters from it if found.
	-- Do as little as possible; return nil immediately if that's what we found.
	local short_description_content = mw.ustring.match( page_content, '{{%s*[Ss]hort description%s*|%s*(.-)%s*}}' ) -- TODO: multiple short desc templates
	if isEmpty( short_description_content ) then
		return nil
	end
	-- The following mess is an alternative to preprocessing, which is expensive and
	-- causes empty strings to be returned if the invocation is substituted.
	-- Why does it look like this though?
	-- Short descriptions defined by template {{short description}} may properly contain:
		-- a numbered or unnumbered 1st param for the description
		-- a numbered or unnumbered 2nd param for noreplace
		-- the pagetype named param
	-- but may also contain:
		-- an empty description or no piped params at all
		-- two descriptions; one numbered and one not
		-- unknown params
	-- we might therefore need to understand the content of:
		-- {{short description|2=noreplace|pagetype=Redirect|Redirect page}} or
		-- {{short description|2=noreplace|1=Redirect page|pagetype=Redirect}} or
		-- {{short description|pagetype=Redirect|Redirect page|noreplace}} or
		-- {{short description|unknown=param|Short description}} or
		-- {{short description|Redirect page|1=Another short desc}} and so on
	-- all with a variety white space.
	
	-- Split the param content into trimmed param expressions.
	local short_description_params = mw.text.split( short_description_content, '%s*|%s*' )
	
	if #short_description_params > 3 then
		previewWarning( pipedLink( name ) .. ' has a [[WP:SDFORMAT|misconfigured]] {{tl|short description}}.' )
	end
	
	-- Create a table to store possible short descriptions
	local possible_short_descriptions = {}
	-- For each param expession:
	for i, param in ipairs( short_description_params ) do
		-- Ignore anything that isn't either '1=Desc' or just 'Desc'
		if param ~= 'noreplace' or not param:match( '=' ) or param:match( '^1' ) then
			-- and the remainder are possible_short_descriptions.
			possible_short_descriptions[ #possible_short_descriptions+1 ] = param
		end
	end
	
	if #possible_short_descriptions > 1 then
		previewWarning( 'the first {{tl|short description}} on ' .. pipedLink( name ) .. ' contains ' ..
			#possible_short_descriptions .. ' descriptions; please see [[WP:SDFORMAT]] and consider fixing it.'
		)
	end
	
	-- Do as little as possible; return nil immediately if there are no possible_short_descriptions.
	if #possible_short_descriptions < 1 then
		return nil
	end
	
	-- Pop the last possible_short_description as that will be the one applied to the page.
	local possible_short_description = possible_short_descriptions[ #possible_short_descriptions ]
	
	-- The possible_short_description might be in the form 'short description' or '1=short description'.
	-- It could also simply start with a number.
	if possible_short_description:match( '=' ) then
		possible_short_description = mw.ustring.gsub( possible_short_description, '^1%s*=%s*', '' )
	end
	-- Now we know what this template's short description is; check if it's in use and return nil if not.
	if possible_short_description:match( '^[Nn]one$' ) then
		return nil
	end
	-- Trim and return the result.
	return mw.ustring.match( possible_short_description, '^%s*(.-)%s*$' )
end

local function getShortDescription( args )
	local name = args.name
	if isEmpty( name ) then
		return errorMessage( 'a page name (including namespace) MUST be provided' )
	end
	local result
	local only = args.only
	local prefer = args.prefer
	if isEmpty( prefer ) then
		prefer = 'explicit'
	end
	local lang = {
		italic = args.lang_italic,
		nocat = args.lang_nocat,
		size = args.lang_size,
		cat = args.lang_cat,
		rtl = args.lang_rtl,
		no = args.lang_no
	}
	if only == 'explicit' then
		result = getExplicitDescription( name )
	elseif only == 'wikidata' then
		result = getWikidataDescription( name, lang )
	elseif prefer == 'explicit' then
		result = getExplicitDescription( name ) or getWikidataDescription( name, lang )
	elseif prefer == 'wikidata' then
		result = getWikidataDescription( name, lang ) or getExplicitDescription( name )
	end
	return result or args.fallback
end

function p.main( frame )
	return getShortDescription( frame.args ) or ''
end

return p