Модуль:Партал
Дакумэнтацыю да гэтага модуля можна стварыць у Модуль:Партал/Дакумэнтацыя
--[==[ Гэты модуль — перапісаны на Lua код шаблёну {{Партал}}.
-- Мае дзьве вонкавыя функцыі:
-- p.portal, якая складае сьпіс парталаў;
-- p.image, якая ўтварае назву выяву для асобна ўзятага парталу.
-- Зьвесткі пра выявы парталаў захоўваюцца ў падмодулях [[Модуль:Партал/выявы]], пералічаных ніжэй:
-- [[Модуль:Партал/выявы/а]] — для парталаў, якія пачынаюцца зь літары «А».
-- [[Модуль:Партал/выявы/б]] — для парталаў, якія пачынаюцца зь літары «Б».
-- [[Модуль:Партал/выявы/в]] — для парталаў, якія пачынаюцца зь літары «В».
-- [[Модуль:Партал/выявы/г]] — для парталаў, якія пачынаюцца зь літары «Г».
-- [[Модуль:Партал/выявы/д]] — для парталаў, якія пачынаюцца зь літары «Д».
-- [[Модуль:Партал/выявы/е]] — для парталаў, якія пачынаюцца зь літары «Е».
-- [[Модуль:Партал/выявы/ё]] — для парталаў, якія пачынаюцца зь літары «Ё».
-- [[Модуль:Партал/выявы/ж]] — для парталаў, якія пачынаюцца зь літары «Ж».
-- [[Модуль:Партал/выявы/з]] — для парталаў, якія пачынаюцца зь літары «З».
-- [[Модуль:Партал/выявы/і]] — для парталаў, якія пачынаюцца зь літары «І».
-- [[Модуль:Партал/выявы/к]] — для парталаў, якія пачынаюцца зь літары «К».
-- [[Модуль:Партал/выявы/л]] — для парталаў, якія пачынаюцца зь літары «Л».
-- [[Модуль:Партал/выявы/м]] — для парталаў, якія пачынаюцца зь літары «М».
-- [[Модуль:Партал/выявы/н]] — для парталаў, якія пачынаюцца зь літары «Н».
-- [[Модуль:Партал/выявы/о]] — для парталаў, якія пачынаюцца зь літары «О».
-- [[Модуль:Партал/выявы/п]] — для парталаў, якія пачынаюцца зь літары «П».
-- [[Модуль:Партал/выявы/р]] — для парталаў, якія пачынаюцца зь літары «Р».
-- [[Модуль:Партал/выявы/с]] — для парталаў, якія пачынаюцца зь літары «С».
-- [[Модуль:Партал/выявы/т]] — для парталаў, якія пачынаюцца зь літары «Т».
-- [[Модуль:Партал/выявы/у]] — для парталаў, якія пачынаюцца зь літары «У».
-- [[Модуль:Партал/выявы/ф]] — для парталаў, якія пачынаюцца зь літары «Ф».
-- [[Модуль:Партал/выявы/х]] — для парталаў, якія пачынаюцца зь літары «Х».
-- [[Модуль:Партал/выявы/ц]] — для парталаў, якія пачынаюцца зь літары «Ц».
-- [[Модуль:Партал/выявы/ч]] — для парталаў, якія пачынаюцца зь літары «Ч».
-- [[Модуль:Партал/выявы/ш]] — для парталаў, якія пачынаюцца зь літары «Ш».
-- [[Модуль:Партал/выявы/э]] — для парталаў, якія пачынаюцца зь літары «Э».
-- [[Модуль:Партал/выявы/ю]] — для парталаў, якія пачынаюцца зь літары «Ю».
-- [[Модуль:Партал/выявы/я]] — для парталаў, якія пачынаюцца зь літары «Я».
-- [[Модуль:Партал/выявы/іншыя]] — для парталаў, якія пачынаюцца зь якіх-кольвек іншых сымбаляў.
-- Сюды ўлучаюцца і лічбы, і літары лацінскага альфабэту, і дыякрытычныя знакі.
-- [[Модуль:Партал/выявы/альт]] — для альтэрнатыўных назваў існых парталаў. Зь любых пачатковых літараў.
--
-- Падстаронкі са зьвесткамі пра выявы падзеленыя па першай літары дзеля зьмяншэньня нагрузкі на сэрвэр у выпадку зьмяненьняў ці дапаўненьняў.
-- Зьмяшчэньне ўсіх выяваў на падстаронцы [[Модуль:Партал/выявы]] ў выпадку абнаўленьня аднае з выяваў
-- прыводзіла б да перазагрузкі ўсіх старонак, якія карыстаюцца гэтым модулем.
]==]
local p = {}
local trackingEnabled = true
local templatestyles = 'Модуль:Партал/styles.css'
local yesno = require('Модуль:ТакНе')
-- Праверыць, ці патрэбнае адсочваньне ў гэтай прасторы назваў
-- Вяртае ісьціну, калі старонка не належыць „забароненым“ прасторам
local function checkTrackingNamespace()
local thisPage = mw.title.getCurrentTitle()
if (thisPage.namespace == 1) -- Абмеркаваньне
or (thisPage.namespace == 2) -- Удзельнік
or (thisPage.namespace == 3) -- Гутаркі ўдзельніка
or (thisPage.namespace == 5) -- Абмеркаваньне Вікіпэдыі
or (thisPage.namespace == 7) -- Абмеркаваньне файла
or (thisPage.namespace == 11) -- Абмеркаваньне шаблёну
or (thisPage.namespace == 15) -- Абмеркаваньне катэгорыі
or (thisPage.namespace == 101) -- Абмеркаваньне парталу
or (thisPage.namespace == 109) -- Абмеркаваньне кнігі
or (thisPage.namespace == 118) -- Чарнавік
or (thisPage.namespace == 119) -- Абмеркаваньне чарнавіку
or (thisPage.namespace == 829) -- Абмеркаваньне модулю
then
return false
end
return true
end
-- Праверыць, ці патрэбнае адсочваньне гэтай назвы старонкі
-- Вяртае хлусьню, калі назва старонкі падпадае пад „забароненую“ маску
-- У іншых выпадках — ісьціна
local function checkTrackingPagename()
local thisPage = mw.title.getCurrentTitle()
local thisPageLC = mw.ustring.lower(thisPage.text)
if (string.match(thisPageLC, "/архіў") ~= nil) then
return false
end
if (string.match(thisPageLC, "/дакумэнтацыя") ~= nil) then
return false
end
if (string.match(thisPageLC, "/тэст") ~= nil) then
return false
end
return true
end
local function matchImagePage(s)
-- Шукае адпаведную падстаронку выяваў па назьве парталу
-- і першай літары ягонай назвы ў ніжнім рэгістры.
if type(s) ~= 'string' or #s < 1 then return end
local firstLetter = mw.ustring.sub(s, 1, 1)
local imagePage
if mw.ustring.find(firstLetter, '^[а-я]') then
imagePage = 'Модуль:Партал/выявы/' .. firstLetter
else
imagePage = 'Модуль:Партал/выявы/іншыя'
end
return mw.loadData(imagePage)[s]
end
local function getAlias(s)
-- Вяртае альтэрнатыву з падстаронкі альтэрнатыўных зьвестак пра выявы.
local aliasData = mw.loadData('Модуль:Партал/выявы/альт')
for portal, aliases in pairs(aliasData) do
for _, alias in ipairs(aliases) do
if alias == s then
return portal
end
end
end
end
local function getImageName(s)
-- Вяртае назву выявы для ўваходнага радку.
local default = 'Portal-puzzle.svg|link=|alt='
if type(s) ~= 'string' or #s < 1 then
return default
end
s = mw.ustring.lower(s)
return matchImagePage(s) or matchImagePage(getAlias(s)) or default
end
local function checkPortalExists(portal)
return not (mw.title.makeTitle(100, portal).id == 0)
end
function p._portal(portals, args)
-- Будуе рамку парталу для шаблёну {{Партал}}.
local root = mw.html.create('div')
:attr('role', 'navigation')
:attr('aria-label', 'Portals')
:addClass('noprint portal plainlist notheme')
:addClass(args.left and 'tleft' or 'tright')
:css('margin', args.margin or nil)
:newline()
-- Дапомна адсочваньне ўключанае.
-- Адключаецца, калі выконваецца адна з такіх умоваў:
-- 1) Парамэтар "tracking" зададзены = 'no, 'n' або 'false'
-- 2) Старонка не прайшла праверку прасторы назваў у checkTrackingNamespace()
-- 3) Старонка не прайшла праверку маскі назвы ў checkTrackingPagename()
trackingEnabled = yesno(args.tracking, trackingEnabled)
if (checkTrackingNamespace() == false) then
trackingEnabled = false
end
if (checkTrackingPagename() == false) then
trackingEnabled = false
end
-- Калі парталы не зададзеныя, выводзіць памылку і дадае старонку ў катэгорыю адсочваньня.
if not portals[1] then
if yesno(args.nominimum) then
-- калі парамэтар nominimum зададзены yes (ці падобнае), апусьціць папярэджаньне
else
root:wikitext('<strong class="error">Не зададзеныя парталы: пазначце хаця б адзін</strong>')
end
if (trackingEnabled) then
root:wikitext('[[Катэгорыя:Вікіпэдыя:Шаблён «Партал» без парамэтраў]]')
end
return tostring(root)
end
-- шукае няісныя парталы; калі такія знойдзеныя, то выдаляе іх з вакна вываду.
--- Калі redlinks=yes, то не выдаляе
local portallen = #portals
-- перабірае сьпіс ззаду наперад, каб упэўніцца, што ніякія парталы не прапушчаныя
-- (table.remove таксама ідзе па адваротным сьпісе парталаў, так што наступны партал не праверыцца, калі ісьці ў простым парадку.
-- праход у адваротным кірунку дазваляе абысьці гэтую праблему
for i=portallen,1,-1 do
-- выкарыстаньнем pcall адсочваем любыя памылкі, якія могуць здарыцца
-- пры спробе пошуку старонак з хібнай назвай
-- калі pcall вяртае ісьціну, тады перазапусьціць функцыю для праверкі, ці існуе старонка
if not pcall(checkPortalExists, portals[i]) or not checkPortalExists(portals[i]) then
-- Калі мы тут, значыць знайшоўся чырвоны партал
if yesno(args.redlinks) or (args.redlinks == 'include') then
-- калі redlinks зададзены yes (ці падобныя), дадаць катэгорыю адсочваньня
-- і выйсьці з цыклю перад тым, як партал будзе выдалены з зьпісу
if (trackingEnabled) then
root:wikitext('[[Катэгорыя:Вікіпэдыя:Шаблён «Партал» з чырвонымі спасылкамі]]')
end
break
end
-- прыбраць партал (не спрацуе, калі redlinks=yes)
table.remove(portals,i)
end
end
-- калі даўжыня табліцы зьмянілася, значыць, зь яе былі выдаленыя радкі,
-- то бок парталы. У такім разе дадаць катэгорыю адсочваньня
if not (portallen == #portals) then
if (trackingEnabled) then
if #portals == 0 then
return '[[Катэгорыя:Вікіпэдыя:Шаблён «Партал» з чыста чырвонымі спасылкамі]]'
else
root:wikitext('[[Катэгорыя:Вікіпэдыя:Шаблён «Партал» з чырвонымі спасылкамі]]')
end
end
end
-- Запачаткоўвае сьпіс. Адпавядае пачатку вікі-табліцы ў старым [[Шаблён:Партал]].
local listroot = root:tag('ul')
:css('width', type(args.boxsize) == 'string' and (args.boxsize .. 'px') or nil)
-- Выводзіць парталы, зададзеныя ў пазыцыйных аргумэнтах.
for _, portal in ipairs(portals) do
local image = getImageName(portal)
-- Генэруе html-код для выявы і назвы парталу.
listroot
:newline()
:tag('li')
:tag('span')
:wikitext(string.format('[[Файл:%s|32x28пкс|class=noviewer]]', image))
:done()
:tag('span')
:wikitext(string.format('Вікіпэдыя мае партал\n«[[Партал:%s|%s]]»', portal, portal, args['break'] and '<br />' or ' '))
end
return tostring(root)
end
function p._image(portals)
-- Абгортачная функцыя, каб getImageName() была дасяжная праз #invoke.
local name = getImageName(portals[1])
return name:match('^(.-)|') or name -- ДАРАБІЦЬ: зрабіць больш элегантны спосаб аддзяляць рамкі і інш. ад назвы выявы
end
local function getAllImageTables()
-- Вяртае масіў з усімі падстаронкамі выяваў (без альтэрнатываў), загружаны mw.loadData.
local images = {}
for i, subpage in ipairs{'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'і', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'э', 'ю', 'я', 'іншыя'} do
images[i] = mw.loadData('Модуль:Партал/выявы/' .. subpage)
end
return images
end
function p._displayAll(portals, args)
-- Выводзіць усе парталы, якія маюць зьвязаныя выявы. Функцыя прызначаная не для артыкулаў, а толькі для службовага выкарыстаньня.
local lang = mw.language.getContentLanguage()
local count = 1
for _, imageTable in ipairs(getAllImageTables()) do
for portal in pairs(imageTable) do
portals[count] = lang:ucfirst(portal)
count = count + 1
end
end
return p._portal(portals, args)
end
function p._imageDupes()
-- Шукае падстаронкі на прадмет дублікатаў выяваў. Калі такія выявы існуюць, гэта не абавязкова памылка,
-- бо розныя парталы могуць карыстацца аднымі і тымі ж выявамі. Аднак функцыя дапамагае вызначыць выявы,
-- якія варта перамясьціць на падстаронку альтэрнатыўных назваў.
local exists, dupes = {}, {}
for _, imageTable in ipairs(getAllImageTables()) do
for portal, image in pairs(imageTable) do
if not exists[image] then
exists[image] = portal
else
table.insert(dupes, string.format('Выява «[[:Файл:%s|%s]]» выкарыстоўваецца ў парталах «%s» і «%s».', image, image, exists[image], portal))
end
end
end
if #dupes < 1 then
return 'Дубляваныя выявы адсутнічаюць.'
else
return 'Знойдзеныя такія дубляваныя выявы:\n* ' .. table.concat(dupes, '\n* ')
end
end
local function processPortalArgs(args)
-- Апрацоўвае табліцу аргумэнтаў і вяртае дзьве табліцы: масіў назваў парталаў дзеля апрацоўкі ў ipairs, і табліцу
-- найменных аргумэнтаў, якія вызначаюць налады стыляў і інш. Карыстацца ipairs даводзіцца, паколькі нам патрэбныя
-- сьпісы ўсіх парталаў у тым парадку, у якім яны былі перададзеныя ў шаблён, а таксама неабходна яўна зьвяртацца да
-- пазыцыйных аргумэнтаў, напрыклад {{Партал|2=Хрысьціянства}}. Паводзіны ipairs у выпадку, калі прысутнічаюць пустыя
-- значэньні, нявызначаныя, таму мусім пераканацца, што ўсе яны выдаленыя.
args = type(args) == 'table' and args or {}
local portals = {}
local namedArgs = {}
for k, v in pairs(args) do
if type(k) == 'number' and type(v) == 'string' then -- Правяраем, ці ня маем нерадковых назваў парталаў.
table.insert(portals, k)
elseif type(k) ~= 'number' then
namedArgs[k] = v
end
end
table.sort(portals)
for i, v in ipairs(portals) do
portals[i] = args[v]
end
return portals, namedArgs
end
local function makeWrapper(funcName)
-- Апрацоўвае вонкавыя аргумэнты і перадае ў іншыя функцыі.
return function (frame)
-- Пры выкліку праз #invoke узяць аргумэнты, перададзеныя ў шаблёне
-- альбо ў #invoke. Інакш лічым, што аргумэнты перададзеныя наўпрост
-- з адладачнай кансолі ці зь іншага Lua-модулю.
local origArgs
if type(frame.getParent) == 'function' then
origArgs = frame:getParent().args
for k, v in pairs(frame.args) do
origArgs = frame.args
break
end
else
origArgs = frame
end
-- Абразае пропусты і выдаляе пустыя аргумэнты.
local args = {}
for k, v in pairs(origArgs) do
if type(v) == 'string' then
v = mw.text.trim(v)
end
if v ~= '' then
args[k] = v
end
end
local results = ''
if funcName == '_portal' or funcName == '_displayAll' then
results = frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles} }
end
return results .. p[funcName](processPortalArgs(args)) -- перадае ў функцыю дзьве табліцы: масіў назваў парталаў і табліцу найменаваных аргумэнтаў.
end
end
for _, funcName in ipairs{'portal', 'image', 'imageDupes', 'displayAll'} do
p[funcName] = makeWrapper('_' .. funcName)
end
return p