Difference between revisions 51763 and 51764 on wikimaniawiki

-- This module implements {{documentation}}.

----------------------------------------------------------------------------
-- Configuration
----------------------------------------------------------------------------

-- Here you can set the values of the parameters and messages used in this module, so that it
-- can be easily ported to other wikis.

local cfg = {}

-- Argument names
-- The following are all names of arguments that affect the behaviour of {{documentation}}.
-- The comments next to the configuration values are the effects that the argument has
-- on the module. (Not the effects of the argument names themselves.)

cfg.livepageArg = 'livepage' -- Name of the live template; used in {{template sandbox notice}}.
cfg.headingArg = 'heading' -- Custom heading used in the start box.
cfg.preloadArg = 'preload' -- Custom preload page for creating documentation.
cfg.headingStyleArg = 'heading-style' -- Custom CSS style for the start box heading.
cfg.contentArg = 'content' -- Passes documentation content directly from the {{documentation}} invocation.
cfg.linkBoxArg = 'link box' -- Specifies a custom link box (end box) or prevents it from being generated.

----------------------------------------------------------------------------
-- End configuration
----------------------------------------------------------------------------

-- Get required modules.
local getArgs = require('Module:Arguments').getArgs
local htmlBuilder = require('Module:HtmlBuilder')
local messageBox = require('Module:Message box')

local p = {}

-- Constants.
local currentTitle = mw.title.getCurrentTitle()
local subjectSpace = mw.site.namespaces[currentTitle.namespace].subject.id

----------------------------------------------------------------------------
-- Helper functions
----------------------------------------------------------------------------

local function makeWikilink(page, display)
	if display then
		return mw.ustring.format('[[%s|%s]]', page, display)
	else
		return mw.ustring.format('[[%s]]', page)
	end
end

local function makeUrlLink(url, display)
	return mw.ustring.format('[%s %s]', url, display)
end

local function makeToolbar(...)
	local ret = {}
	local lim = select('#', ...)
	if lim < 1 then
		return nil
	end
	for i = 1, lim do
		ret[#ret + 1] = select(i, ...)
	end
	return '<small style="font-style: normal;">(' .. table.concat(ret, ' &#124; ') .. ')</small>'
end	

----------------------------------------------------------------------------
-- Argument processing
----------------------------------------------------------------------------

local function makeInvokeFunc(funcName)
	return function (frame)
		local headingArg = cfg.headingArg
		local args = getArgs(frame, {
			valueFunc = function (key, value)
				if type(value) == 'string' then
					value = value:match('^%s*(.-)%s*$') -- Remove whitespace.
					if key == 'heading'Arg or value ~= '' then
						return value
					else
						return nil
					end
				else
					return value
				end
			end
		})
		return p[funcName](args)
	end
end

----------------------------------------------------------------------------
-- Main functions
----------------------------------------------------------------------------

p.main = makeInvokeFunc('_main')

function p._main(args)
	local root = htmlBuilder.create()
	root
		.wikitext(p.protectionTemplate())
		.wikitext(p.sandboxNotice(args))
		 -- This div tag is from {{documentation/start box}}, but moving it here
		 -- so that we don't have to worry about unclosed tags.
		.tag('div')
			.attr('id', 'template-documentation')
			.addClass('template-documentation iezoomfix')
			.wikitext(p._startBox(args))
			.wikitext(p._content(args))
			.tag('div')
				.css('clear', 'both') -- So right or left floating items don't stick out of the doc box.
				.done()
			.done()
		.wikitext(p._endBox(args))
		.wikitext(p.addTrackingCategories())
	return tostring(root)
end

function p.sandboxNotice(args)
	if currentTitle.subpageText == 'sandbox' then
		local frame = mw.getCurrentFrame()
		local root = htmlBuilder.create()
		root
			.tag('div')
				.css('clear', 'both')
				.done()
			.wikitext(frame:expandTemplate{title = 'template sandbox notice', args = {args[cfg.livepageArg]}})
		return tostring(root)
	else
		return nil
	end
end

function p.protectionTemplate()
	if currentTitle.namespace == 10 then -- We are in the template namespace.
		local frame = mw.getCurrentFrame()

		local function getProtectionLevel(protectionType)
			-- Gets the protection level for the current page.
			local level = frame:callParserFunction('PROTECTIONLEVEL', protectionType)
			if level ~= '' then
				return level
			else
				return nil -- The parser function returns the blank string if there is no match.
			end
		end

		if getProtectionLevel('move') == 'sysop' or getProtectionLevel('edit') then
			-- The page is full-move protected, or full, template, or semi-protected.
			return frame:expandTemplate{title = 'pp-template', args = {docusage = 'yes'}}
		end
	end
	return nil
end

p.startBox = makeInvokeFunc('_startBox')

function p._startBox(args)
	-- Arg processing from {{documentation}}.
	local preload = args[cfg.preloadArg] -- Allow custom preloads.
	local heading = args[cfg.headingArg] -- Blank values are not removed.
	local headingStyle = args['cfg.heading-sStyle'Arg]
	local content = args[cfg.contentArg]
	local docspace = p.docspace()
	local docname = args[1] -- Other docname, if fed.
	local templatePage = p.templatePage()

	-- Arg processing from {{documentation/start box2}}.
	local docpage
	if docname then
(contracted; show full)
	return tostring(sbox)
end

p.content = makeInvokeFunc('_content')

function p._content(args)
	local content = args
[cfg.contentArg]
	if not content then
		local docpage = args[1]
		if docpage and mw.title.new(docpage).exists then
			local frame = mw.getCurrentFrame()
			content = frame:preprocess('{{ ' .. docpage .. ' }}')
		else
			docpage = p.docspace() .. ':' .. p.templatePage() .. '/doc'
			if mw.title.new(docpage).exists then
				local frame = mw.getCurrentFrame()
				content = frame:preprocess('{{ ' .. docpage .. ' }}')
			end
		end
	end
	-- The line breaks below are necessary so that "=== Headings ===" at the start and end
	-- of docs are interpreted correctly.
	return '\n' .. (content or '') .. '\n' 
end

p.endBox = makeInvokeFunc('_endBox')

function p._endBox(args)
	-- Argument processing in {{documentation}}.
	local preload = args.preload -- Allow custom preloads.
	local content = args[cfg.contentArg]
	local linkBox = args['link box'cfg.linkBoxArg] -- So "link box=off" works.
	local docspace = p.docspace()
	local docname = args[1] -- Other docname, if fed.
	local templatePage = p.templatePage()

	-- Argument processing in {{documentation/end box2}}.
	local docpageRoot = (docspace or currentTitle.nsText) .. ':' .. (templatePage or currentTitle.text)
	local docpage
(contracted; show full)	if subpage == 'sandbox' or subpage == 'testcases' then
		return currentTitle.baseText
	else
		return currentTitle.text
	end
end

return p