Module:ElementPortraitCarousel: Difference between revisions
// via Wikitext Extension for VSCode |
// via Wikitext Extension for VSCode |
||
| (3 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
--[[ | --[[ | ||
* Name: ElementPortraitCarousel | |||
* Author: Mark W. Datysgeld | |||
* Description: Element module that renders portrait carousels for Person templates with three display modes based on image count | |||
* Notes: Single image (centered display); dual images (orbital display with animation); multi-image (full carousel with navigation arrows); integrates with Blueprint template system; image sanitization; protected execution with error handling | |||
]] | |||
local p = {} | local p = {} | ||
| Line 15: | Line 12: | ||
-- Load required modules | -- Load required modules | ||
local ErrorHandling = require('Module:ErrorHandling') | local ErrorHandling = require('Module:ErrorHandling') | ||
local TemplateHelpers = require('Module:TemplateHelpers') | |||
-- Default configuration | -- Default configuration | ||
| Line 31: | Line 29: | ||
for image in portrait:gmatch("[^;]+") do | for image in portrait:gmatch("[^;]+") do | ||
local imageName = mw.text.trim(image) | local imageName = mw.text.trim(image) | ||
-- Sanitize logo path - extract filename and remove prefixes | |||
imageName = TemplateHelpers.sanitizeUserInput(imageName, "IMAGE_FILES") | |||
-- Store just the image name, we'll use MediaWiki's renderer | -- Store just the image name, we'll use MediaWiki's renderer | ||
if imageName and imageName ~= "" then | if imageName and imageName ~= "" then | ||
| Line 51: | Line 51: | ||
end | end | ||
-- Create dual-image orbital display HTML | -- Create dual-image orbital display HTML with navigation arrows | ||
local function createDualImages(images, maxWidth) | local function createDualImages(images, maxWidth) | ||
local navId = mw.uri.anchorEncode(mw.title.getCurrentTitle().text or "person") | local navId = mw.uri.anchorEncode(mw.title.getCurrentTitle().text or "person") | ||
| Line 60: | Line 60: | ||
local img2 = frame:preprocess(string.format('[[File:%s|%s]]', images[2], maxWidth)) | local img2 = frame:preprocess(string.format('[[File:%s|%s]]', images[2], maxWidth)) | ||
-- Include navigation arrows similar to the carousel, but keep the orbital animation styles | |||
return string.format( | return string.format( | ||
'<div class="person-portrait-carousel">' .. | '<div class="person-portrait-carousel">' .. | ||
'<div class="carousel-container">' .. | '<div class="carousel-container">' .. | ||
'<div class="carousel-nav carousel-prev">◀</div>' .. | |||
'<div class="carousel-images" id="carousel-%s">' .. | '<div class="carousel-images" id="carousel-%s">' .. | ||
'<div class="carousel-item carousel-orbital-1" data-index="1">%s</div>' .. | '<div class="carousel-item carousel-orbital-1" data-index="1">%s</div>' .. | ||
'<div class="carousel-item carousel-orbital-2" data-index="2">%s</div>' .. | '<div class="carousel-item carousel-orbital-2" data-index="2">%s</div>' .. | ||
'</div></div></div>', | '</div>' .. | ||
'<div class="carousel-nav carousel-next">▶</div>' .. | |||
'</div></div>', | |||
navId, | navId, | ||
img1, img2 | img1, img2 | ||