Module:File link: Difference between revisions

From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Content added Content deleted
(add type checks and write the render function; read-only code not working yet)
(fix read-only behaviour and remove the test function)
Line 14: Line 14:
checkSelf(self, 'name')
checkSelf(self, 'name')
checkType('name', 1, s, 'string')
checkType('name', 1, s, 'string')
self.theName = s
data.theName = s
end
end
Line 29: Line 29:
}
}
if validFormats[s] then
if validFormats[s] then
self.theFormat = s
data.theFormat = s
self.theFormatFilename = filename
data.theFormatFilename = filename
else
else
error('invalid format')
error('invalid format')
Line 39: Line 39:
checkSelf(self, 'width')
checkSelf(self, 'width')
checkType('width', 1, px, 'number')
checkType('width', 1, px, 'number')
self.theWidth = px
data.theWidth = px
end
end
Line 45: Line 45:
checkSelf(self, 'height')
checkSelf(self, 'height')
checkType('height', 1, px, 'number')
checkType('height', 1, px, 'number')
self.theHeight = px
data.theHeight = px
end
end
Line 51: Line 51:
checkSelf(self, 'upright')
checkSelf(self, 'upright')
checkType('upright', 1, factor, 'number', true)
checkType('upright', 1, factor, 'number', true)
self.isUpright = true
data.isUpright = true
self.uprightFactor = factor
data.uprightFactor = factor
end
end
Line 58: Line 58:
checkSelf(self, 'resetSize')
checkSelf(self, 'resetSize')
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do
self[field] = nil
data[field] = nil
end
end
end
end
Line 72: Line 72:
}
}
if validLocations[s] then
if validLocations[s] then
self.theLocation = s
data.theLocation = s
else
else
error(string.format(
error(string.format(
"bad argument #1 to 'image:location' ('%s' is not a valid location)",
"bad argument #1 to 'location' ('%s' is not a valid location)",
s
s
))
))
Line 95: Line 95:
}
}
if validAlignments[s] then
if validAlignments[s] then
self.theAlignment = s
data.theAlignment = s
else
else
error(string.format(
error(string.format(
"bad argument #1 to 'image:alignment' ('%s' is not a valid alignment)"
"bad argument #1 to 'alignment' ('%s' is not a valid alignment)"
))
))
end
end
Line 105: Line 105:
function data:border()
function data:border()
checkSelf(self, 'border')
checkSelf(self, 'border')
self.hasBorder = true
data.hasBorder = true
end
end
Line 111: Line 111:
checkSelf(self, 'link')
checkSelf(self, 'link')
checkType('link', 1, s, 'string')
checkType('link', 1, s, 'string')
self.theLink = s
data.theLink = s
end
end
Line 117: Line 117:
checkSelf(self, 'alt')
checkSelf(self, 'alt')
checkType('alt', 1, s, 'string')
checkType('alt', 1, s, 'string')
self.theAlt = s
data.theAlt = s
end
end
Line 123: Line 123:
checkSelf(self, 'caption')
checkSelf(self, 'caption')
checkType('caption', 1, s, 'string')
checkType('caption', 1, s, 'string')
self.theCaption = s
data.theCaption = s
end
end
function data:render()
function data:render()
checkSelf(self, 'render')
checkSelf(self, 'render')
local ret = {}
local ret = {}
-- Image name.
-- Image name.
if not self.theName then
if not data.theName then
error('image:render: no image name was found')
error('image:render: no image name was found')
end
end
ret[#ret + 1] = 'File:' .. self.theName
ret[#ret + 1] = 'File:' .. data.theName
-- Image format
-- Image format
if self.theFormat and self.theFormatFilename then
if data.theFormat and data.theFormatFilename then
ret[#ret + 1] = self.theFormat .. '=' .. self.theFormatFilename
ret[#ret + 1] = data.theFormat .. '=' .. data.theFormatFilename
elseif self.theFormat then
elseif data.theFormat then
ret[#ret + 1] = self.theFormat
ret[#ret + 1] = data.theFormat
end
end
-- Border
-- Border
if self.hasBorder then
if data.hasBorder then
ret[#ret + 1] = 'border'
ret[#ret + 1] = 'border'
end
end
-- Location
-- Location
ret[#ret + 1] = self.theLocation
ret[#ret + 1] = data.theLocation


-- Alignment
-- Alignment
ret[#ret + 1] = self.theAlignment
ret[#ret + 1] = data.theAlignment
-- Size
-- Size
if self.isUpright and (self.theWidth or self.theHeight) then
if data.isUpright and (data.theWidth or data.theHeight) then
error("duplicate size value detected in 'render' (height/width cannot be used at the same time as 'upright')")
error("duplicate size value detected in 'render' (height/width cannot be used at the same time as 'upright')")
elseif self.isUpright and self.uprightFactor then
elseif data.isUpright and data.uprightFactor then
ret[#ret + 1] = 'upright=' .. tostring(self.uprightFactor)
ret[#ret + 1] = 'upright=' .. tostring(data.uprightFactor)
elseif self.isUpright then
elseif data.isUpright then
ret[#ret + 1] = 'upright'
ret[#ret + 1] = 'upright'
elseif self.theWidth and self.theHeight then
elseif data.theWidth and data.theHeight then
ret[#ret + 1] = string.format('%dx%dpx', self.theWidth, self.theHeight)
ret[#ret + 1] = string.format('%dx%dpx', data.theWidth, data.theHeight)
elseif self.theWidth then
elseif data.theWidth then
ret[#ret + 1] = tostring(self.theWidth) .. 'px'
ret[#ret + 1] = tostring(data.theWidth) .. 'px'
elseif self.theHeight then
elseif data.theHeight then
ret[#ret + 1] = string.format('x%dpx', self.theHeight)
ret[#ret + 1] = string.format('x%dpx', data.theHeight)
end
end
-- Link
-- Link
if self.theLink then
if data.theLink then
ret[#ret + 1] = 'link=' .. self.theLink
ret[#ret + 1] = 'link=' .. data.theLink
end
end
-- Alt
-- Alt
if self.theAlt then
if data.theAlt then
ret[#ret + 1] = 'alt=' .. self.theAlt
ret[#ret + 1] = 'alt=' .. data.theAlt
end
end
-- Caption
-- Caption
ret[#ret + 1] = self.theCaption
ret[#ret + 1] = data.theCaption
return string.format('[[%s]]', table.concat(ret, '|'))
return string.format('[[%s]]', table.concat(ret, '|'))
Line 225: Line 224:
end
end


-- return image
return image

local p = {}

function p.test()
local myImage = image.new()
myImage:name('Foo')
return myImage:render()
end

return p

Revision as of 02:01, May 30, 2014

This module is used to construct wikitext links to files. It is primarily useful for templates and modules that use complicated logic to make file links. Simple file links should be made with wikitext markup directly, as it uses less resources than calling this module. For help with wikitext file markup please refer to the documentation at mediawiki.org.

Usage from wikitext

From wikitext, this module should be called from a template, usually {{file link}}. Please see the template page for documentation. However, it can also be called using the syntax {{#invoke:File link|main|arguments}}.

Usage from Lua

First, you need to import the module.

local mFileLink = require('Module:File link')

Then you can make file links using the _main function.

mFileLink._main(args)

args is a table of arguments that can have the following keys:

  • file - the filename. (required)
  • format - the file format, e.g. 'thumb', 'thumbnail', 'frame', 'framed', or 'frameless'.
  • formatfile - a filename to specify with the 'thumbnail' format option. The filename specified will be used instead of the automatically generated thumbnail.
  • border - set this to true or "yes" (or any other value recognized as true by Module:Yesno) to set a border for the image.
  • location - the horizontal alignment of the file, e.g. 'right', 'left', 'center', or 'none'.
  • alignment - the vertical alignment of the file, e.g. 'baseline', 'middle', 'sub', 'super', 'text-top', 'text-bottom', 'top', or 'bottom'.
  • size - the size of the image, e.g. '100px', 'x100px' or '100x100px'.
  • upright - the 'upright' parameter, used for setting the size of tall and thin images.
  • link - the page that the file should link to. Use the blank string '' to suppress the default link to the file description page.
  • alt - the alt text. Use the blank string '' to suppress the default alt text.
  • caption - a caption for the file.
  • page - sets a page number for multi-paged files such as PDFs.
  • class - adds a class parameter to image links. The MediaWiki software adds this parameter to the class="..." attribute of the image's <img /> element when the page is rendered into HTML.
  • lang - adds a language attribute to specify what language to render the file in.
  • start - specifies a start time for audio and video files.
  • end - specifies an end time for audio and video files.
  • thumbtime - specifies the time to use to generate the thumbnail image for video files.

To see the effect of each of these parameters, see the images help page on mediawiki.org.

Examples

With the file only:

mFileLink.main{file = 'Example.png'}
-- Renders as [[File:Example.png]]

With format, size, link and caption options:

mFileLink.main{
	file = 'Example.png',
	format = 'thumb',
	size = '220px',
	link = 'Wikipedia:Sandbox',
	caption = 'An example.'
}
-- Renders as [[File:Example.png|thumb|220px|link=Wikipedia:Sandbox|An example.]]

With format, size, and border:

mFileLink.main{
	file = 'Example.png',
	format = 'frameless',
	size = '220px',
	border = true
}
-- Renders as [[File:Example.png|frameless|border|220px]]



-- This module provides a library for formatting image wikilinks.

local libraryUtil = require('libraryUtil')

local image = {}

function image.new()
	local obj, data = {}, {}
	
	local checkSelf = libraryUtil.makeCheckSelfFunction('image', 'image', obj, 'image object')
	local checkType = libraryUtil.checkType
	
	function data:name(s)
		checkSelf(self, 'name')
		checkType('name', 1, s, 'string')
		data.theName = s
	end
	
	function data:format(s, filename)
		checkSelf(self, 'format')
		checkType('format', 1, s, 'string')
		checkType('format', 2, format, 'string', true)
		local validFormats = {
			thumb = true,
			thumbnail = true,
			frame = true,
			framed = true,
			frameless = true
		}
		if validFormats[s] then
			data.theFormat = s
			data.theFormatFilename = filename
		else
			error('invalid format')
		end
	end
	
	function data:width(px)
		checkSelf(self, 'width')
		checkType('width', 1, px, 'number')
		data.theWidth = px
	end
	
	function data:height(px)
		checkSelf(self, 'height')
		checkType('height', 1, px, 'number')
		data.theHeight = px
	end
	
	function data:upright(factor)
		checkSelf(self, 'upright')
		checkType('upright', 1, factor, 'number', true)
		data.isUpright = true
		data.uprightFactor = factor
	end
	
	function data:resetSize()
		checkSelf(self, 'resetSize')
		for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do
			data[field] = nil
		end
	end
	
	function data:location(s)
		checkSelf(self, 'location')
		checkType('location', 1, s, 'string')
		local validLocations = {
			right = true,
			left = true,
			center = true,
			none = true
		}
		if validLocations[s] then
			data.theLocation = s
		else
			error(string.format(
				"bad argument #1 to 'location' ('%s' is not a valid location)",
				s
			))
		end
	end
	
	function data:alignment(s)
		checkSelf(self, 'alignment')
		checkType('alignment', 1, s, 'string')
		local validAlignments = {
			baseline = true,
			middle = true,
			sub = true,
			super = true,
			['text-top'] = true,
			['text-bottom'] = true,
			top = true,
			bottom = true
		}
		if validAlignments[s] then
			data.theAlignment = s
		else
			error(string.format(
				"bad argument #1 to 'alignment' ('%s' is not a valid alignment)"
			))
		end
	end
	
	function data:border()
		checkSelf(self, 'border')
		data.hasBorder = true
	end
	
	function data:link(s)
		checkSelf(self, 'link')
		checkType('link', 1, s, 'string')
		data.theLink = s
	end
	
	function data:alt(s)
		checkSelf(self, 'alt')
		checkType('alt', 1, s, 'string')
		data.theAlt = s
	end
	
	function data:caption(s)
		checkSelf(self, 'caption')
		checkType('caption', 1, s, 'string')
		data.theCaption = s
	end
	
	function data:render()
		checkSelf(self, 'render')
		local ret = {}
		
		-- Image name.
		if not data.theName then
			error('image:render: no image name was found')
		end
		ret[#ret + 1] = 'File:' .. data.theName
		
		-- Image format
		if data.theFormat and data.theFormatFilename then
			ret[#ret + 1] = data.theFormat .. '=' .. data.theFormatFilename
		elseif data.theFormat then
			ret[#ret + 1] = data.theFormat
		end
		
		-- Border
		if data.hasBorder then
			ret[#ret + 1] = 'border'
		end
		
		-- Location
		ret[#ret + 1] = data.theLocation

		-- Alignment
		ret[#ret + 1] = data.theAlignment
		
		-- Size
		if data.isUpright and (data.theWidth or data.theHeight) then
			error("duplicate size value detected in 'render' (height/width cannot be used at the same time as 'upright')")
		elseif data.isUpright and data.uprightFactor then
			ret[#ret + 1] = 'upright=' .. tostring(data.uprightFactor)
		elseif data.isUpright then
			ret[#ret + 1] = 'upright'
		elseif data.theWidth and data.theHeight then
			ret[#ret + 1] = string.format('%dx%dpx', data.theWidth, data.theHeight)
		elseif data.theWidth then
			ret[#ret + 1] = tostring(data.theWidth) .. 'px'
		elseif data.theHeight then
			ret[#ret + 1] = string.format('x%dpx', data.theHeight)
		end
		
		-- Link
		if data.theLink then
			ret[#ret + 1] = 'link=' .. data.theLink
		end
		
		-- Alt
		if data.theAlt then
			ret[#ret + 1] = 'alt=' .. data.theAlt
		end
		
		-- Caption
		ret[#ret + 1] = data.theCaption
		
		return string.format('[[%s]]', table.concat(ret, '|'))
	end
	
	local readOnlyFields = {
		theName = true,
		theFormat = true,
		theFormatFilename = true,
		theWidth = true,
		theHeight = true,
		isUpright = true,
		uprightFactor = true,
		theLocation = true,
		theAlignment = true,
		hasBorder = true,
		theLink = true,
		theAlt = true,
		theCaption = true
	}
	for field in pairs(data) do
		readOnlyFields[field] = true
	end
	
	setmetatable(obj, {
		__index = data,
		__newindex = function (t, key, value)
			if readOnlyFields[key] then
				error(string.format(
					"field '%s' is read-only",
					tostring(key)
				), 2)
			else
				data[key] = value
			end
		end,
		__tostring = function (t)
			return t:render()
		end
	})
	
	return obj
end

return image