وحدة:Multiple image
| صفحة وحدة لوا متضمنة في قرابة 37٬000 صفحة ويمكن ملاحظتها على نطاق واسع. أختبر تغييرات الوحدة في /الملعب أو /المختبر أو صفحات فرعية، أو عبر ملعب الوحدة. فكر في مناقشة التغييرات في صفحة نقاش قبل تنفيذها. |
| هذه الوحدة تستخدم أنماط قالب: |
هذه الوحدة مستعملة في قالب:عدة صور.
يمكن استدعاء الوحدة {{#استدعاء:Multiple image|render|.. قائمة المدخلات ..}} لتخفيض مستويات التضمين.
--[[
وحدة لمعالجة قالب متعدد الصور
تستخدم لإنشاء معارض صور متعددة بتخطيطات مختلفة
]]
local p = {}
-- دالة مساعدة للتحقق من أن القيمة غير فارغة
local function isnotempty(s)
return s and s:match('^%s*(.-)%s*$') ~= ''
end
-- دالة مساعدة لإزالة 'px' أو 'بك' من نهاية السلسلة
local function removepx(s)
return tostring(s or ''):match('^(.*)[Pp][Xx]%s*$') or tostring(s or ''):match('^(.*)بك%s*$') or s
end
-- دالة مساعدة للحصول على وسيط من جدول الوسائط
local function getArg(pargs, keys)
for _, key in ipairs(keys) do
-- جرب المفتاح كما هو
if isnotempty(pargs[key]) then
return pargs[key]
end
local alt1 = key:gsub('_', ' ')
if alt1 ~= key and isnotempty(pargs[alt1]) then
return pargs[alt1]
end
local alt2 = key:gsub(' ', '_')
if alt2 ~= key and isnotempty(pargs[alt2]) then
return pargs[alt2]
end
end
return nil
end
-- قاموس لتحويل الاتجاهات من العربية إلى الإنجليزية
local dir_ar_to_en = {
["v"] = 'vertical',
["عمودي"] = 'vertical',
["vertical"] = 'vertical',
["رأسي"] = 'vertical',
["أفقي"] = 'horizontal',
["horizontal"] = 'horizontal',
["h"] = 'horizontal',
}
-- قاموس لتحويل المحاذاة من العربية إلى الإنجليزية
local ar_to_en = {
["يسار"] = 'left',
["يمين"] = 'right',
["مركز"] = 'center',
["وسط"] = 'center',
["left"] = 'left',
["right"] = 'right',
["center"] = 'center'
}
-- قاموس لفئات الصور المصغرة
local thumbclass = {
["يسار"] = 'tleft',
["left"] = 'tleft',
["none"] = 'tnone',
["center"] = 'tnone',
["مركز"] = 'tnone',
["وسط"] = 'tnone',
["centre"] = 'tnone',
["right"] = 'tright',
["يمين"] = 'tright'
}
-- دالة للحصول على أبعاد الصورة
local function getdimensions(s, w, h)
local width, height
if tonumber(w) and tonumber(h) then
p.nonautoscaledimages = true
width, height = tonumber(w), tonumber(h)
else
local file = s and mw.title.new('File:' .. mw.uri.decode(mw.ustring.gsub(s, '%|.*$', ''), 'WIKI'))
file = file and file.file or {width = 0, height = 0}
width = tonumber(file.width) or 0
height = tonumber(file.height) or 0
p.autoscaledimages = true
end
return width, height
end
-- دالة لعرض خلية الصورة
local function renderImageCell(image, width, height, link, alt, thumbtime, caption, textalign, istyle, lang)
local root = mw.html.create('')
local altstr = '|alt=' .. (alt or '')
local linkstr = link and ('|link=' .. link) or ''
local widthstr = '|' .. tostring(width) .. 'px'
local thumbtimestr = isnotempty(thumbtime) and ('|thumbtime=' .. thumbtime) or ''
local langstr = isnotempty(lang) and ('|lang=' .. lang) or ''
local imagediv = root:tag('div')
imagediv:addClass('thumbimage')
imagediv:cssText(istyle)
if height then
imagediv:css('height', tostring(height) .. 'px')
imagediv:css('overflow', 'hidden')
end
imagediv:wikitext('[[ملف:' .. image .. langstr .. widthstr .. linkstr .. altstr .. thumbtimestr .. ']]')
if isnotempty(caption) then
local captiondiv = root:tag('div')
captiondiv:addClass('thumbcaption')
if isnotempty(textalign) then
captiondiv:addClass('text-align-' .. textalign)
end
captiondiv:wikitext(caption)
end
return tostring(root)
end
-- دالة للحصول على العرض الافتراضي
local function getWidth(w1, w2)
local w
if isnotempty(w1) then
w = tonumber(w1)
elseif isnotempty(w2) then
w = tonumber(w2)
end
return w or 200
end
-- دالة لتحديد عدد الصور في كل صف
local function getPerRow(pstr, ic)
local pr = mw.text.split(pstr or '', '[^%d][^%d]*')
if #pr < 1 then
pr = {tostring(ic)}
end
local r = 1
local thisrow = tonumber(pr[1] or ic) or ic
local prownum = {}
while ic > 0 do
prownum[r] = thisrow
ic = ic - thisrow
r = r + 1
thisrow = math.min(tonumber(pr[r] or thisrow) or ic, ic)
end
return prownum
end
-- الدالة الرئيسية لعرض الصور المتعددة
local function renderMultipleImages(pargs, args)
local dir = dir_ar_to_en[getArg(pargs, {'direction', 'اتجاه'}) or args['direction'] or args['اتجاه']] or ''
local width = removepx(pargs['width'] or pargs['عرض'] or '')
local border = pargs['border'] or args['border'] or ''
local align = ar_to_en[getArg(pargs, {'align', 'محاذاة'}) or args['align'] or args['محاذاة']] or ''
local capalign = ar_to_en[getArg(pargs, {'caption_align', 'محاذاة_تعليق'}) or args['caption_align'] or args['محاذاة_تعليق']] or ''
local totalwidth = removepx(getArg(pargs, {'total_width', 'مجمل_العرض'}) or args['total_width'] or args['مجمل_العرض'] or '')
local imgstyle = getArg(pargs, {'image_style', 'نمط_الصورة'}) or args['image_style'] or args['نمط_الصورة']
local header = getArg(pargs, {'header', 'title', 'رأس', 'عنوان'}) or args['title'] or args['عنوان'] or args['header'] or args['رأس']
local footer = getArg(pargs, {'footer', 'تذييل'}) or args['footer'] or args['تذييل']
local imagegap = tonumber(pargs['image_gap'] or '1') or 1
local header_align = ar_to_en[getArg(pargs, {'header_align', 'محاذاة_العنوان'})] or ''
local footer_align = ar_to_en[getArg(pargs, {'footer_align', 'محاذاة_التذييل'}) or args['footer_align'] or args['محاذاة_التذييل']] or 'right'
local background_color = getArg(pargs, {'background color', 'لون_الخلفية'})
local header_bg = getArg(pargs, {'header_background', 'خلفية_العنوان'})
local footer_bg = getArg(pargs, {'footer_background', 'خلفية_التذييل'})
local perrow_arg = getArg(pargs, {'perrow', 'لكل_سطر'})
-- البحث عن جميع الصور غير الفارغة
local imagenumbers = {}
local imagecount = 0
for k, v in pairs(pargs) do
local i = tonumber(tostring(k):match('^%s*image([%d]+)%s*$') or tostring(k):match('^%s*صورة([%d]+)%s*$') or '0')
if i > 0 and isnotempty(v) then
table.insert(imagenumbers, i)
imagecount = imagecount + 1
end
end
-- ترتيب أرقام الصور
table.sort(imagenumbers)
-- إنشاء مصفوفة بعدد الصور في كل صف
local perrow = getPerRow(dir == 'vertical' and '1' or perrow_arg, imagecount)
local rowcount = #perrow
-- تخزين أبعاد الصور وحساب أبعاد الصفوف
local heights = {}
local widths = {}
local widthmax = 0
local widthsum = {}
local k = 0
for r = 1, rowcount do
widthsum[r] = 0
for c = 1, perrow[r] do
k = k + 1
if k <= imagecount then
local i = imagenumbers[k]
if isnotempty(totalwidth) then
local a_image = pargs['image' .. i] or pargs['صورة' .. i]
local a_width = pargs['width' .. i] or pargs['عرض' .. i]
local a_height = pargs['height' .. i] or pargs['ارتفاع' .. i]
widths[k], heights[k] = getdimensions(a_image, a_width, a_height)
else
local a_width = pargs['width' .. i] or pargs['عرض' .. i]
widths[k] = getWidth(width, a_width)
end
widthsum[r] = widthsum[r] + widths[k]
end
end
widthmax = math.max(widthmax, widthsum[r])
end
-- التأكد من أن الفجوة بين الصور غير سالبة
if imagegap < 0 then imagegap = 0 end
-- إذا تم تحديد العرض الكلي، تغيير حجم الصور
if isnotempty(totalwidth) then
totalwidth = tonumber(totalwidth)
widthmax = 0
local k = 0
for r = 1, rowcount do
local koffset = k
local tw = totalwidth - (3 + imagegap) * (perrow[r] - 1) - 12
local ar = {}
local arsum = 0
for j = 1, perrow[r] do
k = k + 1
if k <= imagecount then
local i = imagenumbers[k]
local h = heights[k] or 0
if h > 0 then
ar[j] = widths[k] / h
heights[k] = h
else
ar[j] = widths[k] / 100
end
arsum = arsum + ar[j]
end
end
local ht = tw / arsum
local ws = 0
k = koffset
for j = 1, perrow[r] do
k = k + 1
if k <= imagecount then
local i = imagenumbers[k]
widths[k] = math.floor(ar[j] * ht + 0.5)
ws = ws + widths[k]
if heights[k] then
heights[k] = math.floor(ht)
end
end
end
widthsum[r] = ws
widthmax = math.max(widthmax, widthsum[r])
end
end
-- بدء بناء مصفوفة الصور إذا كانت هناك صور
if imagecount > 0 then
-- حساب عرض div الخارجي
local bodywidth = 0
for r = 1, rowcount do
if widthmax == widthsum[r] then
bodywidth = widthmax + (3 + imagegap) * (perrow[r] - 1) + 12
end
end
bodywidth = math.max(100, bodywidth - 8)
local bg = background_color or ''
local root = mw.html.create('div')
root:addClass('thumb')
root:addClass('tmulti')
root:addClass(thumbclass[align] or 'tleft')
if align == 'center' or align == 'centre' then
root:addClass('center')
end
if bg ~= '' then
root:css('background-color', bg)
end
local div = root:tag('div')
div:addClass('thumbinner')
div:css('width', tostring(bodywidth) .. 'px')
:css('max-width', tostring(bodywidth) .. 'px')
if bg ~= '' then
div:css('background-color', bg)
end
if border == 'infobox' or border == 'none' then
div:css('border', 'none')
end
-- إضافة العنوان
if isnotempty(header) then
div:tag('div')
:addClass('trow')
:tag('div')
:addClass('theader')
:css('text-align', header_align)
:css('background-color', header_bg)
:wikitext(header)
end
-- حلقة لعرض الصور
local k = 0
for r = 1, rowcount do
local rowdiv = div:tag('div'):addClass('trow')
for j = 1, perrow[r] do
k = k + 1
if k <= imagecount then
local imagediv = rowdiv:tag('div')
imagediv:addClass('tsingle')
if bg ~= '' then
imagediv:css('background-color', bg)
end
if imagegap > 1 and j < perrow[r] then
-- in Arabic margin-left
imagediv:css('margin-left', tostring(imagegap) .. 'px')
end
local i = imagenumbers[k]
local img = pargs['image' .. i] or pargs['صورة' .. i]
local w = widths[k]
local a_caption = pargs['caption' .. i] or pargs['تعليق' .. i]
local a_link = pargs['link' .. i] or pargs['وصلة' .. i] -- الجديد
local a_alt = pargs['alt' .. i] or pargs['بديل' .. i] -- الجديد
imagediv:css('width', tostring(2 + w) .. 'px')
:css('max-width', tostring(2 + w) .. 'px')
:wikitext(renderImageCell(img, w, heights[k],
a_link, a_alt, -- استخدام المتغيرات الجديدة
pargs['thumbtime' .. i], a_caption, capalign, imgstyle, pargs['lang' .. i]))
end
end
end
-- إضافة التذييل
if isnotempty(footer) then
local footerContainer = div:tag('div')
:addClass('trow')
:css('display', 'block')
local footerDiv = footerContainer:tag('div')
:addClass('thumbcaption')
:css('text-align', footer_align)
:css('background-color', footer_bg)
if footer_align == 'center' then
footerDiv:css('display', 'block')
:css('margin-left', 'auto')
:css('margin-right', 'auto')
end
footerDiv:wikitext(footer)
end
return tostring(root)
end
return ''
end
-- دالة للاستدعاء من القوالب
function p.render(frame)
local pargs = frame:getParent().args or {}
local args = frame.args or {}
p.autoscaledimages = false
p.nonautoscaledimages = false
local result = frame:extensionTag {
name = 'templatestyles',
args = {src = 'Multiple image/styles.css', wrapper = ".tmulti"}
} .. renderMultipleImages(pargs, args)
if p.autoscaledimages then
result = result .. '[[تصنيف:صفحات تستخدم قالب عدة صور بمقاس تلقائي]]'
end
if p.nonautoscaledimages then
result = result .. '[[تصنيف:صفحات تستخدم قالب عدة صور بمقاس محدد]]'
end
return result
end
-- جعل الدالة متاحة للاستدعاء من وحدات أخرى
function p.renderMultipleImages(args)
return renderMultipleImages(args,args)
.. mw.getCurrentFrame():extensionTag( 'templatestyles', '', { src = "Multiple image/styles.css"})
end
return p