Module:Shortcut: Difference between revisions
From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Content added Content deleted
(allow output if no shortcuts are set but msg is present) |
m (9 revisions imported: Originally imported from Wikipedia.) |
||
(24 intermediate revisions by 9 users not shown) | |||
Line 6: | Line 6: | ||
-- Load required modules |
-- Load required modules |
||
local checkType = require('libraryUtil').checkType |
local checkType = require('libraryUtil').checkType |
||
local yesno = require('Module:Yesno') |
|||
local p = {} |
local p = {} |
||
local function message(msg, ...) |
|||
return mw.message.newRawMessage(msg, ...):plain() |
|||
end |
|||
local function makeCategoryLink(cat) |
|||
return string.format('[[%s:%s]]', mw.site.namespaces[14].name, cat) |
|||
end |
|||
function p._main(shortcuts, options, frame, cfg) |
function p._main(shortcuts, options, frame, cfg) |
||
Line 15: | Line 24: | ||
frame = frame or mw.getCurrentFrame() |
frame = frame or mw.getCurrentFrame() |
||
cfg = cfg or mw.loadData(CONFIG_MODULE) |
cfg = cfg or mw.loadData(CONFIG_MODULE) |
||
local templateMode = options.template and yesno(options.template) |
|||
local nShortcuts = #shortcuts |
|||
local redirectMode = options.redirect and yesno(options.redirect) |
|||
local isCategorized = not options.category or yesno(options.category) ~= false |
|||
-- Check that we have something to display |
|||
if nShortcuts < 1 and not options.msg then |
|||
return nil |
|||
end |
|||
-- Validate shortcuts |
-- Validate shortcuts |
||
for i, shortcut in ipairs(shortcuts) do |
for i, shortcut in ipairs(shortcuts) do |
||
if type(shortcut) ~= 'string' or #shortcut < 1 then |
if type(shortcut) ~= 'string' or #shortcut < 1 then |
||
error(message(cfg['invalid-shortcut-error'], i), 2) |
|||
error(string.format( |
|||
'shortcut #%d was invalid (shortcuts must be strings of ' .. |
|||
'at least one character in length)' |
|||
), 2) |
|||
end |
end |
||
end |
end |
||
-- Make the list items. These are the shortcuts plus any extra lines such |
|||
local root = mw.html.create() |
|||
-- as options.msg. |
|||
local listItems = {} |
|||
for i, shortcut in ipairs(shortcuts) do |
|||
local templatePath, prefix |
|||
if templateMode then |
|||
-- Namespace detection |
|||
local titleObj = mw.title.new(shortcut, 10) |
|||
if titleObj.namespace == 10 then |
|||
templatePath = titleObj.fullText |
|||
else |
|||
templatePath = shortcut |
|||
end |
|||
prefix = options['pre' .. i] or options.pre or '' |
|||
end |
|||
if options.target and yesno(options.target) then |
|||
listItems[i] = templateMode |
|||
and string.format("{{%s[[%s|%s]]}}", prefix, templatePath, shortcut) |
|||
or string.format("[[%s]]", shortcut) |
|||
else |
|||
listItems[i] = frame:expandTemplate{ |
|||
title = 'No redirect', |
|||
args = templateMode and {templatePath, shortcut} or {shortcut, shortcut} |
|||
} |
|||
if templateMode then |
|||
listItems[i] = string.format("{{%s%s}}", prefix, listItems[i]) |
|||
end |
|||
end |
|||
end |
|||
table.insert(listItems, options.msg) |
|||
-- Return an error if we have nothing to display |
|||
if #listItems < 1 then |
|||
local msg = cfg['no-content-error'] |
|||
msg = string.format('<strong class="error">%s</strong>', msg) |
|||
if isCategorized and cfg['no-content-error-category'] then |
|||
msg = msg .. makeCategoryLink(cfg['no-content-error-category']) |
|||
end |
|||
return msg |
|||
end |
|||
local root = mw.html.create() |
|||
root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = 'Shortcut/styles.css'} }) |
|||
-- Anchors |
-- Anchors |
||
local anchorDiv = root |
local anchorDiv = root |
||
:tag('div') |
:tag('div') |
||
:addClass('module-shortcutanchordiv') |
|||
: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) |
local anchor = mw.uri.anchorEncode(shortcut) |
||
anchorDiv:tag('span'):attr('id', anchor) |
anchorDiv:tag('span'):attr('id', anchor) |
||
end |
end |
||
root:newline() -- To match the old [[Template:Shortcut]] |
|||
-- Shortcut heading |
-- Shortcut heading |
||
local shortcutHeading |
local shortcutHeading |
||
do |
|||
cfg['shortcut-heading'], |
|||
nShortcuts |
local nShortcuts = #shortcuts |
||
if nShortcuts > 0 then |
|||
):plain() |
|||
local headingMsg = options['shortcut-heading'] or |
|||
shortcutHeading = frame:preprocess(shortcutHeading) |
|||
redirectMode and cfg['redirect-heading'] or |
|||
cfg['shortcut-heading'] |
|||
shortcutHeading = message(headingMsg, nShortcuts) |
|||
shortcutHeading = frame:preprocess(shortcutHeading) |
|||
end |
|||
end |
|||
-- Shortcut box |
-- Shortcut box |
||
local shortcutList = root |
local shortcutList = root |
||
:tag(' |
:tag('div') |
||
:addClass(' |
:addClass('module-shortcutboxplain plainlist noprint') |
||
: |
:attr('role', 'note') |
||
if options.float and options.float:lower() == 'left' then |
|||
:css('border', '1px solid #aaa') |
|||
shortcutList:addClass('module-shortcutboxleft') |
|||
: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 |
end |
||
if options. |
if options.clear and options.clear ~= '' then |
||
shortcutList: |
shortcutList:css('clear', options.clear) |
||
end |
end |
||
if shortcutHeading then |
|||
shortcutList |
|||
-- Error category |
|||
:tag('div') |
|||
if shortcuts[1] then |
|||
:addClass('module-shortcutlist') |
|||
local title = mw.title.new(shortcuts[1]) |
|||
:wikitext(shortcutHeading) |
|||
if not title or not title.exists then |
|||
end |
|||
root:wikitext(string.format( |
|||
local list = shortcutList:tag('ul') |
|||
'[[%s:%s]]', |
|||
for i, item in ipairs(listItems) do |
|||
mw.site.namespaces[14].name, |
|||
list:tag('li'):wikitext(item) |
|||
cfg['first-parameter-error-category'] |
|||
)) |
|||
end |
|||
end |
end |
||
return tostring(root) |
return tostring(root) |
||
end |
end |
||
function p.main(frame) |
function p.main(frame) |
||
local args = require('Module:Arguments').getArgs(frame |
local args = require('Module:Arguments').getArgs(frame) |
||
wrappers = 'Template:Shortcut' |
|||
}) |
|||
-- Separate shortcuts from options |
-- Separate shortcuts from options |
Latest revision as of 18:11, January 24, 2022
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 yesno = require('Module:Yesno')
local p = {}
local function message(msg, ...)
return mw.message.newRawMessage(msg, ...):plain()
end
local function makeCategoryLink(cat)
return string.format('[[%s:%s]]', mw.site.namespaces[14].name, cat)
end
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 templateMode = options.template and yesno(options.template)
local redirectMode = options.redirect and yesno(options.redirect)
local isCategorized = not options.category or yesno(options.category) ~= false
-- Validate shortcuts
for i, shortcut in ipairs(shortcuts) do
if type(shortcut) ~= 'string' or #shortcut < 1 then
error(message(cfg['invalid-shortcut-error'], i), 2)
end
end
-- Make the list items. These are the shortcuts plus any extra lines such
-- as options.msg.
local listItems = {}
for i, shortcut in ipairs(shortcuts) do
local templatePath, prefix
if templateMode then
-- Namespace detection
local titleObj = mw.title.new(shortcut, 10)
if titleObj.namespace == 10 then
templatePath = titleObj.fullText
else
templatePath = shortcut
end
prefix = options['pre' .. i] or options.pre or ''
end
if options.target and yesno(options.target) then
listItems[i] = templateMode
and string.format("{{%s[[%s|%s]]}}", prefix, templatePath, shortcut)
or string.format("[[%s]]", shortcut)
else
listItems[i] = frame:expandTemplate{
title = 'No redirect',
args = templateMode and {templatePath, shortcut} or {shortcut, shortcut}
}
if templateMode then
listItems[i] = string.format("{{%s%s}}", prefix, listItems[i])
end
end
end
table.insert(listItems, options.msg)
-- Return an error if we have nothing to display
if #listItems < 1 then
local msg = cfg['no-content-error']
msg = string.format('<strong class="error">%s</strong>', msg)
if isCategorized and cfg['no-content-error-category'] then
msg = msg .. makeCategoryLink(cfg['no-content-error-category'])
end
return msg
end
local root = mw.html.create()
root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = 'Shortcut/styles.css'} })
-- Anchors
local anchorDiv = root
:tag('div')
:addClass('module-shortcutanchordiv')
for i, shortcut in ipairs(shortcuts) do
local anchor = mw.uri.anchorEncode(shortcut)
anchorDiv:tag('span'):attr('id', anchor)
end
-- Shortcut heading
local shortcutHeading
do
local nShortcuts = #shortcuts
if nShortcuts > 0 then
local headingMsg = options['shortcut-heading'] or
redirectMode and cfg['redirect-heading'] or
cfg['shortcut-heading']
shortcutHeading = message(headingMsg, nShortcuts)
shortcutHeading = frame:preprocess(shortcutHeading)
end
end
-- Shortcut box
local shortcutList = root
:tag('div')
:addClass('module-shortcutboxplain plainlist noprint')
:attr('role', 'note')
if options.float and options.float:lower() == 'left' then
shortcutList:addClass('module-shortcutboxleft')
end
if options.clear and options.clear ~= '' then
shortcutList:css('clear', options.clear)
end
if shortcutHeading then
shortcutList
:tag('div')
:addClass('module-shortcutlist')
:wikitext(shortcutHeading)
end
local list = shortcutList:tag('ul')
for i, item in ipairs(listItems) do
list:tag('li'):wikitext(item)
end
return tostring(root)
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame)
-- 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