Module:Class/sandbox

-- This module implements [[Template:Class]], [[Template:Class/icon]] and
-- [[Template:Class/colour]].

local mArguments -- lazily loaded
local definitions = mw.loadJsonData('Module:Class/sandbox/definition.json')

local p = {}

--------------------------------------------------------------------------------
-- Local configuration and messages
--------------------------------------------------------------------------------

local cfg = {
	defaultCode = 'DEFAULT',
	classPrefix = 'assess-',
	globalClass = 'assess',
	defaultClassSuffix = 'default',
	unboldClassSuffix = 'unbold',
	catRootFormat = '%s %s',
	catTopicFormat = '%s %s %s',
	catBasicFormat = '%s %s',
	categoryFormat = '[[:Category:%s|%s]]',
	templateLocation = 'Template:Class',
	iconTemplateLocation = 'Template:Class/icon',
	colourTemplateLocation = 'Template:Class/colour',
	stylesLocation = 'Module:Class/styles.css',
	baseColourPath = {'colour', 'base'},
	iconPath = {"icon", "file"},
	iconDefaultPath = {"icon", "default"},
	iconAttribPath = {"icon", "requiresAttribution"},
	fullLabelPath = {"labels", "full"},
	shortLabelPath = {"labels", "short"},
	categoryRootPath = {"categoryRoot"},
	tooltipPath = {"labels", "tooltip"},
	articlePath = {"article"},
	yes = "yes",
	no = "no",
	articles = "articles",
	pages = "pages",
	argumentNames = {
		class = "class",
		style = "style"
	},
	getOptions = {
		--First item is localized argument name, second is case-sensitivity
		bold = {"bold", false},
		header = {"header", false},
		image = {"image", false},
		rowspan = {"rowspan", false},
		fullcategory = {"fullcategory", true},
		category = {"category", true},
		topic = {"topic", true}
	}
}

--------------------------------------------------------------------------------
-- Argument helper functions
--------------------------------------------------------------------------------

local function getRawArgs(frame, wrapper)
	--Retrieves the arguments from the frame
	mArguments = mArguments or require('Module:Arguments')
	return mArguments.getArgs(frame, {
		wrappers = wrapper,
		trim = false,
		removeBlanks = false
	})
end

local function makeInvokeFunction(func, wrapper)
	--Wraps a general function into an invokable version
	return function (frame)
		local args = getRawArgs(frame, wrapper)
		return func(args)
	end
end

--------------------------------------------------------------------------------
-- String helper functions
--------------------------------------------------------------------------------

local function trim(str)
	--Trims strings, passes through non-strings without modification
	return (type(str) == 'string') and mw.text.trim(str) or str
end

local function normalizeValue(val)
	--Normalizes strings, particularly class codes
	if type(val) == 'string' then val = trim(val):lower() end
	if val == '' then val = nil end
	return val
end

local function ucfirst(str)
	--Capitalizes the first character of a string
	return mw.ustring.upper(mw.ustring.sub(str, 1, 1)) .. mw.ustring.sub(str, 2)
end

--------------------------------------------------------------------------------
-- Definition helper functions
--------------------------------------------------------------------------------

local function getDefinition(code)
	--Retrieves the definition and canonical class code for a given code.
	--Returns two values: the definition object and the canonical class code
	--string.
	local canonicalCode = normalizeValue(code)
	if code == cfg.defaultCode then canonicalCode = code end
	local class = definitions[canonicalCode]
	while class and class.alias do
		canonicalCode = class.alias
		class = definitions[class.alias]
	end
	if not class then
		return nil, nil
	end
	return class, canonicalCode
end

local function getDefault()
	--Shortcut function for retrieving the default definition
	return getDefinition(cfg.defaultCode) end

local function getProperty(class, default, map)
	--Retrieves a given property from a string given a class definition, a
	--default class definition, and a map for the path to traverse through the
	--class object. The map should be a sequential table of string property
	--names, e.g. {"colour", "base"} would retrieve someClass.colour.base
	local prop, dProp = class, default
	for k, v in ipairs(map) do
		prop = ((type(prop) == 'table') or nil) and prop[v]
		dProp = ((type(dProp) == 'table') or nil) and dProp[v]
	end
	if prop == nil then prop = dProp end
	return prop
end

--------------------------------------------------------------------------------
-- Color functions
--------------------------------------------------------------------------------

function p._colour(code)
	--Retrieves the base colour for a given code
	return getProperty(getDefinition(code), getDefault(), cfg.baseColourPath)
end

function p.colour(frame)
	--Retrieves the base colour for a given code; is invokable
	local args = getRawArgs(frame, cfg.colourTemplateLocation)
	-- Nowiki tags prevent output beginning with "#" from triggering bug 14974.
	return frame:extensionTag('nowiki', p._colour(args[1]))
end

--------------------------------------------------------------------------------
-- Icon functions
--------------------------------------------------------------------------------

function p._icon(args)
	--Retrieves an icon image and formats it as wikitext
	local class = getDefinition(args[cfg.argumentNames.class] or args[1])
	local default = getDefault()
	local file = getProperty(class, default, cfg.iconPath)
	local label = 
		getProperty(class, default, cfg.tooltipPath) or
		ucfirst(getProperty(class, default, cfg.fullLabelPath))
	local attrib = getProperty(class, default, cfg.iconAttribPath)
	local size = args.size or '16px'
	local span = mw.html.create('span')

	span
		:cssText(args[cfg.argumentNames.style])
		:attr('title', label)
		:wikitext(
			string.format(
				'[[File:%s|%s|' .. size .. '%s|class=noviewer|alt=]]',
				file,
				label,
				attrib and '' or '|link='
			)
		)
	return tostring(span)
end

p.icon = makeInvokeFunction(p._icon, cfg.iconTemplateLocation)
--Invokable version of p._icon

--------------------------------------------------------------------------------
-- Class functions
--------------------------------------------------------------------------------

function p._class(args)
	--Parses its arguments into a table cell with an optional icon, a name
	--linked to an appropriate category, and appropriate colour styling
	local classDef, classCode = getDefinition(args[cfg.argumentNames.class] or args[1])
	local default = getDefault()
	local iconDefault = getProperty(classDef, default, cfg.iconDefaultPath)
	local shortLabel = getProperty(classDef, default, cfg.shortLabelPath)
	local categoryRoot = getProperty(classDef, default, cfg.categoryRootPath)
	local article = getProperty(classDef, false, cfg.articlePath)
	local pagetype = article and cfg.articles or cfg.pages
	--o is short for "options", go for "get options". Bool true → case-sensitive
	local o, go = {}, cfg.getOptions
	for k, v in pairs(go) do
		o[k] = v[2] and trim(args[v[1]]) or normalizeValue(args[v[1]])
	end

	local cell = mw.html.create(o.header and 'th' or 'td')
	--image=yes forces icon, image=no disables it, otherwise checks default
	local icon = iconDefault and (o.image ~= cfg.no) or (o.image == cfg.yes)
	icon = icon and p.icon(args) .. ' ' or ''

	local category
	if o.fullcategory then
		category = o.fullcategory
	elseif o.category then
		category = cfg.catRootFormat:format(categoryRoot, o.category)
	elseif o.topic then
		category = cfg.catTopicFormat:format(categoryRoot, o.topic, pagetype)
	else
		category = cfg.catBasicFormat:format(categoryRoot, pagetype)
	end
	local text = string.format(cfg.categoryFormat, category, shortLabel)
	cell
		:addClass(cfg.globalClass)
		:addClass(
			o.bold == cfg.no and cfg.classPrefix .. cfg.unboldClassSuffix or nil
		)
		:addClass(cfg.classPrefix .. (classCode or cfg.defaultClassSuffix))
		:attr('rowspan', tonumber(o.rowspan))
		:wikitext(mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = {src = cfg.stylesLocation} }, icon, text)

	return tostring(cell)
end

p.class = makeInvokeFunction(p._class, cfg.templateLocation)
--Invokable version of p._class

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.