Moduł:Sprawdź
Ten moduł zapewnia platformę programistyczną dla tworzenia szablonów budujących przypadki testowe szablonów Wikipedii. Przypadki testowe mogą być tworzone ręcznie, aczkolwiek te tworzone za pomocą szablonów opartych na module Lua, takim jak niniejszy moduł, mają taką zaletę, że argumenty szablonu muszą być wprowadzone jedynie jednokrotnie, co zmniejsza nakład pracy konieczny do tworzenia testów, a także zmniejsza ryzyko występowania błędów w danych wejściowych.
Porównaj
Ta funkcja jest obecnie wykorzystywana przez szablon {{Przypadek testowy}}.
Parametry
Funkcja do wykrywania wywołań szablonów z nierozpoznanymi, pustymi lub przestarzałymi parametrami. Należy ją wywołać ze wszystkimi możliwymi parametrami jakie przyjmuje szablon podlegający sprawdzaniu.
- Opis parametrów
pole | status | uwagi | |
---|---|---|---|
bez nazwy | konfiguracja działania | wymagany | klasa lub klasa odstęp suffix |
inny | deklaracja pola obsługiwanego w szablonie | opcjonalny | txt, num, num?, uri, uri?, old, ^…$ lub pusty |
- Konfiguracja
- klasa – ciąg znaków bez spacji umieszczany jako wartość atrybutu class w tagu <span> z wygenerowanym raportem
- odstęp – ciąg znaków odstępu oddzielający pozostałą treść konfiguracji, jeśli zawiera znak nowej linii to przed wygenerowanym raportem jest również umieszczany znak nowej linii
- suffix – treść dołączana po wygenerowanym raporcie, zwykle deklaracja technicznej kategorii
- Sprawdzanie parametrów
- pusty – parametr jest opcjonalny, jest to najczęściej stosowany sposób użycia
- txt – oczekiwana jest dowolna niepusta wartość pola
- text – oczekiwana jest dowolna niepusta wartość pola, która nie generuje obrazka
- text? – oczekiwana jest wartość pola, która nie generuje obrazka
- num – sprawdzanie czy przekazana wartość jest liczbą
- num? – sprawdzanie czy przekazana wartość jest pusta lub jest liczbą
- uri – sprawdzanie czy przekazana wartość jest linkiem obsługiwanym przez MediaWiki
- uri? – sprawdzanie czy przekazana wartość jest pusta lub jest linkiem
- grafika – sprawdzanie czy przekazana wartość jest nazwą pliku graficznego
- grafika? – sprawdzanie czy przekazana wartość jest pusta lub jest nazwą pliku graficznego
- old – informuje, że przekazywany parametr jest przestarzały
- ^…$ – tekst rozpoczynający się znakiem
^
i zakończony na$
w całości traktowany jest jako wyrażenie regularne Lua wskazującego prawidłowy parametr
Modyfikator | Brak parametru
np. {{formatprice}} |
Pusty parametr
np. {{formatprice|1=}} |
Niepusty parametr
np. {{formatprice|123}} |
---|---|---|---|
?[uwaga 2] | poprawne | poprawne | wg testu |
bez mod. | poprawne | wg testu | wg testu |
! | Brakujące pola: ... | wg testu | wg testu |
- Przykład
- {{#invoke:Sprawdź|Parametry|=problemy-w-szablonie [[Kategoria:Błędy wywołań w szablonie]]|parametr_w_szablonie_1=|parametr_w_szablonie_2=num?}}
odn
Funkcja sprawdzająca prawidłowość parametrów w {{odn}}.
Uwagi
local function checkUri(uri) local urilen = #uri for _,v in ipairs(mw.loadData("Moduł:Cytuj/dane").supportedUriSchemas) do if (#v < urilen) and (string.lower(string.sub(uri,1, #v)) == v) then return not string.match(uri, '%s') end end end function checkImageName(name) if not name or (#name==0) or string.match(name, "[#<>%[%]|{}]") then return false end local title = mw.title.makeTitle("Plik", name) if not title then return false end local res = { prefix = { plik = true, image = true, grafika = true, file = true, }, extension = { jpg = true, jpeg = true, jpe = true, png = true, svg = true, tif = true, tiff = true, gif = true, xcf = true, pdf = true, djvu = true, webp = true, }, } local prefix = string.match(name, "^:? *([^:]+) *:") if prefix and res.prefix[string.lower(prefix)] then return false end local extension = string.match(name, "%S.*%.([^%.]+)$") return extension and res.extension[string.lower(extension)] end local function findPlainHttp(text) if text then text = mw.ustring.gsub(text, "%[[hH][tT][tT][pP][sS]?://%S+", "_") return string.match(text, "[hH][tT][tT][pP][sS]?://%S") end end local function findFile(text) -- schowaj wyjątek: obrazek generowany przez Szablon:Link-interwiki text = mw.ustring.gsub(text, "%[%[Plik:Wikidata%-logo%-en%.svg|10x9px|link=:d:Q%d+|Informacje powiązane z artykułem „.-” w Wikidanych%]%]", "") -- normalize text = mw.ustring.gsub(text, "%s*[Pp]lik%s*:%s*", "Plik:") text = mw.ustring.gsub(text, "%s*[Ff]ile%s*:%s*", "Plik:") text = mw.ustring.gsub(text, "%s*[Gg]rafika%s*:%s*", "Plik:") text = mw.ustring.gsub(text, "%s*[Ii]mage%s*:%s*", "Plik:") return mw.ustring.match(text, "%[%[Plik:([^%[%]|]+)[|%]]") end -- Lista of template params for wikicode. Like this: -- | grafika = | data śmierci = | www = local function listToTplParams(strArray) return "| " .. table.concat(strArray, " = | ") .. " ="; end local function showTemplate(templateName, args) local result = {} local flags = {} table.insert(result, mw.text.nowiki("{{")) if mw.isSubsting() then table.insert(result, "subst:") end local title = mw.title.new(templateName) if not args then table.insert(result, "[[") table.insert(result, title.nsText) table.insert(result, ":") table.insert(result, title.text) table.insert(result, "|") end if title.namespace ~= 10 then table.insert(result, title.nsText) table.insert(result, ":") end table.insert(result, title.text) if not args then table.insert(result, "]]") end if args then local i = 1 while args[i] do table.insert(result, "|") table.insert(result, mw.text.nowiki(args[i])) i = i + 1 end for k, v in pairs(args) do local index = tonumber(k) if (type(k) == "string") or (index and ((index < 1) or (index > i))) then table.insert(result, "|") table.insert(result, tostring(k)) table.insert(result, "=") table.insert(result, mw.text.nowiki(v)) end end end table.insert(result, mw.text.nowiki("}}")) return table.concat(result) end local function infoboxCatTitle(infobox, class) local catTitle = mw.title.makeTitle(14, "Infoboksy – "..class.." – "..infobox) if not catTitle.exists then mw.logObject(catTitle, "Dedykowana kategoria błędów w infoboksie nie istnieje") catTitle = mw.title.makeTitle(14, "Infoboksy – "..class) end mw.logObject(catTitle, "infoboxCatTitle") return catTitle end local function daysInMonth(year, month) if month == 1 then return 31 end if month == 2 then return ((year % 4) == 0) and 29 or 28 end if month == 3 then return 31 end if month == 4 then return 30 end if month == 5 then return 31 end if month == 6 then return 30 end if month == 7 then return 31 end if month == 8 then return 31 end if month == 9 then return 30 end if month == 10 then return 31 end if month == 11 then return 30 end if month == 12 then return 31 end return 0 end local function isDate20YYMMDD(date) local y, m, d = mw.ustring.match(date, "^(20[0-9][0-9])%-([01][0-9])%-([0123][0-9])$") local year = tonumber(y) local month = tonumber(m) local day = tonumber(d) local result = year and month and day and (year >= 2001) and (month >= 1) and (month <= 12) and (day >= 1) and (day <= daysInMonth(year, month)) if not result then mw.logObject({date=date,year=year,month=month,day=day}, "isDate20YYMMDD") end return result end return { ["Porównaj"] = function(frame) local config = frame:getParent().args[""] or "" local options = mw.text.split(config, "|") local templateName = mw.text.trim(options[1]) if #templateName == 0 then local title = mw.title.getCurrentTitle() if title.namespace == 10 then templateName = mw.ustring.match(title.text, "^(.-)/opis") or mw.ustring.match(title.text, "^(.-)/test") or mw.ustring.match(title.text, "^(.-)/brudnopis") or title.text end if #templateName == 0 then mw.log("brak nazwy szablonu") return end end local templateTitle = mw.title.new(templateName, 10) if templateTitle.id == 0 then mw.log("szablon '"..templateName.."' nie istnieje") return end local sandboxName = templateName.."/brudnopis" local sandboxTitle = mw.title.new(sandboxName, 10) if sandboxTitle.id == 0 then mw.log("brudnopis '"..sandboxName.."' nie istnieje") return end local i = 2 local showparams = true local showinfo = true local vertical = false while i <= #options do local option = mw.text.trim(options[i]) if option == "bez wikikodu" then showparams = false elseif option == "bez opisu" then showinfo = false elseif option == "pionowo" then vertical = true end i = i + 1 end local templateParams = {} local params = {} for k, v in pairs(frame:getParent().args) do if k ~= "" then templateParams[k] = v table.insert(params, k) end end local result = {} table.insert(result, '<table style="width: 100%;">') if showparams and (#params > 0) then local compare = function(a, b) -- return a < b if (type(a) == "number") and (type(b) == "number") then return a < b end if (type(a) == "string") and (type(b) == "string") then return a < b end if (type(a) == "number") and (type(b) == "string") then return true end return false end table.sort(params, compare) table.insert(result, "<caption><code>{{") table.insert(result, templateName) for i, k in ipairs(params) do table.insert(result, " | ") local p = mw.text.nowiki(tostring(k)) local v = mw.text.nowiki(templateParams[k]) table.insert(result, p) table.insert(result, " = ") table.insert(result, v) end table.insert(result, "}}</code></caption>") end local templateResult = frame:expandTemplate{ title=templateName, args=templateParams} local sandboxResult = frame:expandTemplate{ title=sandboxName, args=templateParams} if templateResult and string.match(templateResult, "^{|") then templateResult = "\n"..templateResult end if sandboxResult and string.match(sandboxResult, "^{|") then sandboxResult = "\n"..sandboxResult end if vertical and showinfo then table.insert(result, '<tr><th style="width: 15em">[[Szablon:') table.insert(result, templateName) table.insert(result, '|Szablon]]</th><td>') table.insert(result, templateResult) table.insert(result, '</td></tr><tr><th>[[Szablon:') table.insert(result, sandboxName) table.insert(result, '|Brudnopis szablonu]]</th><td>') table.insert(result, sandboxResult) table.insert(result, '</td></tr>') elseif vertical then table.insert(result, '<tr><td>') table.insert(result, templateResult) table.insert(result, '</td></tr><tr><td>') table.insert(result, sandboxResult) table.insert(result, '</td></tr>') else if showinfo then table.insert(result, '<tr><th style="width: 50%;">[[Szablon:') table.insert(result, templateName) table.insert(result, '|Szablon]]</th><th style="width: 50%;">[[Szablon:') table.insert(result, sandboxName) table.insert(result, '|Brudnopis szablonu]]</th></tr>') end table.insert(result, '<tr style="vertical-align: top;"><td>') table.insert(result, templateResult) table.insert(result, '</td><td>') table.insert(result, sandboxResult) table.insert(result, '</td></tr>') end table.insert(result, "</table>") return table.concat(result) end, ["Parametry"] = function(frame) if mw.title.getCurrentTitle().contentModel ~= "wikitext" then mw.logObject(mw.title.getCurrentTitle().contentModel, "mw.title.getCurrentTitle().contentModel") return -- to nie ma sensu w takim wypadku end local unknown = {} local invalid = {} local deprecated = {} local nakedurl = {} local files = {} local templateName = frame:getParent():getTitle() local infobox = mw.ustring.match(templateName, "^Szablon:(.- infobox)$") local config = frame.args[""] local class, space, category = string.match(config or "", "^%s*(%S+)(%s+)(.-)%s*$") local nl = space and string.match(space, "\n") or "" class = class or config local function argName(arg) return type(arg) ~= "string" and tostring(arg) or ('"'..arg..'"') end local required = {} for k, v in pairs(frame.args) do if mw.ustring.match(v, "!$") then required[k] = true if infobox then -- odróżniaj pola sugerowane w infoboksach, które mogą być puste if v == "!" or mw.ustring.match(v, "%?!$") then required[k] = false else local pattern = string.match(v,"^(^.-$)!?$") if pattern and mw.ustring.match("", pattern) then required[k] = false end end end end end local emptyArg = false for k, v in pairs(frame:getParent().args) do required[k] = nil local kind = frame.args[k] if kind == "" or kind == "!" then kind = "text?" end if k == "" then emptyArg = v elseif not kind then table.insert(unknown, argName(k)) elseif (kind == "num") or (kind == "num!") then local n = tonumber(v) if not n then table.insert(invalid, argName(k)) end elseif (kind == "num?") or (kind == "num?!") then local n = (#v == 0) or tonumber(v) if not n then table.insert(invalid, argName(k)) end elseif (kind == "grafika") or (kind == "grafika!") then if findPlainHttp(v) then table.insert(nakedurl, argName(k)) else local g = checkImageName(v) if not g then table.insert(invalid, argName(k)) end end elseif (kind == "grafika?") or (kind == "grafika?!") then if findPlainHttp(v) then table.insert(nakedurl, argName(k)) else local g = (#v == 0) or checkImageName(v) if not g then table.insert(invalid, argName(k)) end end elseif (kind == "uri") or (kind == "uri!") then local u = checkUri(v) if not u then table.insert(invalid, argName(k)) end elseif (kind == "uri?") or (kind == "uri?!") then local u = (#v == 0) or checkUri(v) if not u then table.insert(invalid, argName(k)) end elseif (kind == "txt") or (kind == "txt!") then if #v == 0 then table.insert(invalid, argName(k)) elseif checkUri(v) then table.insert(nakedurl, argName(k)) elseif findPlainHttp(v) then table.insert(nakedurl, argName(k)) end elseif (kind == "text") or (kind == "text!") or (kind == "text?") then if ((kind ~= "text?") and (#v == 0)) then table.insert(invalid, argName(k)) elseif findFile(v) then table.insert(files, argName(k)) elseif checkUri(v) then table.insert(nakedurl, argName(k)) elseif findPlainHttp(v) then table.insert(nakedurl, argName(k)) end elseif kind == "old" then table.insert(deprecated, argName(k)) elseif kind == "uri*" then -- specjalny przpadek dla pola 'url' w [[Szablon:Cytuj]] local u = checkUri(v) or checkUri(mw.text.unstripNoWiki(v)) if not u then table.insert(invalid, argName(k)) end else local pattern = string.match(kind,"^(^.-$)!?$") if pattern and not mw.ustring.match(v, pattern) then table.insert(invalid, argName(k)) elseif (#v > 0) and checkUri(v) then table.insert(nakedurl, argName(k)) elseif findPlainHttp(v) then table.insert(nakedurl, argName(k)) end end end local missing = {} local suggested = {} mw.logObject(required, "required") for k, v in pairs(required) do table.insert(v and missing or suggested, k) end if (#missing == 0) and (#suggested == 0) and (#unknown == 0) and (#invalid == 0) and (#deprecated == 0) and (#nakedurl == 0) and (#files == 0) then return nil end local errorClasses = 0 -- generate messages for each category of problems local messages = {} if #invalid > 0 then errorClasses = errorClasses + 2 table.insert(messages, "Nieprawidłowe/puste pola: " .. mw.text.listToText(invalid) .. ".") end if (#missing > 0) or (#suggested > 0) then errorClasses = errorClasses + 1 if (#missing > 0) then table.insert(messages, "Brakujące pola: " .. mw.text.listToText(missing) .. ".") end if (#suggested > 0) then table.insert(messages, "Sugerowane pola (wstaw w kodzie): <code>" .. listToTplParams(suggested) .. "</code>") end end if #unknown > 0 then errorClasses = errorClasses + 4 table.insert(messages, "Nieznane pola: " .. mw.text.listToText(unknown) .. ".") end if #deprecated > 0 then errorClasses = errorClasses + 8 table.insert(messages, "Przestarzałe pola: " .. mw.text.listToText(deprecated) .. ".") end if #nakedurl > 0 then errorClasses = errorClasses + 16 table.insert(messages, "Gołe linki: " .. mw.text.listToText(nakedurl) .. ".") end if #files > 0 then errorClasses = errorClasses + 32 table.insert(messages, "Nieoczekiwana grafika: " .. mw.text.listToText(files) .. ".") end -- render messages local message = mw.html.create() if emptyArg then message:wikitext("|=", emptyArg, "| ") end if infobox then message:wikitext("\n* ", table.concat(messages, "\n* ")) else message:wikitext(table.concat(messages, " ")) end message = tostring(message) -- result container local result = mw.html.create(infobox and "table" or "span") result:addClass("problemy") :addClass(class or nil) :attr("aria-hidden", "true") local restext = result if infobox then result:addClass("infobox") restext = result:tag("tr"):tag("td") else result:attr("data-nosnippet", "") end if templateName then restext:wikitext(showTemplate(templateName).." ") -- pomiń ten komunikat jeśli zabraknie tylko pól sugerowanych w infoboksie if not infobox or (errorClasses ~= 1) or (#missing > 0) then local warning = mw.html.create() warning:tag("code"):wikitext(showTemplate(templateName, frame:getParent().args)) warning:wikitext(" ") warning:tag("span"):addClass("problemy"):wikitext(message) mw.addWarning(tostring(warning)) end end restext:wikitext(message) if category then result:wikitext(category) end if infobox then if (errorClasses == 1) and (#missing <= 0) then result:addClass("tylko-braki") -- tylko SUGEROWANE braki end if mw.title.getCurrentTitle().namespace == 0 then if (#missing > 0) or (#suggested > 0) then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "brakujące parametry").text, "]]") end if #invalid > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "nieprawidłowe parametry").text, "]]") end if #unknown > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "nieznane parametry").text, "]]") end if #deprecated > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "przestarzałe parametry").text, "]]") end if #nakedurl > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "gołe linki").text, "]]") end if #files > 0 then result:wikitext("[[Kategoria:", infoboxCatTitle(infobox, "grafika w nieodpowiednim miejscu").text, "]]") end end end return nl..tostring(result) end, ["odn"] = function(frame) local pf = frame:getParent() local i = 1 local problems = false local yeardetected = false while true do local arg = pf.args[i] if not arg then problems = i == 1 and "brak argumentów" or false break end if (i > 5) or yeardetected then problems = "za dużo argumentów pozycyjnych" break end if #arg == 0 then problems = "pusty argument" break end if arg ~= mw.text.trim(arg) then problems = "nieoczekiwane odstępy na początku lub końcu argumentu" break end if string.match(arg, "^%d+%l?$") then yeardetected = true if i == 1 then problems = "rok musi być ostatnim parametrem po nazwiskach autorów" break end elseif string.match(arg, "^s[%-%.:]%s*%d+") then problems = "prawdopodobnie nieprawidłowo podany numer strony" break elseif string.match(arg, "%s%s") then problems = "podwójne odstępy" break elseif mw.ustring.match(arg, "^%a+%d") then if not mw.ustring.match(arg, "^[%u%d]+$") then problems = "prawdopodobnie sklejone argumenty (brak pionowej kreski)" break end elseif mw.ustring.match(arg, "^OdeB ") then -- [[Ordre de Bataille]] elseif mw.ustring.match(arg, "^%u%l+%u") then local justification = { ["De"] = true, ["Del"] = true, ["Di"] = true, ["Le"] = true, ["Mac"] = true, ["Mc"] = true, ["Te"] = true, -- TeSelle ["Sar"] = true, -- SarDesai ["Van"] = true, -- VanBuren ["La"] = true, -- LaSalle } if not justification[mw.ustring.match(arg, "^%u%l+")] then problems = "prawdopodobnie sklejone argumenty (brak pionowej kreski)" break end end i = i + 1 end if not problems then local odn = pf.args.odn if odn and ((#odn ~= 1) or (odn < "a") or (odn > "z")) then problems = "nieoczekiwany parametr odn" end end if not problems then local s = pf.args.s if s and string.match(s, "&[a-z]+;") then problems = "użyto encji HTML w numerze strony" end end if not problems then if pf.args.strona or pf.args.ss or pf.args.strony or pf.args.p or pf.args.page or pf.args.pp or pf.args.pages then problems = "przestarzały parametr z numerem strony" end end if not problems then return nil end local result = mw.html.create("span") :addClass("problemy") :addClass("problemy-w-odn") if mw.title.getCurrentTitle().namespace == 0 then result:wikitext("[[Kategoria:Szablon odn do sprawdzenia]]") end result:wikitext("ODN: ", problems) return tostring(result) end, ["Wikidane"] = function(frame) local property = frame.args.cecha local field = frame.args.pole local value = frame.args[1] if not property or not field then return end if not value then value = frame:getParent().args[field] if not value or (#value == 0) then return end end local entity = mw.wikibase.getEntity() if not entity or not entity.claims or not entity.claims[property] then return end for i, v in ipairs(entity.claims[property]) do if v.mainsnak.snaktype == "value" then if value == v.mainsnak.datavalue.value then return end end end local template = frame:getParent():getTitle() local infobox = mw.ustring.match(template, "^Szablon:(.- infobox)$") return mw.ustring.format("[[Kategoria:%s – niezgodność w Wikidanych – %s – %s]]", infobox and "Infoboksy" or "Szablony", infobox or template, field) end, ["bez parametrów"] = function(frame) for k, v in pairs(frame:getParent().args) do return nil end return "tak" end, ["pole z hostem"] = function (frame) local host = frame.args.host if host and (#host > 0) then for k, v in pairs(frame:getParent().args) do local link = string.match(v, "[hH][tT][tT][pP][sS]?://[%S]+") if link then local uri = mw.uri.new(link) local valid, _ = mw.uri.validate(uri) if valid and uri.host and (#uri.host > 0) then if host == uri.host then mw.logObject({k, link}, "cały") return k end if #host < #uri.host then local s1 = '.'..host local s2 = string.sub(uri.host, -#s1) if s1 == s2 then mw.logObject({k, link}, "fragment") return k end end end end end end end, ["pola z autorami"] = function (frame) local result = {} local nazwisko = frame.args["nazwisko"] local imie = frame.args["imię"] local autor = frame.args["autor"] local link = frame.args["link"] local maxIndex = tonumber(frame.args["max"]) local prefix = frame.args["przed"] or "" local suffix = frame.args["po"] or "" for i = 1, maxIndex do local s = i == 1 and "" or tostring(i) local nin = string.gsub(nazwisko, '#', s) local iin = string.gsub(imie, '#', s) local ain = string.gsub(autor, '#', s) local lin = string.gsub(link, '#', s) local niv = frame:getParent().args[nin] local iiv = frame:getParent().args[iin] local aiv = frame:getParent().args[ain] local liv = frame:getParent().args[lin] local nis = niv and (#niv > 0) local iis = iiv and (#iiv > 0) local ais = aiv and (#aiv > 0) local lis = liv and (#liv > 0) local bad = (nis and ais) -- nazwisko -> zbędny autor or (nis and not iis) -- nazwisko bez imienia or (lis and not nis and not ais) -- tylko link or (iis and not nis) -- imię bez nazwiska if bad then table.insert(result, i) end end if #result > 0 then return prefix..mw.text.listToText(result)..suffix end end, ["uri"] = function(frame) mw.logObject(frame:getParent():getTitle(), "parent:title") _ = mw.title.new("Moduł:Sprawdź/deprecated/uri").id local link = frame.args["link"] local space = frame.args["spacja"] local check = checkUri(link) if check then return link end return (space and (check ~= nil)) and link or "" end, --[[Sprawdzanie url do szablonów Wykorzystanie: {{#invoke:Sprawdź|url|{{{www|}}}|[{{{www}}} Strona internetowa]}} {{#invoke:Sprawdź|url|{{{www}}}|[{{{www}}} Strona internetowa]}} @param #1 Url do sprawdzenia. Ciąg typu "{{{abc}}}" pominie sprawdzenie, żeby pokazać wartość na stronie szablonu. @param #2 Tekst do wyświetlenia gdy OK. @return pusty string gdy błędny, "ok" lub zawartość #2 gdy OK. ]] ["url"] = function(frame) local link = frame.args[1] local okText = frame.args[2] or "ok" local isValid = string.find(link, '{{{') == 1 or checkUri(link) if isValid then return okText end return "" end, ["lista nazw niepustych argumentów"] = function(frame) local argNames = {} for k, v in pairs(frame:getParent().args) do if #mw.text.trim(v) > 0 then table.insert(argNames, tostring(k)) end end return table.concat(argNames, ", ") end, ["zapis daty dostępu"] = function(frame) local accessDate = frame:getParent().args["data dostępu"] if accessDate and (#accessDate > 0) then if not isDate20YYMMDD(accessDate) then local builder = mw.html.create('span') :addClass('problemy') :wikitext('zły zapis daty dostępu') if mw.title.getCurrentTitle().namespace == 0 then builder:wikitext('[[Kategoria:Szablon cytowania – zły zapis daty dostępu]]') end return builder end end end, }