Module:Gallery: Difference between revisions
Appearance
Content deleted Content added
adds classN for enabling darkmode skin-invert-image Tag: Reverted |
Removes wikilinks and wikicode when adding the caption to the alt text Tag: Reverted |
||
Line 5: | Line 5: | ||
local templatestyles = 'Module:Gallery/styles.css' |
local templatestyles = 'Module:Gallery/styles.css' |
||
local yesno = require('Module:Yesno') |
local yesno = require('Module:Yesno') |
||
local Text = require('Module:Text') |
|||
Text = Text.Text() |
|||
local function trim(s) |
local function trim(s) |
||
Line 174: | Line 176: | ||
-- It is necessary because we add classes codes in the next step, |
-- It is necessary because we add classes codes in the next step, |
||
-- we do not want to let the alt empty with just the non-printing characters. |
-- we do not want to let the alt empty with just the non-printing characters. |
||
alt = caption |
alt = (caption ~= '') and Text.getPlain(caption) or '' |
||
end |
end |
||
Revision as of 16:56, 7 February 2025
![]() | This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
![]() | 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 Lua module is used on approximately 15,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 depends on the following other modules: |
![]() | This module uses TemplateStyles: |
Implements {{gallery}}
Tracking categories
-- This module implements {{gallery}} by wrapping the <gallery> core extension tag.
local p = {}
local templatestyles = 'Module:Gallery/styles.css'
local yesno = require('Module:Yesno')
local Text = require('Module:Text')
Text = Text.Text()
local function trim(s)
return mw.ustring.gsub(mw.ustring.gsub(s or '', '%s', ' '), '^%s*(.-)%s*$', '%1')
end
local tracking, preview
local function isImage(file)
local file = trim(file):lower() -- Case insensitive check
-- Check if it starts with "File:", "Image:", or "Media:"
prefix = file:match("^(%a+):")
if prefix and (prefix == "file" or prefix == "image" or prefix == "media") then
return true
end
local valid_extensions = {
"apng", "djvu", "flac", "gif", "jfi", "jfif", "jif", "jpe", "jpeg", "jpg",
"m1a", "m1v", "m2a", "m2v", "mid", "mp1", "mp2", "mp3", "mpa", "mpe", "mpeg", "mpg",
"mpv", "oga", "ogg", "ogv", "opus", "pdf", "png", "stl", "svg", "svgz", "tif", "tiff",
"wav", "wave", "webm", "webp", "xcf"
}
-- Extract file extension, of 3 or 4 characters only
local ext = file:match("%.(%w%w%w%w?)$")
-- Check if the extension is in the valid list
if ext then
for _, valid_ext in ipairs(valid_extensions) do
if ext == valid_ext then
table.insert(tracking, '[[Category:Pages using gallery without a media namespace prefix]]')
return true
end
end
end
return false
end
local function checkarg(k,v)
if k and type(k) == 'string' then
if k == 'align' or k == 'state' or k == 'style' or k == 'title' or
k == 'width' or k == 'height' or k == 'whitebg' or
k == 'mode' or k == 'footer' or k == 'perrow' or k == 'noborder' or
k:match('^alt%d+$') or k:match('^class%d+$') or k:match('^%d+$') then
-- valid
elseif k == 'captionstyle' then
if not v:match('^text%-align%s*:%s*center[;%s]*$') then
table.insert(tracking, '[[Category:Pages using gallery with the captionstyle parameter]]')
end
else
-- invalid
local vlen = mw.ustring.len(k)
k = mw.ustring.sub(k, 1, (vlen < 25) and vlen or 25)
k = mw.ustring.gsub(k, '[^%w%-_ ]', '?')
table.insert(tracking, '[[Category:Pages using gallery with unknown parameters|' .. k .. ']]')
table.insert(preview, '"' .. k .. '"')
end
end
end
function p.gallery(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
local origArgs = (type(frame.getParent) == 'function') and frame:getParent().args or frame
-- ParserFunctions considers the empty string to be false, so to preserve the previous
-- behavior of {{gallery}}, change any empty arguments to nil, so Lua will consider
-- them false too.
local args = {}
tracking, preview = {}, {}
for k, v in pairs(origArgs) do
if v ~= '' then
args[k] = v
checkarg(k,v)
end
end
if (args.mode or '') == 'packed' and (args.align or '') == '' then
args.align = 'center'
end
if (args.align or '') == 'centre' then
args.align = 'center'
end
local tbl = mw.html.create('div')
tbl:addClass('mod-gallery')
if args.state then
tbl
:addClass('mod-gallery-collapsible')
:addClass('collapsible')
:addClass(args.state)
end
if args.style then
tbl:cssText(args.style)
else
tbl:addClass('mod-gallery-default')
end
if args.align then
tbl:addClass('mod-gallery-' .. args.align:lower())
end
if args.title then
tbl:tag('div')
:addClass('title')
:tag('div')
:wikitext(args.title)
end
local gargs = {}
gargs['class'] = 'nochecker' .. (args.noborder and '' or ' bordered-images')
gargs['widths'] = tonumber(args.width) or 180
gargs['heights'] = tonumber(args.height) or 180
gargs['style'] = args.captionstyle
gargs['perrow'] = args.perrow
gargs['mode'] = args.mode
if yesno(args.whitebg or 'yes') then
gargs['class'] = gargs['class'] .. ' whitebg'
end
local virtualgallery = {}
local gallery = {}
local imageCount = 0
local zwsp = string.char(0xE2, 0x80, 0x8B) -- U+200B Zero Width Space
local zwnj = string.char(0xE2, 0x80, 0x8C) -- U+200C Zero Width Non-Joiner
-- create a coding to identify classes
-- using unicode non-printing characters
-- this is a workaround until we get the class arg in the <gallery> tag
-- https://phabricator.wikimedia.org/T344784
local skininvert = zwsp .. zwsp .. zwsp;
local bgtransparent = zwsp .. zwsp .. zwnj;
for i = 1, #args do
local currentfield = trim(args[i]) or ''
if currentfield == '' then
-- Skip empty fields
elseif isImage(currentfield) then
imageCount = imageCount + 1
virtualgallery[imageCount] = { currentfield }
elseif imageCount > 0 and virtualgallery[imageCount][2] == nil then
-- In case of multiple captions, use the first and ignore the laters
virtualgallery[imageCount][2] = currentfield
end
end
local altCount = 0;
-- Run through virtualgallery and builds gallery
for n = 1, #virtualgallery do
local img = virtualgallery[n][1]
local caption = virtualgallery[n][2] or ''
local alt = trim(args['alt' .. n] or '')
local class = trim(args['class' .. n] or '')
-- we count alt text only before any modification
if alt ~= '' then
altCount = altCount + 1
else
-- if alt is empty, we use the caption as a alt text.
-- It is necessary because we add classes codes in the next step,
-- we do not want to let the alt empty with just the non-printing characters.
alt = (caption ~= '') and Text.getPlain(caption) or ''
end
-- we attach the non-printing code to the end of the alt text
if mw.ustring.find(class, 'skin%-invert') then -- this matches both skin-invert and skin-invert-image
alt = alt .. skininvert
end
-- as it is possible to combine multiple classes, we use find instead of ==
if mw.ustring.find(class, 'bg%-transparent') then
alt = alt .. bgtransparent
end
table.insert(gallery, img ..
(alt ~= '' and ('|alt=' .. alt) or '') ..
(caption ~= '' and ('|' .. caption) or ''))
end
-- For tracking and verifying during migration to the new algorimth.
-- It can be removed once everything is verified
if math.ceil(#args / 2) > imageCount then
if altCount > 0 then
table.insert(tracking, '[[Category:Pages using gallery with potential alt text mismatch]]')
--else
-- table.insert(tracking, '[[Category:Pages using gallery with extra empty fields]]')
end
end
tbl:tag('div')
:addClass('main')
:tag('div')
:wikitext(
frame:extensionTag{ name = 'gallery', content = '\n' .. table.concat(gallery,'\n'), args = gargs}
)
if args.footer then
tbl:tag('div')
:addClass('footer')
:tag('div')
:wikitext(args.footer)
end
local trackstr = (#tracking > 0) and table.concat(tracking, '') or ''
if #preview > 0 then
trackstr = require('Module:If preview')._warning({
'Unknown parameters ' .. table.concat(preview, '; ') .. '.'
}) .. trackstr
end
return frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles} } .. tostring(tbl) .. trackstr
end
return p