Module:Icon box/sandbox
| This is the module sandbox page for Module:Icon box (diff). |
| This Lua module is used on approximately 255,000 pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
| This module depends on the following other modules: |
Create a compact box with a list of icons and links, suitable for talk page banners. For mainspace usage, see {{Portal}} instead.
Usage
{{#invoke:Icon box|main|portal1=|portal2=|...|project1=|project2=|...|noticeboard1=|noticeboard2=|...}}
- Create a box with a optional list of portals, projects, and noticeboards
Specialized usage
{{#invoke:Icon box|portal|portal1|portal2|...}}
- Create box with a list of portals
{{#invoke:Icon box|wikiproject|projectname1|projectname2|...}}
- Create box with a list of wikiprojects
{{#invoke:Icon box|noticeboard|projectname1|projectname2|...}}
- Create box with a list of notice boards (usually WikiProject talk pages)
{{#invoke:Icon box|all|projectname}}
- Create box with a Portal, WikiProject, and Noticeboard/talk page
{{#invoke:Icon box|workgroup|wikiproject|work group}}
- Create box with a link to a work group within a wikiproject
{{#invoke:Icon box|taskforce|wikiproject|task force}}
- Create box with a link to a task force within a wikiproject
Named arguments
- align, float
- how to place box on page, default "right"
- color
- background color for box
- size
- font size. If bare number, interpreted as pt
- lh
- line height
- width
- width of box. If bare number, interpreted as px
- talign
- alignment of link text, defaults to "center"
- image
- (all, workgroup, and taskforce only, no namespace prefix) override default image
- ilink
- (all, workgroup, and taskforce only) override link in icon
require('strict')
local p = {}
-- FUNCTIONS TO GENERATE LINKS AND ICONS
local function exists(title)
local success, titleExists = pcall(function() return title.exists end)
-- If success = false, then we're out of expensive parser function calls
-- in that case, assume it exists
return not success or titleExists
end
-- If requested link doesn't exist, instead return link to directory
local defaultPortal = '[[Portal:Contents/Portals|Portal<br/>Directory]]'
local defaultWikiproject = '[[Wikipedia:WikiProject Council/Directory|WikiProject<br/>Directory]]'
local defaultNoticeboard = '[[Wikipedia:Regional notice boards|Regional<br/>Notice Boards]]'
local function portalLink(item)
local title = mw.title.new('Portal:' .. item)
if title and exists(title) then
local separator = mw.ustring.len(item) > 24 and ' ' or '<br/>'
return string.format('[[Portal:%s|%s%sportal]]',
item, item, separator), true
end
return defaultPortal, false
end
local function wikiProjectLink(item)
local title = mw.title.new('Wikipedia:WikiProject '..item)
if title and exists(title) then
local separator = mw.ustring.len(item) > 24 and ' ' or '<br/>'
return string.format('[[Wikipedia:WikiProject %s|WikiProject%s%s]]',
item, separator, item), true
end
return defaultWikiproject, false
end
-- Function to infer a country from a string (item)
-- String can either be country name, ISO 3166 code, or adjectival form,
-- or other miscellaneous string found in countryMap in [[Module:Icon box/data]]
local function findCountry(item)
local country = item
local countryMap = require('Module:Icon box/data').countryMap
if countryMap[item] then
country = countryMap[item]
else
local adjective = require('Module:CountryAdjectiveDemonym').getCountryFromAdjective
local adjName = adjective({args={item}})
if adjName and adjName ~= '' then
country = adjName
elseif mw.ustring.match(item,'^%a%a%a?$') or mw.ustring.match(item,'^%a%a%a?-%a%a%a?$') then
local iso3166 = require('Module:ISO_3166').luaname
local isoName = iso3166({item,nocat='true'})
if isoName and isoName ~= '' then
country = isoName
end
end
end
return country
end
local function noticeboardLink(country)
local linkMap = require('Module:Icon box/data').linkMap
local titleStr = linkMap[country] or "Wikipedia talk:WikiProject "..country
local title = mw.title.new(titleStr)
local text
if title and exists(title) then
local textMap = require('Module:Icon box/data').textMap
text = (textMap[country] or country).."<br/>notice board"
return '[['..titleStr..'|'..text..']]', true
end
return defaultNoticeboard, false
end
-- Function to generate link to work group or task force subproject
-- Arguments:
-- project = name of wikiproject
-- workgroup = name of work group or task force within wikiproject
-- groupType = either "work group" or "task force"
-- label = if non-nil, override workgroup in displayed link
local function workgroupLink(project, workgroup, groupType, label)
label = label or workgroup
local title = mw.title.new('Wikipedia:WikiProject '..project..'/'..workgroup..' '..groupType)
if title and exists(title) then
local separator = mw.ustring.len(workgroup) > 24 and ' ' or '<br/>'
return string.format('[[Wikipedia:WikiProject %s/%s %s|%s%s%s]]',
project, workgroup, groupType, label, separator, groupType), true
end
return defaultWikiproject, false
end
local function getImage(item,args)
local getPortalImage = require('Module:Portal')._image
local img = args.image or getPortalImage(item, true)
local ilink = args.ilink
if ilink then
img = img:gsub("|link%s*=%s*[^|}]*","")
img = img.."|link="..(ilink == 'none' and '' or ilink)
end
return '[[File:'..img..'|48x24px]]'
end
--FUNCTIONS TO GENERATE HTML+CSS
--The HTML has a container, which has a table, which has one or more rows, each of which has an icon and a link
--Note that the code generates UL/LI so that each row is a list entry: this is so screen readers operate correctly
local function createContainer(args)
local isRight = (args.align == 'right')
local container = mw.html.create('div')
:attr('aria-label',args.ariaLabel or '')
:addClass('noprint')
:addClass('portal')
:addClass(isRight and 'floatright' or 'floatleft')
:attr('role', 'navigation')
:css('border', 'solid #777799 1px')
:css('margin', isRight and '0.2em 0 0.2em 0.2em' or '0.2em 0.2em 0.2em 0')
return container
end
local function createList(container, args)
local bgColor = args.color or 'var(--background-color-base, #fff)'
local textColor = args.color and '#202122' or 'inherit'
local list = container:tag('ul')
:css('display','table')
:css('list-style','none')
:css('border-spacing','2px')
:css('margin',0)
:css('background',bgColor)
:css('color',textColor)
:css('font-size',args.size)
:css('line-height',args.lh)
:css('max-width',args.width)
return list
end
local function createRow(list)
return list:tag('li')
:css('display','table-row')
:css('min-height','24px')
end
local function createImageSpan(row, img)
return row:tag('span')
:css('display','table-cell')
:css('text-align','center')
:css('vertical-align','middle')
:css('padding','1px')
:wikitext(img)
end
-- function to generate HTML span for link
-- Arguments:
-- row = parent HTML for link
-- text = link to display
-- item = name of project/portal to link to (for formatting)
-- args = arguments passed to module
local function createLinkSpan(row, text, item, args)
return row:tag('span')
:css('display','table-cell')
:css('padding','0 0.2em')
:css('text-align',args.talign)
:css('vertical-align','middle')
:css('font-weight','bold')
:css('font-size',mw.ustring.len(item) > 40 and '88%' or '')
:wikitext(text)
end
-- set defaults and units on arguments passed to module
local function processArgs(args)
args.align = args.align or args.float or 'right'
args.size = args.size or 8
if tonumber(args.size) then
args.size = args.size..'pt'
end
args.lh = args.lh or '110%'
args.width = args.width or 200
if tonumber(args.width) then
args.width = args.width..'px'
end
args.talign = args.talign or 'center'
local yesNo = require('Module:Yesno')
args.nodefault = yesNo(args.nodefault)
return args
end
local function generateBoxName(portals, projects, noticeboards)
if portals then
if projects or noticeboards then
return 'Portals and projects'
end
return 'Portals'
end
if projects then
return 'Wikiprojects'
end
if noticeboards then
return 'Noticeboards'
end
return 'Icon box'
end
local function iterateItems(list, items, linkFcn, args)
local hasItem = false
for _, item in ipairs(items) do
item = findCountry(item)
local text, itemExists = linkFcn(item)
if itemExists or (not args.nodefault) then
hasItem = true
item = itemExists and item or 'regional'
local img = getImage(item, args)
local row = createRow(list)
createImageSpan(row, img)
createLinkSpan(row, text, item, args)
end
end
return hasItem
end
-- function that creates portal or wikiproject boxes
-- Arguments:
-- portals = list of portals to display (or nil)
-- projects = list of projects to display (or nil)
-- noticeboards = list of noticeboards to display (or nil)
-- args = parameters for display
-- args.align: how to place box on page, default "right"
-- args.color: background color for box
-- args.size: font size. If bare number, interpreted as pt
-- args.lh: line height
-- args.width: width of box. If bare number, interpreted as px
-- args.talign: alignment of link text, defaults to "center"
function p._main(portals, projects, noticeboards, args)
args = processArgs(args)
args.ariaLabel = generateBoxName(portals, projects, noticeboards)
local container = createContainer(args)
local list = createList(container, args)
local hasItem = false
if portals and iterateItems(list, portals, portalLink, args) then
hasItem = true
end
if projects and iterateItems(list, projects, wikiProjectLink, args) then
hasItem = true
end
if noticeboards and iterateItems(list, noticeboards, noticeboardLink, args) then
hasItem = true
end
if not hasItem then
return nil
end
return container
end
-- Function to generate box that links to work group or task force
-- Arguments:
-- args = parameters for display
-- args[1] or args.wpname: name of wikiproject
-- args[2] or args.wgname: name of work group or task force
-- args.type: "workgroup" or "taskforce" depending on which is desired
-- args.image: override image shown in box (without namespace prefix)
-- args.ilink: override link in image
-- other optional arguments documented in p._main() above
function p._workgroup(args)
args = processArgs(args)
args.color = args.color or '#FFFFFE'
args.wpname = args.wpname or args[1] or '?'
args.wgname = args.wgname or args[2] or 'regional'
local groupType = ''
if args.type == 'workgroup' then
groupType = 'work group'
args.ariaLabel = 'Workgroups'
elseif args.type == 'taskforce' then
groupType = 'task force'
args.ariaLabel = 'Taskforces'
end
local container = createContainer(args)
local list = createList(container, args)
local row = createRow(list)
local img = getImage(args.wgname,args)
local text, wgExists
text, wgExists = workgroupLink(args.wpname, args.wgname, groupType, args.label)
createImageSpan(row, img)
createLinkSpan(row, text, wgExists and args.wgname or '', args)
return container
end
-- Functions to separate named and positional arguments out of frame
-- Also sets default single item to "?"
-- Forbids use of image and ilink arguments
local function separateArgs(frame)
local getArgs = require('Module:Arguments').getArgs
local portalArgs = require('Module:Portal')._processPortalArgs
local args = getArgs(frame)
local items, namedArgs = portalArgs(args)
if not items[1] then
table.insert(items,'?')
end
args.image = nil
args.ilink = nil
return items, namedArgs
end
local function getNumericArgs(args, param)
local pattern = "^"..param.."_?(%d+)$"
local results = {}
for k, v in pairs(args) do
local m = tonumber(mw.ustring.match(k, pattern))
if m then
results[m] = v
end
end
local compressSparseArray = require('Module:TableTools').compressSparseArray
return compressSparseArray(results)
end
-- ENTRY POINTS FOR TEMPLATES
function p.main(frame)
local getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame)
local portals = getNumericArgs(args,"portal")
local projects = getNumericArgs(args,"project")
local noticeboards = getNumericArgs(args,"noticeboard")
local result = p._main(portals, projects, noticeboards, args)
return result and tostring(result) or ""
end
function p.portal(frame)
local portals, args = separateArgs(frame)
local result = p._main(portals, nil, nil, args)
return result and tostring(result) or ""
end
function p.wikiproject(frame)
local projects, args = separateArgs(frame)
local result = p._main(nil, projects, nil, args)
return result and tostring(result) or ""
end
function p.noticeboard(frame)
local noticeboards, args = separateArgs(frame)
local result = p._main(nil, nil, noticeboards, args)
return result and tostring(result) or ""
end
function p.all(frame)
local getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame)
local item = args[1]
if not item then
return ""
end
local result = p._main({item},{item},{item},args)
return result and tostring(result) or ""
end
function p.workgroup(frame)
local getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame)
args.type = 'workgroup'
local result = p._workgroup(args)
return result and tostring(result) or ""
end
function p.taskforce(frame)
local getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame)
args.type = 'taskforce'
local result = p._workgroup(args)
return result and tostring(result) or ""
end
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.
- 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:
- 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.
- 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.
- 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.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.