Module:File link: Difference between revisions
imported>Mr. Stradivarius (rename the image table to a fileLink table, seeing as this code is applicable to all file links) |
imported>Mr. Stradivarius (don't include the library name in checkSelf method names) |
||
Line 23: | Line 23: | ||
function data:name(s) |
function data:name(s) |
||
checkSelf(self, ' |
checkSelf(self, 'name') |
||
checkType('fileLink:name', 1, s, 'string') |
checkType('fileLink:name', 1, s, 'string') |
||
data.theName = s |
data.theName = s |
||
Line 30: | Line 30: | ||
function data:format(s, filename) |
function data:format(s, filename) |
||
checkSelf(self, ' |
checkSelf(self, 'format') |
||
checkType('fileLink:format', 1, s, 'string', true) |
checkType('fileLink:format', 1, s, 'string', true) |
||
checkType('fileLink:format', 2, format, 'string', true) |
checkType('fileLink:format', 2, format, 'string', true) |
||
Line 62: | Line 62: | ||
function data:width(px) |
function data:width(px) |
||
checkSelf(self, ' |
checkSelf(self, 'width') |
||
checkType('fileLink:width', 1, px, 'number', true) |
checkType('fileLink:width', 1, px, 'number', true) |
||
if px and data.isUpright then |
if px and data.isUpright then |
||
Line 72: | Line 72: | ||
function data:height(px) |
function data:height(px) |
||
checkSelf(self, ' |
checkSelf(self, 'height') |
||
checkType('fileLink:height', 1, px, 'number', true) |
checkType('fileLink:height', 1, px, 'number', true) |
||
if px and data.isUpright then |
if px and data.isUpright then |
||
Line 82: | Line 82: | ||
function data:upright(isUpright, factor) |
function data:upright(isUpright, factor) |
||
checkSelf(self, ' |
checkSelf(self, 'upright') |
||
checkType('fileLink:upright', 1, isUpright, 'boolean', true) |
checkType('fileLink:upright', 1, isUpright, 'boolean', true) |
||
checkType('fileLink:upright', 2, factor, 'number', true) |
checkType('fileLink:upright', 2, factor, 'number', true) |
||
Line 94: | Line 94: | ||
function data:resetSize() |
function data:resetSize() |
||
checkSelf(self, ' |
checkSelf(self, 'resetSize') |
||
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do |
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do |
||
data[field] = nil |
data[field] = nil |
||
Line 102: | Line 102: | ||
function data:location(s) |
function data:location(s) |
||
checkSelf(self, ' |
checkSelf(self, 'location') |
||
checkType('fileLink:location', 1, s, 'string', true) |
checkType('fileLink:location', 1, s, 'string', true) |
||
local validLocations = { |
local validLocations = { |
||
Line 122: | Line 122: | ||
function data:alignment(s) |
function data:alignment(s) |
||
checkSelf(self, ' |
checkSelf(self, 'alignment') |
||
checkType('fileLink:alignment', 1, s, 'string', true) |
checkType('fileLink:alignment', 1, s, 'string', true) |
||
local validAlignments = { |
local validAlignments = { |
||
Line 146: | Line 146: | ||
function data:border(hasBorder) |
function data:border(hasBorder) |
||
checkSelf(self, ' |
checkSelf(self, 'border') |
||
checkType('fileLink:border', 1, hasBorder, 'boolean', true) |
checkType('fileLink:border', 1, hasBorder, 'boolean', true) |
||
data.hasBorder = hasBorder |
data.hasBorder = hasBorder |
||
Line 153: | Line 153: | ||
function data:link(s) |
function data:link(s) |
||
checkSelf(self, ' |
checkSelf(self, 'link') |
||
checkType('fileLink:link', 1, s, 'string', true) |
checkType('fileLink:link', 1, s, 'string', true) |
||
data.theLink = s |
data.theLink = s |
||
Line 160: | Line 160: | ||
function data:alt(s) |
function data:alt(s) |
||
checkSelf(self, ' |
checkSelf(self, 'alt') |
||
checkType('fileLink:alt', 1, s, 'string', true) |
checkType('fileLink:alt', 1, s, 'string', true) |
||
data.theAlt = s |
data.theAlt = s |
||
Line 167: | Line 167: | ||
function data:page(num) |
function data:page(num) |
||
checkSelf(self, ' |
checkSelf(self, 'page') |
||
checkType('fileLink:page', 1, num, 'number', true) |
checkType('fileLink:page', 1, num, 'number', true) |
||
data.thePage = s |
data.thePage = s |
||
Line 174: | Line 174: | ||
function data:class(s) |
function data:class(s) |
||
checkSelf(self, ' |
checkSelf(self, 'class') |
||
checkType('fileLink:class', 1, s, 'string', true) |
checkType('fileLink:class', 1, s, 'string', true) |
||
data.theClass = s |
data.theClass = s |
||
Line 181: | Line 181: | ||
function data:lang(s) |
function data:lang(s) |
||
checkSelf(self, ' |
checkSelf(self, 'lang') |
||
checkType('fileLink:lang', 1, s, 'string', true) |
checkType('fileLink:lang', 1, s, 'string', true) |
||
data.theLang = s |
data.theLang = s |
||
Line 188: | Line 188: | ||
function data:caption(s) |
function data:caption(s) |
||
checkSelf(self, ' |
checkSelf(self, 'caption') |
||
checkType('fileLink:caption', 1, s, 'string', true) |
checkType('fileLink:caption', 1, s, 'string', true) |
||
data.theCaption = s |
data.theCaption = s |
||
Line 195: | Line 195: | ||
function data:render() |
function data:render() |
||
checkSelf(self, ' |
checkSelf(self, 'render') |
||
local ret = {} |
local ret = {} |
||
Revision as of 15:26, 30 May 2014
![]() | This Lua module is used on approximately 76,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This module depends on the following other modules: |
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 aclass
parameter to image links. The MediaWiki software adds this parameter to theclass="..."
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 file wikilinks.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local fileLink = {}
function fileLink.new(filename)
checkType('fileLink.new', 1, filename, 'string', true)
local obj, data = {}, {}
local checkSelf = libraryUtil.makeCheckSelfFunction(
'fileLink',
'fileLink',
obj,
'fileLink object'
)
-- Set the filename if we were passed it as an input to fileLink.new.
if filename then
data.theName = filename
end
function data:name(s)
checkSelf(self, 'name')
checkType('fileLink:name', 1, s, 'string')
data.theName = s
return self
end
function data:format(s, filename)
checkSelf(self, 'format')
checkType('fileLink:format', 1, s, 'string', true)
checkType('fileLink:format', 2, format, 'string', true)
local validFormats = {
thumb = true,
thumbnail = true,
frame = true,
framed = true,
frameless = true
}
if s == nil or validFormats[s] then
data.theFormat = s
data.theFormatFilename = filename
else
error(string.format(
"bad argument #1 to 'fileLink:format' ('%s' is not a valid format)",
s
), 2)
end
return self
end
local function sizeError(methodName)
-- Used for formatting duplication errors in size-related methods.
error(string.format(
"duplicate size argument detected in '%s'"
.. " ('upright' cannot be used in conjunction with height or width)",
methodName
), 3)
end
function data:width(px)
checkSelf(self, 'width')
checkType('fileLink:width', 1, px, 'number', true)
if px and data.isUpright then
sizeError('fileLink:width')
end
data.theWidth = px
return self
end
function data:height(px)
checkSelf(self, 'height')
checkType('fileLink:height', 1, px, 'number', true)
if px and data.isUpright then
sizeError('fileLink:height')
end
data.theHeight = px
return self
end
function data:upright(isUpright, factor)
checkSelf(self, 'upright')
checkType('fileLink:upright', 1, isUpright, 'boolean', true)
checkType('fileLink:upright', 2, factor, 'number', true)
if isUpright and (data.theWidth or data.theHeight) then
sizeError('fileLink:upright')
end
data.isUpright = isUpright
data.uprightFactor = factor
return self
end
function data:resetSize()
checkSelf(self, 'resetSize')
for i, field in ipairs{'theWidth', 'theHeight', 'isUpright', 'uprightFactor'} do
data[field] = nil
end
return self
end
function data:location(s)
checkSelf(self, 'location')
checkType('fileLink:location', 1, s, 'string', true)
local validLocations = {
right = true,
left = true,
center = true,
none = true
}
if s == nil or validLocations[s] then
data.theLocation = s
else
error(string.format(
"bad argument #1 to 'fileLink:location' ('%s' is not a valid location)",
s
), 2)
end
return self
end
function data:alignment(s)
checkSelf(self, 'alignment')
checkType('fileLink:alignment', 1, s, 'string', true)
local validAlignments = {
baseline = true,
middle = true,
sub = true,
super = true,
['text-top'] = true,
['text-bottom'] = true,
top = true,
bottom = true
}
if s == nil or validAlignments[s] then
data.theAlignment = s
else
error(string.format(
"bad argument #1 to 'fileLink:alignment' ('%s' is not a valid alignment)",
s
), 2)
end
return self
end
function data:border(hasBorder)
checkSelf(self, 'border')
checkType('fileLink:border', 1, hasBorder, 'boolean', true)
data.hasBorder = hasBorder
return self
end
function data:link(s)
checkSelf(self, 'link')
checkType('fileLink:link', 1, s, 'string', true)
data.theLink = s
return self
end
function data:alt(s)
checkSelf(self, 'alt')
checkType('fileLink:alt', 1, s, 'string', true)
data.theAlt = s
return self
end
function data:page(num)
checkSelf(self, 'page')
checkType('fileLink:page', 1, num, 'number', true)
data.thePage = s
return self
end
function data:class(s)
checkSelf(self, 'class')
checkType('fileLink:class', 1, s, 'string', true)
data.theClass = s
return self
end
function data:lang(s)
checkSelf(self, 'lang')
checkType('fileLink:lang', 1, s, 'string', true)
data.theLang = s
return self
end
function data:caption(s)
checkSelf(self, 'caption')
checkType('fileLink:caption', 1, s, 'string', true)
data.theCaption = s
return self
end
function data:render()
checkSelf(self, 'render')
local ret = {}
-- Filename
if not data.theName then
error('fileLink:render: no filename was found')
end
ret[#ret + 1] = 'File:' .. data.theName
-- 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.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
-- Render named parameters.
-- That includes link, alt, page, class, and lang.
do
local namedParameters = {'link', 'alt', 'page', 'class', 'lang'}
for i, parameter in ipairs(namedParameters) do
local dataField = 'the' .. parameter:sub(1, 1):upper() .. parameter:sub(2, -1)
local value = data[dataField]
if value then
ret[#ret + 1] = parameter .. '=' .. tostring(value)
end
end
end
-- Caption
ret[#ret + 1] = data.theCaption
return string.format('[[%s]]', table.concat(ret, '|'))
end
local privateFields = {
theName = true,
theFormat = true,
theFormatFilename = true,
theWidth = true,
theHeight = true,
isUpright = true,
uprightFactor = true,
theLocation = true,
theAlignment = true,
hasBorder = true,
theLink = true,
theAlt = true,
thePage = true,
theClass = true,
theLang = true,
theCaption = true
}
local readOnlyFields = {}
for field in pairs(data) do
readOnlyFields[field] = true
end
readOnlyFields.theName = nil -- This is set if a filename is given to fileLink.new, so remove it.
local function restrictedFieldError(key, restriction)
error(string.format(
"fileLink object field '%s' is %s",
tostring(key),
restriction
), 3)
end
setmetatable(obj, {
__index = function (t, key)
if privateFields[key] then
restrictedFieldError(key, 'private')
else
return data[key]
end
end,
__newindex = function (t, key, value)
if privateFields[key] then
restrictedFieldError(key, 'private')
elseif readOnlyFields[key] then
restrictedFieldError(key, 'read-only')
else
data[key] = value
end
end,
__tostring = function (t)
return t:render()
end,
__pairs = function ()
local temp = {}
for k, v in pairs(data) do
if not privateFields[k] then
temp[k] = v
end
end
return pairs(temp)
end
})
return obj
end
return fileLink