Module:Shortcut: Difference between revisions
From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Content added Content deleted
(use redirect=no) |
(rewrite this without so many dependencies and with it hopefully easier to read) |
||
Line 1: | Line 1: | ||
-- This module implements {{shortcut}}. |
-- This module implements {{shortcut}}. |
||
-- Set constants |
|||
local cfg = {} |
|||
local CONFIG_MODULE = 'Module:Shortcut/config' |
|||
-- Load required modules |
|||
-------------------------------------------------------------------------------- |
|||
local checkType = require('libraryUtil').checkType |
|||
-- Configuration |
|||
-------------------------------------------------------------------------------- |
|||
-- Name for the error category produced if the first shortcut is not an existing |
|||
-- page on the wiki. |
|||
cfg.errorCategory = 'Wikipedia shortcut box first parameter needs fixing' |
|||
-- The header text for the list of shortcuts. |
|||
-- cfg.shortcutHeaderSingular will be displayed if there is one shortcut, and |
|||
-- cfg.shortcutHeaderPlural will be displayed if there are multiple shortcuts. |
|||
cfg.shortcutHeaderSingular = '[[Wikipedia:Shortcut|Shortcut]]:' |
|||
cfg.shortcutHeaderPlural = '[[Wikipedia:Shortcut|Shortcuts]]:' |
|||
-------------------------------------------------------------------------------- |
|||
-- Load external modules and define often-used functions |
|||
-------------------------------------------------------------------------------- |
|||
-- Load external modules |
|||
local mArguments = require('Module:Arguments') |
|||
local mTableTools = require('Module:TableTools') |
|||
local mList = require('Module:List') |
|||
-- Define often-used functions |
|||
local anchorEncode = mw.uri.anchorEncode |
|||
local format = string.format |
|||
local fullUrl = mw.uri.fullUrl |
|||
-------------------------------------------------------------------------------- |
|||
-- Main functions |
|||
-------------------------------------------------------------------------------- |
|||
local p = {} |
local p = {} |
||
function p. |
function p._main(shortcuts, options, frame, cfg) |
||
checkType('_main', 1, shortcuts, 'table') |
|||
local args = mArguments.getArgs(frame) |
|||
checkType('_main', 2, options, 'table', true) |
|||
return p._main(args) |
|||
options = options or {} |
|||
end |
|||
frame = frame or mw.getCurrentFrame() |
|||
cfg = cfg or mw.loadData(CONFIG_MODULE) |
|||
local nShortcuts = #shortcuts |
|||
-- Validate shortcuts |
|||
function p._main(args) |
|||
local shortcuts = p.getShortcuts(args) |
|||
local nShortcuts = #shortcuts |
|||
if nShortcuts < 1 then |
if nShortcuts < 1 then |
||
return nil |
|||
-- Don't output anything if {{shortcut}} was called with no arguments. |
|||
else |
|||
return '' |
|||
for i, shortcut in ipairs(shortcuts) do |
|||
if type(shortcut) ~= 'string' or #shortcut < 1 then |
|||
error(string.format( |
|||
'shortcut #%d was invalid (shortcuts must be strings of ' .. |
|||
'least one character in length)' |
|||
), 2) |
|||
end |
|||
end |
|||
end |
end |
||
local anchors = p.makeAnchorList(shortcuts) |
|||
local shortcutList = p.makeShortcutList(shortcuts) |
|||
local errorCategories = p.getErrorCategories(shortcuts) |
|||
return p.export(anchors, nShortcuts, shortcutList, errorCategories) |
|||
end |
|||
local root = mw.html.create() |
|||
function p.getShortcuts(args) |
|||
local shortcuts = mTableTools.compressSparseArray(args) |
|||
return shortcuts |
|||
end |
|||
-- Anchors |
|||
function p.makeAnchorList(shortcuts) |
|||
local |
local anchorDiv = root |
||
:tag('div') |
|||
local anchors = {} |
|||
:css('position', 'relative') |
|||
:css('top', '-3em') |
|||
for i, shortcut in ipairs(shortcuts) do |
for i, shortcut in ipairs(shortcuts) do |
||
local anchor = mw.uri.anchorEncode(shortcut) |
|||
anchorDiv:tag('span'):attr('id', anchor) |
|||
end |
end |
||
return table.concat(anchors) |
|||
end |
|||
root:newline() -- To match the old [[Template:Shortcut]] |
|||
function p.makeAnchor(s) |
|||
s = anchorEncode(s) |
|||
local anchor = format('<span id="%s"></span>', s) |
|||
return anchor |
|||
end |
|||
-- Shortcut heading |
|||
function p.makeShortcutList(shortcuts) |
|||
local |
local shortcutHeading = mw.message.newRawMessage( |
||
cfg['shortcut-heading'], |
|||
local listArgs = {} |
|||
nShortcuts |
|||
):plain() |
|||
shortcutHeading = frame:preprocess(shortcutHeading) |
|||
-- Shortcut box |
|||
local shortcutList = root |
|||
:tag('table') |
|||
:addClass('shortcutbox noprint') |
|||
:css('float', 'right') |
|||
:css('border', '1px solid #aaa') |
|||
:css('background', '#fff') |
|||
:css('margin', '.3em .3em .3em 1em') |
|||
:css('padding', '3px') |
|||
:css('text-align', 'center') |
|||
:tag('tr') |
|||
:tag('th') |
|||
:addClass('plainlist') |
|||
:css('border', 'none') |
|||
:css('background', 'transparent') |
|||
:tag('small') |
|||
:wikitext(shortcutHeading) |
|||
:newline() |
|||
:tag('ul') |
|||
for i, shortcut in ipairs(shortcuts) do |
for i, shortcut in ipairs(shortcuts) do |
||
local |
local url = mw.uri.fullUrl(shortcut, {redirect = 'no'}) |
||
url = tostring(url) |
|||
listArgs[#listArgs + 1] = link |
|||
local link = string.format('[%s %s]', url, shortcut) |
|||
shortcutList:tag('li'):wikitext(link) |
|||
end |
|||
if options.msg then |
|||
shortcutList:tag('li'):wikitext(options.msg) |
|||
end |
end |
||
listArgs.class = 'plainlinks' |
|||
return mList.makeList('bulleted', listArgs) |
|||
end |
|||
-- Error category |
|||
function p.makeShortcutLink(s) |
|||
do |
|||
local uriObj = fullUrl(s, {redirect = 'no'}) |
|||
local title = mw.title.new(shortcuts[1]) |
|||
if not title or not title.exists then |
|||
return format('[%s %s]', url, s) |
|||
root:wikitext(string.format( |
|||
'[[%s:%s]]', |
|||
mw.site.namespaces[14].name, |
|||
cfg['first-parameter-error-category'] |
|||
)) |
|||
end |
|||
end |
|||
return tostring(root) |
|||
end |
end |
||
function p. |
function p.main(frame) |
||
local args = require('Module:Arguments').getArgs(frame, { |
|||
local shortcut1 = shortcuts[1] |
|||
wrappers = 'Template:Shortcut' |
|||
local title = mw.title.new(shortcut1) |
|||
}) |
|||
if not title or not title.exists then |
|||
local categoryNsName = mw.site.namespaces[14].name |
|||
-- Separate shortcuts from options |
|||
return format('[[%s:%s]]', categoryNsName, cfg.errorCategory) |
|||
local shortcuts, options = {}, {} |
|||
else |
|||
for k, v in pairs(args) do |
|||
return nil |
|||
if type(k) == 'number' then |
|||
shortcuts[k] = v |
|||
else |
|||
options[k] = v |
|||
end |
|||
end |
end |
||
end |
|||
-- Compress the shortcut array, which may contain nils. |
|||
function p.export(anchors, nShortcuts, shortcutList, errorCategories) |
|||
local |
local function compressArray(t) |
||
local nums, ret = {}, {} |
|||
root |
|||
for k in pairs(t) do |
|||
:tag('div') |
|||
nums[#nums + 1] = k |
|||
:css{position = 'relative', top = '-3em'} |
|||
end |
|||
:wikitext(anchors) |
|||
table.sort(nums) |
|||
root |
|||
for i, num in ipairs(nums) do |
|||
:tag('table') |
|||
ret[i] = t[num] |
|||
:addClass('shortcutbox noprint') |
|||
end |
|||
return ret |
|||
float = 'right', |
|||
end |
|||
border = '1px solid #aaa', |
|||
shortcuts = compressArray(shortcuts) |
|||
background = '#fff', |
|||
margin = '.3em .3em .3em 1em', |
|||
return p._main(shortcuts, options, frame) |
|||
padding = '3px', |
|||
['text-align'] = 'center' |
|||
} |
|||
:tag('tr') |
|||
:tag('th') |
|||
:addClass('plainlist') |
|||
:css{border = 'none', background = 'transparent'} |
|||
:tag('small') |
|||
:wikitext( |
|||
nShortcuts <= 1 |
|||
and cfg.shortcutHeaderSingular |
|||
or cfg.shortcutHeaderPlural |
|||
) |
|||
:newline() |
|||
:wikitext(shortcutList) |
|||
root:wikitext(errorCategories) |
|||
return tostring(root) |
|||
end |
end |
||
Revision as of 07:30, December 15, 2014
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. |
Template:Uses TemplateStyles Template:Lua sidebar This module makes a box showing the shortcut links to a page.
Usage
From wikitext
From wikitext, this module should be called from a template, usually {{shortcut}}. Please see the template page for documentation. However, it can also be called using the syntax {{#invoke:shortcut|main|arguments}}
.
From Lua
To use this module from Lua, first load it.
local mShortcut = require('Module:Shortcut')
Then you can create shortcut boxes with the following syntax:
mShortcut._main(shortcuts, options, frame, cfg)
- shortcuts is an array of shortcut page names. (required)
- options is a table of options. The following keys are supported:
msg
- a message to leave after the list of shortcuts.category
- if set to false (or a value regarded as false by Module:Yesno, such as "no"), categories are suppressed.
- frame a frame object. This is optional, and only intended to be used internally.
- cfg a table of config values. This is optional, and is only intended for testing.
Technical details
This module has a configuration file at Module:Shortcut/config. It can be used to translate this module into different languages or to change details like category names.
-- This module implements {{shortcut}}.
-- Set constants
local CONFIG_MODULE = 'Module:Shortcut/config'
-- Load required modules
local checkType = require('libraryUtil').checkType
local p = {}
function p._main(shortcuts, options, frame, cfg)
checkType('_main', 1, shortcuts, 'table')
checkType('_main', 2, options, 'table', true)
options = options or {}
frame = frame or mw.getCurrentFrame()
cfg = cfg or mw.loadData(CONFIG_MODULE)
local nShortcuts = #shortcuts
-- Validate shortcuts
if nShortcuts < 1 then
return nil
else
for i, shortcut in ipairs(shortcuts) do
if type(shortcut) ~= 'string' or #shortcut < 1 then
error(string.format(
'shortcut #%d was invalid (shortcuts must be strings of ' ..
'least one character in length)'
), 2)
end
end
end
local root = mw.html.create()
-- Anchors
local anchorDiv = root
:tag('div')
:css('position', 'relative')
:css('top', '-3em')
for i, shortcut in ipairs(shortcuts) do
local anchor = mw.uri.anchorEncode(shortcut)
anchorDiv:tag('span'):attr('id', anchor)
end
root:newline() -- To match the old [[Template:Shortcut]]
-- Shortcut heading
local shortcutHeading = mw.message.newRawMessage(
cfg['shortcut-heading'],
nShortcuts
):plain()
shortcutHeading = frame:preprocess(shortcutHeading)
-- Shortcut box
local shortcutList = root
:tag('table')
:addClass('shortcutbox noprint')
:css('float', 'right')
:css('border', '1px solid #aaa')
:css('background', '#fff')
:css('margin', '.3em .3em .3em 1em')
:css('padding', '3px')
:css('text-align', 'center')
:tag('tr')
:tag('th')
:addClass('plainlist')
:css('border', 'none')
:css('background', 'transparent')
:tag('small')
:wikitext(shortcutHeading)
:newline()
:tag('ul')
for i, shortcut in ipairs(shortcuts) do
local url = mw.uri.fullUrl(shortcut, {redirect = 'no'})
url = tostring(url)
local link = string.format('[%s %s]', url, shortcut)
shortcutList:tag('li'):wikitext(link)
end
if options.msg then
shortcutList:tag('li'):wikitext(options.msg)
end
-- Error category
do
local title = mw.title.new(shortcuts[1])
if not title or not title.exists then
root:wikitext(string.format(
'[[%s:%s]]',
mw.site.namespaces[14].name,
cfg['first-parameter-error-category']
))
end
end
return tostring(root)
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = 'Template:Shortcut'
})
-- Separate shortcuts from options
local shortcuts, options = {}, {}
for k, v in pairs(args) do
if type(k) == 'number' then
shortcuts[k] = v
else
options[k] = v
end
end
-- Compress the shortcut array, which may contain nils.
local function compressArray(t)
local nums, ret = {}, {}
for k in pairs(t) do
nums[#nums + 1] = k
end
table.sort(nums)
for i, num in ipairs(nums) do
ret[i] = t[num]
end
return ret
end
shortcuts = compressArray(shortcuts)
return p._main(shortcuts, options, frame)
end
return p