Moduł:Infobox: Różnice pomiędzy wersjami

Z PUTwiki
Przejdź do nawigacjiPrzejdź do wyszukiwania
wen>Izno
merge hlist here
 
Linia 1: Linia 1:
local p = {}
require("strict")
local args = {}
local resources = mw.loadData("Moduł:Infobox/resources")
local origArgs = {}
 
local root
local function P(frame, qid, pid)
local empty_row_categories = {}
local sd = require("Module:Wikidane/select")
local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]'
return sd.selectProperty(pid, sd.prepareFilters(frame), qid)
local has_rows = false
end
local lists = {
plainlist_t = {
patterns = {
'^plainlist$',
'%splainlist$',
'^plainlist%s',
'%splainlist%s'
},
found = false,
styles = 'Plainlist/styles.css'
},
hlist_t = {
patterns = {
'^hlist$',
'%shlist$',
'^hlist%s',
'%shlist%s'
},
found = false,
styles = 'Hlist/styles.css'
}
}


local function has_list_class(args_to_check)
local function isNullOrWhiteSpace(text)
for _, list in pairs(lists) do
return (text == nil)
if not list.found then
or (#text <= 0)
for _, arg in pairs(args_to_check) do
or string.match(text, "^%s+$")
for _, pattern in ipairs(list.patterns) do
if mw.ustring.find(arg or '', pattern) then
list.found = true
break
end
end
if list.found then break end
end
end
end
end
end


local function fixChildBoxes(sval, tt)
local function addClass(attributes, class)
local function notempty( s ) return s and s:match( '%S' ) end
if not class or (#class == 0) then
return attributes
end
if notempty(sval) then
if not attributes or (#attributes == 0) then
local marker = '<span class=special_infobox_marker>'
return "class=\""..class.."\""
local s = sval
end
-- start moving templatestyles and categories inside of table rows
local slast = ''
local r, c = string.gsub(attributes or "", "%f[%w]class%s*=%s*['\"]", "%0"..class.." ", 1)
while slast ~= s do
if c == 1 then
slast = s
return r
s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])', '%2%1')
s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)', '%2%1')
end
-- end moving templatestyles and categories inside of table rows
s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1')
s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker)
if s:match(marker) then
s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '')
s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1')
s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1')
s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1')
s = mw.ustring.gsub(s, marker .. '(%s*\n|%})', '%1')
end
if s:match(marker) then
local subcells = mw.text.split(s, marker)
s = ''
for k = 1, #subcells do
if k == 1 then
s = s .. subcells[k] .. '</' .. tt .. '></tr>'
elseif k == #subcells then
local rowstyle = ' style="display:none"'
if notempty(subcells[k]) then rowstyle = '' end
s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' ..
subcells[k]
elseif notempty(subcells[k]) then
if (k % 2) == 0 then
s = s .. subcells[k]
else
s = s .. '<tr><' .. tt .. ' colspan=2>\n' ..
subcells[k] .. '</' .. tt .. '></tr>'
end
end
end
end
-- the next two lines add a newline at the end of lists for the PHP parser
-- [[Special:Diff/849054481]]
-- remove when [[:phab:T191516]] is fixed or OBE
s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n')
s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n')
s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1')
s = mw.ustring.gsub(s, '^(%{%|)', '\n%1')
return s
else
return sval
end
end
return "class=\""..class.."\" "..attributes
end
end


-- Cleans empty tables
local function iboxSpan(header, text, row, cell)
local function cleanInfobox()
assert(type(header) == "boolean")
root = tostring(root)
 
if has_rows == false then
local result = {}
root = mw.ustring.gsub(root, '<table[^<>]*>%s*</table>', '')
table.insert(result, "|-")
if row and (#row > 0) then
table.insert(result, " ")
table.insert(result, row)
end
 
table.insert(result, "\n")
table.insert(result, header and "!" or "|")
if cell and (#cell > 0) then
table.insert(result, cell)
table.insert(result,' ')
end
end
table.insert(result, 'colspan="2"|')
table.insert(result, text)
table.insert(result, "\n|-\n")
return table.concat(result)
end
end


-- Returns the union of the values of two tables, as a sequence.
local function emptyCategory(frame, emptyCat)
local function union(t1, t2)
if not emptyCat or (mw.title.getCurrentTitle().namespace ~= 0) then
 
return ""
local vals = {}
for k, v in pairs(t1) do
vals[v] = true
end
end
for k, v in pairs(t2) do
vals[v] = true
if mw.ustring.match(emptyCat, "%[%[[Kk]ategoria:.-%]%]") then
return emptyCat
end
end
local ret = {}
for k, v in pairs(vals) do
local template = frame:getParent():getTitle()
table.insert(ret, k)
local infobox = mw.ustring.match(template, "^Szablon:(.- infobox)$")
end
return mw.ustring.format(resources.catMissingData, infobox or template, emptyCat)
return ret
end
end


-- Returns a table containing the numbers of the arguments that exist
local function InputData(frame, Q, demo, source, sourcepropid)
-- for the specified prefix. For example, if the prefix was 'data', and
local ns = mw.title.getCurrentTitle().namespace
-- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
local add = frame.args["dodaj"]
local function getArgNums(prefix)
local cell = frame.args["pole"]
local nums = {}
local propid = frame.args[sourcepropid or "cecha"]
for k, v in pairs(args) do
local emptyCat = frame.args["kategoria brak"]
local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
local value = frame.args[source or 1]
if num then table.insert(nums, tonumber(num)) end
add = (add == nil) or (#add > 0)
 
if emptyCat and (#emptyCat == 0) then
emptyCat = false
end
end
table.sort(nums)
return nums
end


-- Adds a row to the infobox, with either a header cell
if propid and (#propid == 0) then
-- or a label/data cell combination.
propid = false
local function addRow(rowArgs)
end
if rowArgs.header and rowArgs.header ~= '_BLANK_' then
if isNullOrWhiteSpace(value) then
has_rows = true
value = false
has_list_class({ rowArgs.rowclass, rowArgs.class, args.headerclass })
end
root
local demovalue = false
:tag('tr')
if value then
:addClass(rowArgs.rowclass)
demovalue = mw.ustring.match(value, "^%s*{{{(.-)}}}%s*$")
:cssText(rowArgs.rowstyle)
end
:tag('th')
:attr('colspan', '2')
local wdvalue = false
:addClass('infobox-header')
if add and not demo and (not value or demovalue) and propid then
:addClass(rowArgs.class)
local pid, qid, prop = P(frame, Q, propid)
:addClass(args.headerclass)
if pid and qid and prop then
-- @deprecated next; target .infobox-<name> .infobox-header
value = require("Moduł:Wikidane/format").run(frame, pid, prop)
:cssText(args.headerstyle)
if not value or (#value <= 0) then
:cssText(rowArgs.rowcellstyle)
value = false
:wikitext(fixChildBoxes(rowArgs.header, 'th'))
else
if rowArgs.data then
wdvalue = true
root:wikitext(
end
'[[Category:Pages using infobox templates with ignored data cells]]'
)
end
end
elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
end
has_rows = true
 
has_list_class({ rowArgs.rowclass, rowArgs.class })
if add and not demo and (not value or (demovalue and not wdvalue)) and emptyCat then
cell = addClass(cell, resources.classEmpty)
local row = root:tag('tr')
value = (value or "") .. emptyCategory(frame, emptyCat)
row:addClass(rowArgs.rowclass)
end
row:cssText(rowArgs.rowstyle)
if rowArgs.label then
if not demo and demovalue then
row
cell = addClass(cell, resources.classMissingArg)
:tag('th')
if ns == 0 then
:attr('scope', 'row')
value = value..resources.catMissingArg
:addClass('infobox-label')
-- @deprecated next; target .infobox-<name> .infobox-label
:cssText(args.labelstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(rowArgs.label)
:done()
end
end
local dataCell = row:tag('td')
dataCell
:attr('colspan', not rowArgs.label and '2' or nil)
:addClass(not rowArgs.label and 'infobox-full-data' or 'infobox-data')
:addClass(rowArgs.class)
-- @deprecated next; target .infobox-<name> .infobox(-full)-data
:cssText(rowArgs.datastyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.data, 'td'))
else
table.insert(empty_row_categories, rowArgs.data or '')
end
end
return add and value or false, cell, demovalue, propid
end
end


local function renderTitle()
local function Qdemo(frame)
if not args.title then return end
local Q = frame:getParent().args.Q
 
if Q and string.match(Q, "^%d") then
has_rows = true
Q = "Q"..Q
has_list_class({args.titleclass})
end
root
if Q then
:tag('caption')
-- jest Q to nie demo
:addClass('infobox-title')
return Q, false
:addClass(args.titleclass)
end
-- @deprecated next; target .infobox-<name> .infobox-title
:cssText(args.titlestyle)
:wikitext(args.title)
for k, v in pairs(frame:getParent().args) do
-- nie ma Q lecz dowolny argument to również nie demo
return nil, false
end
-- nie ma Q ani żadnego parametru, jeśli to źródło szablonu, to musi to być demo
return nil, (mw.title.getCurrentTitle().fullText == frame:getParent():getTitle())
end
end


local function renderAboveRow()
local function editWDlink(qid, pid)
if not args.above then return end
return "<span class=\"plainlinks wdlink\" title=\"edytuj dane z infoboxu w Wikidanych\">&#x5B;[https://www.wikidata.org/wiki/"..qid.."#"..pid.." e]&#x5D;</span>"
end


has_rows = true
local function imageWDdemo(pid)
has_list_class({ args.aboveclass })
if pid then
if string.match(pid, "^P%d+$") then
return "[[:d:Property:"..pid.."|"..pid.."]]"
end
root
return "<span class=\"wdimgdemo\">"..pid.."</span>"
:tag('tr')
end
:tag('th')
:attr('colspan', '2')
:addClass('infobox-above')
:addClass(args.aboveclass)
-- @deprecated next; target .infobox-<name> .infobox-above
:cssText(args.abovestyle)
:wikitext(fixChildBoxes(args.above,'th'))
end
end


local function renderBelowRow()
local function propertyLabel(frame, propid, propid2)
if not args.below then return end
local lang = mw.getContentLanguage()
if not propid2 then
local pid, qid, prop = P(frame, propid, "P1629")
if pid and qid and prop then
mw.logObject(prop, "P1629")
local value = require("Moduł:Wikidane/format").run(frame, pid, prop)
if value and (#value > 0) then
value = mw.ustring.gsub(value, "(|)(%l)", function(bar, lcase) return bar..lang:ucfirst(lcase) end)
return lang:ucfirst(value)
end
end
end


has_rows = true
local label1 = mw.wikibase.label(propid)
has_list_class({ args.belowclass })
if not label1 or (#label1 <= 0) then
return false
end
root
if not propid2 then
:tag('tr')
return lang:ucfirst(label1)
:tag('td')
end
:attr('colspan', '2')
:addClass('infobox-below')
local label2 = mw.wikibase.label(propid2)
:addClass(args.belowclass)
if not label2 or (#label2 <= 0) then
-- @deprecated next; target .infobox-<name> .infobox-below
return false
:cssText(args.belowstyle)
end
:wikitext(fixChildBoxes(args.below,'td'))
end
 
local function addSubheaderRow(subheaderArgs)
if subheaderArgs.data and
subheaderArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
has_rows = true
has_list_class({ subheaderArgs.rowclass, subheaderArgs.class })
local row = root:tag('tr')
local cp1 = { mw.ustring.codepoint(label1, 1, mw.ustring.len(label1)) }
row:addClass(subheaderArgs.rowclass)
local cp2 = { mw.ustring.codepoint(label2, 1, mw.ustring.len(label2)) }
 
local len = #cp1 < #cp2 and #cp1 or #cp2
local dataCell = row:tag('td')
-- find common suffix
dataCell
local suffix = false
:attr('colspan', '2')
for i = 1, len do
:addClass('infobox-subheader')
if cp1[#cp1-i+1] ~= cp2[#cp2-i+1] then
:addClass(subheaderArgs.class)
suffix = len - i + 1
:cssText(subheaderArgs.datastyle)
break
:cssText(subheaderArgs.rowcellstyle)
end
:wikitext(fixChildBoxes(subheaderArgs.data, 'td'))
else
table.insert(empty_row_categories, subheaderArgs.data or '')
end
end
end


local function renderSubheaders()
while (suffix < len) and (cp1[#cp1 - suffix + 1] ~= 32) do
if args.subheader then
suffix = suffix + 1
args.subheader1 = args.subheader
end
end
if args.subheaderrowclass then
args.subheaderrowclass1 = args.subheaderrowclass
if suffix < len then
end
label1 = mw.ustring.char(unpack(cp1, 1, #cp1 - suffix))
local subheadernums = getArgNums('subheader')
for k, num in ipairs(subheadernums) do
addSubheaderRow({
data = args['subheader' .. tostring(num)],
-- @deprecated next; target .infobox-<name> .infobox-subheader
datastyle = args.subheaderstyle,
rowcellstyle = args['subheaderstyle' .. tostring(num)],
class = args.subheaderclass,
rowclass = args['subheaderrowclass' .. tostring(num)]
})
end
end
return lang:ucfirst(mw.text.trim(label1).." i "..mw.text.trim(label2))
end
end


local function addImageRow(imageArgs)
local function makeDemoArg(wrap, ...)
local count = select('#', ...)
if count <= 0 then
return
end


if imageArgs.data and
local items = {}
imageArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
local index = 1
 
while index <= count do
has_rows = true
local v = select(index, ...)
has_list_class({ imageArgs.rowclass, imageArgs.class })
if v and (type(v) == "string") then
table.insert(items, v)
end
local row = root:tag('tr')
index = index + 1
row:addClass(imageArgs.rowclass)
end
if #items <= 0 then
return
end


local dataCell = row:tag('td')
local prefix = wrap and "{{{" or ""
dataCell
local suffix = wrap and "}}}" or ""
:attr('colspan', '2')
return prefix..table.concat(items,"&#x7C;")..suffix
:addClass('infobox-image')
:addClass(imageArgs.class)
:cssText(imageArgs.datastyle)
:wikitext(fixChildBoxes(imageArgs.data, 'td'))
else
table.insert(empty_row_categories, imageArgs.data or '')
end
end
end


local function renderImages()
local function SecondaryInfobox(templateTitle, message)
if args.image then
local contents = mw.title.getCurrentTitle():getContent()
args.image1 = args.image
local infoboxPattern = "{{ *(%f[%a][%a ]-%f[ ] infobox)%s*|"
end
local start = 1
if args.caption then
while true do
args.caption1 = args.caption
mw.logObject(start, "Kolejny:start")
end
local s, e, n = mw.ustring.find(contents, infoboxPattern, start, false)
local imagenums = getArgNums('image')
if not s then
for k, num in ipairs(imagenums) do
break
local caption = args['caption' .. tostring(num)]
end
local data = mw.html.create():wikitext(args['image' .. tostring(num)])
if caption then
mw.logObject({s, e, n}, "Kolejny:find{s e n}")
data
local prefix = mw.ustring.match(n, "^(%a-):")
:tag('div')
mw.logObject(prefix, "Kolejny:prefix")
:addClass('infobox-caption')
local ns = 10
-- @deprecated next; target .infobox-<name> .infobox-caption
if prefix then
:cssText(args.captionstyle)
prefix = mw.getCurrentLang():ucfirst(prefix)
:wikitext(caption)
ns = mw.site.namespaces[prefix] or ns
end
mw.logObject(ns, "Kolejny:ns")
local infoboxTitle = mw.title.new(n, ns)
mw.logObject(infoboxTitle, "Kolejny:infoboxTitle")
if templateTitle == infoboxTitle then
mw.logObject(start == 1 and "" or message, "Kolejny:return")
return start == 1 and "" or message
end
end
addImageRow({
data = tostring(data),
start = e
-- @deprecated next; target .infobox-<name> .infobox-image
datastyle = args.imagestyle,
class = args.imageclass,
rowclass = args['imagerowclass' .. tostring(num)]
})
end
end
mw.log("Kolejny: BRAK")
return mw.title.getCurrentTitle().namespace == 0
and "?" -- tego przypadku nie powinno być w przestrzeni głównej
or false -- a poza nią to nie ma takiego znaczenia
end
end


-- When autoheaders are turned on, preprocesses the rows
return {
local function preprocessRows()
["Q"] = function(frame)
if not args.autoheaders then return end
local Q, demo = Qdemo(frame)
return demo and "demo" or Q
end,
local rownums = union(getArgNums('header'), getArgNums('data'))
["Demo"] = function(frame)
table.sort(rownums)
local args = require('Module:Arguments').getArgs(frame, { trim = false, removeBlanks = false })
local lastheader
local result = {}
for k, num in ipairs(rownums) do
local i = 1
if args['header' .. tostring(num)] then
local wd = false
if lastheader then
while true do
args['header' .. tostring(lastheader)] = nil
local v = args[i]
i = i + 1
if not v then
break
end
end
lastheader = num
elseif args['data' .. tostring(num)] and
if #v == 0 then
args['data' .. tostring(num)]:gsub(
if wd then
category_in_empty_row_pattern, ''
table.insert(result, "")
):match('^%S') then
end
local data = args['data' .. tostring(num)]
if data:gsub(category_in_empty_row_pattern, ''):match('%S') then
wd = true
lastheader = nil
else
table.insert(result, wd and imageWDdemo(v) or v)
wd = false
end
end
end
end
end
if lastheader then
if #result then
args['header' .. tostring(lastheader)] = nil
local result = "{{{"..table.concat(result,"&#x7C;").."}}}"
end
mw.logObject(result, "result")
end
return result
end
end,
["Kolejny"] = function(frame)
local message = frame.args[1]
if not message or (#mw.text.trim(message) == 0) then
message = "tak"
end
local templateTitle = mw.title.new(frame:getParent():getTitle())
return SecondaryInfobox(templateTitle, message)
end,


-- Gets the union of the header and data argument numbers,
["Test"] = function(frame)
-- and renders them all in order
local Q, demo = Qdemo(frame)
local function renderRows()
if demo then
return "demo"
end
local i = 1
local sd = require("Module:Wikidane/select")
while true do
local pid = frame.args[i]
if not pid then
return
end
local pid, qid, prop = sd.selectProperty(pid, {}, Q)
if qid then
return pid
end
i = i + 1
end
end,


local rownums = union(getArgNums('header'), getArgNums('data'))
["Tytuł"] = function(frame)
table.sort(rownums)
local Q, demo = Qdemo(frame)
for k, num in ipairs(rownums) do
local emptyCat = frame.args["kategoria brak"]
addRow({
local attrs = frame.args["pole"]
header = args['header' .. tostring(num)],
local props = frame.args["cecha"] or resources.defaultTitle2Property
label = args['label' .. tostring(num)],
local text1 = frame.args[1]
data = args['data' .. tostring(num)],
local text2 = frame.args[2]
datastyle = args.datastyle,
local text3 = frame.args[3]
class = args['class' .. tostring(num)],
rowclass = args['rowclass' .. tostring(num)],
if isNullOrWhiteSpace(text1) then
-- @deprecated next; target .infobox-<name> rowclass
text1 = false
rowstyle = args['rowstyle' .. tostring(num)],
end
rowcellstyle = args['rowcellstyle' .. tostring(num)]
if isNullOrWhiteSpace(text2) then
})
text2 = false
end
end
end
if isNullOrWhiteSpace(text3) then
text3 = false
end


local function renderNavBar()
local demo1 = false
if not args.name then return end
if text1 then
demo1 = mw.ustring.match(text1, "^{{{(.-)}}}$")
end
local demo2 = false
if text2 then
demo2 = mw.ustring.match(text2, "^{{{(.-)}}}$")
end
local demo3 = false
if text3 then
demo3 = mw.ustring.match(text3, "^{{{(.-)}}}$")
end


has_rows = true
local Q, demo = Qdemo(frame)
root
:tag('tr')
:tag('td')
:attr('colspan', '2')
:addClass('infobox-navbar')
:wikitext(require('Module:Navbar')._navbar{
args.name,
mini = 1,
})
end


local function renderItalicTitle()
local builder = mw.html.create()
local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title'])
builder:wikitext("|+")
if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then
if attrs and (#attrs > 0) then
root:wikitext(require('Module:Italic title')._main({}))
builder:wikitext(" ", attrs, " | ")
end
end
end


-- Categories in otherwise empty rows are collected in empty_row_categories.
local titleWithText = false
-- This function adds them to the module output. It is not affected by
local function appendPart(class)
-- args.decat because this module should not prevent module-external categories
if titleWithText then
-- from rendering.
builder:tag("br")
local function renderEmptyRowCategories()
end
for _, s in ipairs(empty_row_categories) do
root:wikitext(s)
titleWithText = true
end
return builder:tag("span"):addClass(class)
end
end
local label = false
if demo and demo1 then
appendPart(resources.classTitle1):wikitext("{{{", demo1, "&#x7C;", imageWDdemo("Etykieta"), "}}}")
elseif demo then
appendPart(resources.classTitle1):wikitext(imageWDdemo("Etykieta"))
elseif text1 and (#text1 > 0) then
appendPart(resources.classTitle1):wikitext(text1)
else
label = mw.wikibase.label(Q)
if label then
appendPart(resources.classTitle1):wikitext(label)
end
end
local props1 = {}
local props2 = {}
for propid in string.gmatch(props, "%S+") do
table.insert(props1, propid)
table.insert(props2, "&#x7C;")
table.insert(props2, imageWDdemo(propid))
end
props2 = table.concat(props2, "")
mw.text.split(props, "%s")
if demo and demo2 then
appendPart(resources.classTitle2):wikitext("{{{", demo2, props2, "}}}")
elseif demo and (#props1 > 0) then
appendPart(resources.classTitle2):wikitext("{{{", props2, "}}}")
elseif text2 and (#text2 > 0) then
appendPart(resources.classTitle2):wikitext(text2)
elseif #props1 > 0 then
local pid, qid, prop
for _, propid in ipairs(props1) do
pid, qid, prop = P(frame, Q, propid)
if qid and prop then
local text2 = require("Moduł:Wikidane/format").run(frame, pid, prop)
if text2 then
local lang = mw.getContentLanguage()
local l = label and lang:caseFold(label) or label
local t1 = text1 and lang:caseFold(text1) or text1
local t2, _ = mw.ustring.gsub(text2, "</?[A-Za-z]+ ?[^<>]*/?>", "") -- remove HTML tags
t2 = lang:caseFold(t2)
if (t2 ~= t1) and (t2 ~= l) then
appendPart(resources.classTitle2):wikitext(text2)
break
end
end
end
end
end
if text3 and (#text3 > 0) then
appendPart(resources.classTitle3):wikitext(text3)
end
if not titleWithText then
-- use page title
local title = mw.title.getCurrentTitle()
local text = title.text
local nodisambig = mw.ustring.match(text, "^(.-)%s+%([^%(%)]+%)$")
if nodisambig and (#nodisambig > 0) then
text = nodisambig
end
appendPart(resources.classEmpty):wikitext(text, emptyCategory(frame, emptyCat))
end
if not titleWithText then
-- no text
return
end
builder:wikitext("\n")
return builder:allDone()
end,


-- Render tracking categories. args.decat == turns off tracking categories.
["Grafika"] = function(frame)
local function renderTrackingCategories()
local add = frame.args["dodaj"]
if args.decat == 'yes' then return end
add = (add == nil) or (#add > 0)
if args.child == 'yes' then
if not add then
if args.title then
return
root:wikitext(
'[[Category:Pages using embedded infobox templates with the title parameter]]'
)
end
end
elseif #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
root:wikitext('[[Category:Articles using infobox templates with no data rows]]')
local function formatFile(file, alt, format, description)
end
end
local function removeLinks(text)
--mw.logObject(text, "RemoveLinks:input")
if text then
text = mw.ustring.gsub(text, "%s+", " ") -- compact white characters into one space
text = mw.ustring.gsub(text, "%[https?://[^%[%]%s|]+%]", "") -- remove LZ
text = mw.ustring.gsub(text, "%[https?://[^%[%]%s|]+ ([^%[%]|]+)%]", "%1") -- remove LZ, leave description
text = mw.ustring.gsub(text, "%[%[[^%[%]|]+|([^%[%]|]*)%]%]", "%1" ) -- remove wikilinks, leave description
text = mw.ustring.gsub(text, "%[%[([^%[%]|]*)%]%]", "%1" ) -- remove wikilinks, leave description
text = mw.ustring.gsub(text, "%s+", " ") -- compact white characters into one space again
text = mw.text.nowiki(text)
end
--mw.logObject(text, "RemoveLinks:output")
return text
end


--[=[
local result = {}
Loads the templatestyles for the infobox.
table.insert(result, "[[Plik:")
table.insert(result, file)
if format and (#format > 0) then
table.insert(result, "|")
table.insert(result, format)
if mw.ustring.match(format, "^%s*alt%s*=") or mw.ustring.match(format, "|%s*alt%s*=") then
alt = false
end
end
if alt and (#alt > 0) then
table.insert(result, "|alt=")
table.insert(result, removeLinks(alt))
end
if description and (#description > 0) then
table.insert(result, "|")
table.insert(result, removeLinks(description))
end
table.insert(result,"]]")
return table.concat(result)
end
local function checkIfFileExists(file)
local pattern, _ = mw.ustring.gsub( file, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
pattern, _ = mw.ustring.gsub(pattern, "[ _]", "[ _]")
pattern = "%[%[%s*(%a+)%s*:"..pattern.."%s*[%]|]"
--mw.logObject(pattern, "Grafika:checkIfFileExists PATTERN")
local contents = mw.title.getCurrentTitle():getContent()
local start = 1
while true do
--mw.logObject(start, "Grafika:checkIfFileExists NEXT")
local s, e, n = mw.ustring.find(contents, pattern, start, false)
if not s then
--mw.logObject(file, "Grafika:checkIfFileExists FALSE")
return false
end
--mw.logObject({n,file}, "Grafika:checkIfFileExists{n,file}")
local title = mw.title.new(file, n)
if title and (title.namespace == 6) then
--mw.logObject(file, "Grafika:checkIfFileExists TRUE")
return true
end
start = e
end
end
local Q, demo = Qdemo(frame)
local row = frame.args["wiersz"]
local cell = frame.args["pole"]
local format = frame.args["format"]
local imageTitle = false
local secondary = false
local callingTemplate = frame:getParent():getTitle()
if mw.title.new(callingTemplate) == mw.title.new("Szablon:Infobox grafika") then
imageTitle = frame:getParent().args["tytuł grafiki"]
secondary = frame:getParent().args["kolejny"]
else
imageTitle = frame.args["tytuł grafiki"]
if (#callingTemplate > 8) and (mw.ustring.sub(callingTemplate, -8) == " infobox") then
secondary = SecondaryInfobox(callingTemplate, callingTemplate)
end
end


TODO: FINISH loading base templatestyles here rather than in
if format and (#format <= 0) then
MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables.
format = nil
See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :).
end
When we do this we should clean up the inline CSS below too.
Will have to do some bizarre conversion category like with sidebar.
mw.logObject(secondary,"secondary")
local wdExists = false
local function loadPicture(file, description, fileProperty, descProperty, defaultFormat)
if file == "nie" then
return
end
if isNullOrWhiteSpace(file) then
file = false
description = false
elseif isNullOrWhiteSpace(description) then
description = false
end
if isNullOrWhiteSpace(fileProperty) then
fileProperty = false
descProperty = false
elseif isNullOrWhiteSpace(descProperty) then
descProperty = false
end
local alt = false
local desc = nil
local patched = false
if fileProperty then
alt = mw.wikibase.label(fileProperty)
end
local demoFile = false
local demoDescription = false
if file then
demoFile = mw.ustring.match(file, "^{{{(.-)}}}$")
if not demoFile then
file = mw.ustring.gsub(file, "%s*[Pp]lik%s*:%s*", "Plik:")
file = mw.ustring.gsub(file, "%s*[Ff]ile%s*:%s*", "Plik:")
file = mw.ustring.gsub(file, "%s*[Gg]rafika%s*:%s*", "Plik:")
file = mw.ustring.gsub(file, "%s*[Ii]mage%s*:%s*", "Plik:")
if mw.ustring.match(file, "^Plik:(.*)") then
    file = mw.ustring.match(file, "^Plik:(.*)")
    patched = true
elseif mw.ustring.match(file, "%[%[Plik:([^%[%]|]+)[|%]]") then
    file = mw.ustring.match(file, "%[%[Plik:([^%[%]|]+)[|%]]")
    patched = true
end
end
end
if description then
demoDescription = mw.ustring.match(description, "^{{{(.-)}}}$")
end
if not demo and (not file or demoFile) and fileProperty then
if secondary and (#secondary > 0) then
mw.logObject(secondary, "Grafika: nie ładuję obrazka z Wikidanych na drugim lub kolejnym infoboksie")
return
end
local pid, qid, prop = P(frame, Q, fileProperty)
if pid and qid and prop then
for _, v in ipairs(prop) do
if v.mainsnak and (v.mainsnak.snaktype == "value") and (v.mainsnak.datatype == "commonsMedia") and v.mainsnak.datavalue and (v.mainsnak.datavalue.type == "string") then
local commonMedia = v.mainsnak.datavalue.value
if not isNullOrWhiteSpace(commonMedia) then
if checkIfFileExists(commonMedia) then
mw.logObject(commonMedia, "Grafika: obrazek, który jest oferowany w Wikidanych, już jest umieszczony w kodzie strony")
wdExists = true
return
end
file = commonMedia
alt = mw.wikibase.label(v.mainsnak.property)
desc = require("Moduł:Wikidane/format/qualifiers").TEXT1(v, nil, "P2096")
break
end
end
end
end
if file and descProperty then
pid, qid, prop = P(frame, Q, descProperty)
if pid and qid and prop then
local v = require("Moduł:Wikidane/format").run(frame, pid, prop)
if not isNullOrWhiteSpace(v) then
description = v
end
end
end
end
if not demo and file then
return {
formatFile(file, alt, format or defaultFormat, desc or description)..(patched and resources.catPatchedFile or ""),
description or desc
}
end
if demo and (demoFile or fileProperty) then
return {
formatFile(makeDemoArg(true, demoFile, imageWDdemo(fileProperty)), alt, format or defaultFormat, false),
makeDemoArg(true, demoDescription, imageWDdemo(descProperty))
}
end
end


]=]
local args = {
local function loadTemplateStyles()
file = "grafika", description = "opis grafiki", fileProperty = "cecha", descProperty = "cecha opisu", defaultFormat = "250x250px",
local frame = mw.getCurrentFrame()
fileN = "%d. grafika", descriptionN = "%d. opis grafiki", filePropertyN = "%d. cecha", descPropertyN = "%d. cecha opisu", defaultFormatN = "100x100px",
}
local bigImage = loadPicture(frame.args[args.file], frame.args[args.description], frame.args[args.fileProperty], frame.args[args.descProperty], args.defaultFormat)
mw.logObject(bigImage, "bigImage")
local smallImages = {}
local index = 1
while true do
local file = frame.args[mw.ustring.format(args.fileN, index)]
local description = frame.args[mw.ustring.format(args.descriptionN, index)]
local fileProperty = frame.args[mw.ustring.format(args.filePropertyN, index)]
local descProperty = frame.args[mw.ustring.format(args.descPropertyN, index)]
if not file and not fileProperty then
break
end
index = index + 1
local image = loadPicture(file, description, fileProperty, descProperty, args.defaultFormatN)
if image then
table.insert(smallImages, image)
end
end
local result = {}
if wdExists and secondary and (#secondary == 0) and (mw.title.getCurrentTitle().namespace == 0) then
table.insert(result, '|- style="display:none"\n| colspan="2" |"')
table.insert(result, resources.catIgnoreImage)
table.insert(result, '\n')
end
if bigImage then
if imageTitle and (#imageTitle > 0) then
table.insert(bigImage, 1, '<span style="font-weight: bold>'..imageTitle..'</span>')
end
table.insert(result, iboxSpan(false, table.concat(bigImage, "<br />"), row, cell))
end
if #smallImages > 0 then
local index = 1
table.insert(result, '|-')
table.insert(result, row)
table.insert(result, '\n|colspan="2" padding="0" ')
table.insert(result, cell)
table.insert(result, '|\n{| class="ibox2"\n')
-- display images in pairs
while (index + 1) <= #smallImages do
local image1 = smallImages[index + 0]
local image2 = smallImages[index + 1]
-- both files must exists
table.insert(result, '|-\n|')
table.insert(result, image1[1])
table.insert(result, '\n|')
table.insert(result, image2[1])
table.insert(result, '\n')
-- descriptions are optional
if image1[2] or image2[2] then
table.insert(result, '|-\n|')
table.insert(result, image1[2] or "")
table.insert(result, '\n|')
table.insert(result, image2[2] or "")
table.insert(result, '\n')
end
-- next pair
index = index + 2
end
-- display last odd image
if index == #smallImages then
local image = smallImages[index]
table.insert(result, '|-\n|colspan=2|')
table.insert(result, image[1])
table.insert(result, '\n')
if image[2] then
table.insert(result, '|-\n|colspan=2|')
table.insert(result, image[2])
table.insert(result, '\n')
end
end
table.insert(result, '|-\n|}\n|-\n')
end
if (#result > 0) and frame.args["dodaj zamykający wiersz"] then
-- łatka na wywołanie w szablonie wewnątrz #if:,
-- który obcina odstępy, w tym znak nowej linii
-- a domyślnie wynik kończy się tym znakiem
table.insert(result, '|-\n')
end
if #result > 0 then
return table.concat(result)
end
end,
local hlist_templatestyles = ''
["Grupa"] = function(frame)
if lists.hlist_t.found then
local Q, demo = Qdemo(frame)
hlist_templatestyles = frame:extensionTag{
local emptyCat = frame.args["kategoria brak"]
name = 'templatestyles', args = { src = lists.hlist_t.styles }
local header = frame.args["nagłówek"]
}
local headerRow = frame.args["wiersz nagłówka"]
end
local headerCell = frame.args["pole nagłówka"]
local lineClass = frame.args["klasa kreski"]
local result = {}
local append = function(text)
if (#result == 0) and header then
local cell = headerCell
if #header == 0 then
cell = addClass(headerCell, resources.classEmpty)
header = emptyCategory(frame, emptyCat)
elseif not demo and mw.ustring.match(header, "^{{{(.-)}}}$") then
cell = addClass(headerCell, resources.classMissingArg)
end
table.insert(result, iboxSpan(true, header, headerRow, cell))
end
table.insert(result, text)
end
local total = false
local sep = false
local i = 1
while true do
local arg = frame.args[i]
if not arg then
break
end
i = i + 1
arg = string.match(arg, "^(.-)%s*$") -- trim remaing space
if arg == "-" then
sep = true
elseif #arg > 0 then -- real content
local next = false
for line in mw.text.gsplit(arg, "\n%f[|!]", false) do
if next then
append("\n")
end
next = true
if sep and (#line >= 2) and (string.byte(line, 1) == 124) and (string.byte(line, 2) == 45) then
-- row with separator line
local class = string.match(line, 'class="(.-)"')
local newClass = resources.classSeparator
if lineClass and (#lineClass > 0) then
newClass = newClass.." "..lineClass
end
if class then
line = string.gsub(line, 'class="', 'class="'..newClass.." ", 1)
else
line = mw.text.trim(line)..' class="'..newClass..'"'
end
else
-- content or row without separator line
sep = false
end
append(line)
end
end
end
local plainlist_templatestyles = ''
return table.concat(result)
if lists.plainlist_t.found then
end,
plainlist_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = lists.plainlist_t.styles }
}
end
-- See function description
["Blok"] = function(frame)
local base_templatestyles = frame:extensionTag{
local Q, demo = Qdemo(frame)
name = 'templatestyles', args = { src = 'Module:Infobox/styles.css' }
local headerRow = frame.args["wiersz nagłówka"]
}
local headerCell = frame.args["pole nagłówka"]
local row = frame.args["wiersz"]
local label = frame.args["nagłówek"]
local value, cell, demovalue, propid = InputData(frame, Q, demo)
 
if label == "-" then
label = false
row = addClass(row, resources.classSeparator)
elseif label and (#label == 0) then
label = false
elseif not label and propid then
label = propertyLabel(frame, propid)
end
local demolabel = false
if label then
demolabel = mw.ustring.match(label, "^{{{(.-)}}}$")
end
local text = false
if demo and demovalue and propid then
text = "{{{"..demovalue.."&#x7C;"..imageWDdemo(propid).."}}}"
elseif demo and propid then
text = "{{{"..imageWDdemo(propid).."}}}"
elseif demo and demolabel then
text = "{{{"..demovalue.."}}}"
elseif value then
text = value
end
if not text then
return
end
local header
if label == false then
header = false
elseif label and (#label > 0) then
header = label
elseif demo and demolabel and propid then
header = "{{{"..demolabel.."&#x7C;"..imageWDdemo("label").."}}}"
elseif demo and propid then
header = "{{{"..imageWDdemo("label").."}}}"
elseif demo and demolabel then
header = "{{{"..demolabel.."}}}"
elseif propid then
header = "{{{nagłówek}}}"..resources.catMissingLabel
elseif demo then
header = "{{{nagłówek}}}"
end
local result = {}
if header then
table.insert(result, iboxSpan(true, header, headerRow, headerCell))
end
table.insert(result, iboxSpan(false, text, row, cell))
return table.concat(result)
end,


local templatestyles = ''
["Wiersz"] = function(frame)
if args['templatestyles'] then
local Q, demo = Qdemo(frame)
templatestyles = frame:extensionTag{
local row = frame.args["wiersz"]
name = 'templatestyles', args = { src = args['templatestyles'] }
local label = frame.args["etykieta"]
}
local value, cell, demovalue, propid = InputData(frame, Q, demo)
end
local child_templatestyles = ''
if args['child templatestyles'] then
child_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = args['child templatestyles'] }
}
end
local grandchild_templatestyles = ''
if args['grandchild templatestyles'] then
grandchild_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = args['grandchild templatestyles'] }
}
end
return table.concat({
-- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering.
-- this ordering is not a guarantee because the rows of interest invoking
-- each class may not be on a specific page
hlist_templatestyles,
plainlist_templatestyles,
base_templatestyles,
templatestyles,
child_templatestyles,
grandchild_templatestyles
})
end


-- common functions between the child and non child cases
if label and (#label == 0) then
local function structure_infobox_common()
label = false
renderSubheaders()
end
renderImages()
preprocessRows()
if not label and propid then
renderRows()
label = propertyLabel(frame, propid)
renderBelowRow()
end
renderNavBar()
renderItalicTitle()
local demolabel = false
renderEmptyRowCategories()
if label then
renderTrackingCategories()
demolabel = mw.ustring.match(label, "^{{{(.-)}}}$")
cleanInfobox()
end
end
local builder = mw.html.create()
builder:wikitext("|-")
if row and (#row > 0) then
builder:wikitext(" ", row, " | ")
end


-- Specify the overall layout of the infobox, with special settings if the
builder:wikitext("\n! ")
-- infobox is used as a 'child' inside another infobox.
local function _infobox()
if label and (#label > 0) then
if args.child ~= 'yes' then
builder:wikitext(label)
root = mw.html.create('table')
elseif demo and demolabel and propid then
builder:wikitext("{{{", demolabel, "&#x7C;", imageWDdemo("label"), "}}}")
elseif demo and propid then
builder:wikitext("{{{", imageWDdemo("label"), "}}}")
elseif demo and demolabel then
builder:wikitext("{{{", demolabel, "}}}")
elseif propid then
builder:wikitext("{{{etykieta}}}", resources.catMissingLabel)
else
builder:wikitext("{{{etykieta}}}")
end
builder:wikitext("\n| ")
if cell and (#cell > 0) then
builder:wikitext(cell)
builder:wikitext("| ")
end
if demo and demovalue and propid then
builder:wikitext("{{{", demovalue, "&#x7C;", imageWDdemo(propid), "}}}")
elseif demo and propid then
builder:wikitext("{{{", imageWDdemo(propid), "}}}")
elseif demo and demovalue then
builder:wikitext("{{{", demovalue, "}}}")
elseif value then
builder:wikitext(value)
else
return
end
builder:wikitext("\n|-")
return builder:allDone()
end,
["Wiersz2"] = function(frame)
local Q, demo = Qdemo(frame)
local row = frame.args["wiersz"]
local label = frame.args["etykieta"]
local label1 = frame.args["etykieta 1"]
local label2 = frame.args["etykieta 2"]
local value1, cell, demovalue1, propid1 = InputData(frame, Q, demo, 1, "cecha 1")
local value2, _, demovalue2, propid2 = InputData(frame, Q, demo, 2, "cecha 2")


root
if label and (#label == 0) then
:addClass(args.subbox == 'yes' and 'infobox-subbox' or 'infobox')
label = false
:addClass(args.bodyclass)
end
-- @deprecated next; target .infobox-<name>
:cssText(args.bodystyle)
has_list_class({ args.bodyclass })
if not label and propid1 and propid2 then
label = propertyLabel(frame, propid1, propid2)
end


renderTitle()
if label1 and (#label1 == 0) then
renderAboveRow()
label1 = false
else
end
root = mw.html.create()
if not label1 and propid1 then
label1 = propertyLabel(frame, propid1)
end


root
if label2 and (#label2 == 0) then
:wikitext(args.title)
label2 = false
end
end
structure_infobox_common()
if not label2 and propid2 then
return loadTemplateStyles() .. root
label2 = propertyLabel(frame, propid2)
end
end


-- If the argument exists and isn't blank, add it to the argument table.
local demolabel1 = false
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
if label1 then
local function preprocessSingleArg(argName)
demolabel1 = mw.ustring.match(label1, "^{{{(.-)}}}$")
if origArgs[argName] and origArgs[argName] ~= '' then
end
args[argName] = origArgs[argName]
end
local demolabel2 = false
end
if label2 then
demolabel2 = mw.ustring.match(label2, "^{{{(.-)}}}$")
end
local builder = mw.html.create()
builder:wikitext("|-")
if row and (#row > 0) then
builder:wikitext(" ", row, " | ")
end


-- Assign the parameters with the given prefixes to the args table, in order, in
builder:wikitext("\n! ")
-- batches of the step size specified. This is to prevent references etc. from
-- appearing in the wrong order. The prefixTable should be an array containing
if demo then
-- tables, each of which has two possible fields, a "prefix" string and a
if label and (#label > 0) then
-- "depend" table. The function always parses parameters containing the "prefix"
builder:wikitext(label)
-- string, but only parses parameters in the "depend" table if the prefix
else
-- parameter is present and non-blank.
if label1 and (#label1 > 0) then
local function preprocessArgs(prefixTable, step)
builder:wikitext(label1)
if type(prefixTable) ~= 'table' then
elseif demolabel1 and propid1 then
error("Non-table value detected for the prefix table", 2)
builder:wikitext("{{{", demolabel1, "&#x7C;", imageWDdemo("label1"), "}}}")
end
elseif propid1 then
if type(step) ~= 'number' then
builder:wikitext("{{{", imageWDdemo("label1"), "}}}")
error("Invalid step value detected", 2)
elseif demolabel1 then
end
builder:wikitext("{{{", demolabel1, "}}}")
elseif propid1 then
builder:wikitext("{{{etykieta 1}}}", resources.catMissingLabel)
else
builder:wikitext("{{{etykieta 1}}}")
end
builder:wikitext(" i ")
if label2 and (#label2 > 0) then
builder:wikitext(label2)
elseif demolabel2 and propid2 then
builder:wikitext("{{{", demolabel2, "&#x7C;", imageWDdemo("label2"), "}}}")
elseif propid2 then
builder:wikitext("{{{", imageWDdemo("label2"), "}}}")
elseif demolabel2 then
builder:wikitext("{{{", demolabel2, "}}}")
elseif propid2 then
builder:wikitext("{{{etykieta 2}}}", resources.catMissingLabel)
else
builder:wikitext("{{{etykieta 2}}}")
end
end
elseif value1 and value2 and label then
builder:wikitext(label)
elseif value1 and value2 and label1 and label2 then
builder:wikitext(label1, " i ", label2)
elseif value1 and value2 then
builder:wikitext("{{{etykieta}}}", resources.catMissingLabel)
elseif value1 and label1 then
builder:wikitext(label1)
elseif value1 then
builder:wikitext("{{{etykieta 1}}}", resources.catMissingLabel)
elseif value2 and label2 then
builder:wikitext(label2)
elseif value2 then
builder:wikitext("{{{etykieta 2}}}", resources.catMissingLabel)
else
return
end


-- Get arguments without a number suffix, and check for bad input.
builder:wikitext("\n| ")
for i,v in ipairs(prefixTable) do
if cell and (#cell > 0) then
if type(v) ~= 'table' or type(v.prefix) ~= "string" or
builder:wikitext(cell)
(v.depend and type(v.depend) ~= 'table') then
builder:wikitext("| ")
error('Invalid input detected to preprocessArgs prefix table', 2)
end
local br = true
if demo and demovalue1 and propid1 then
builder:wikitext("{{{", demovalue1, "&#x7C;", imageWDdemo(propid1), "}}}")
elseif demo and propid1 then
builder:wikitext("{{{", imageWDdemo(propid1), "}}}")
elseif demo and demovalue1 then
builder:wikitext("{{{", demovalue1, "}}}")
elseif value1 then
builder:wikitext(value1)
else
br = false
end
if demo and demovalue2 and propid2 then
if br then builder:tag("br") end
builder:wikitext("{{{", demovalue2, "&#x7C;", imageWDdemo(propid2), "}}}")
elseif demo and propid2 then
if br then builder:tag("br") end
builder:wikitext("{{{", imageWDdemo(propid2), "}}}")
elseif demo and demovalue2 then
if br then builder:tag("br") end
builder:wikitext("{{{", demovalue2, "}}}")
elseif value2 then
if br then builder:tag("br") end
builder:wikitext(value2)
end
end
preprocessSingleArg(v.prefix)
-- Only parse the depend parameter if the prefix parameter is present
builder:wikitext("\n|-")
-- and not blank.
return builder:allDone()
if args[v.prefix] and v.depend then
end,
for j, dependValue in ipairs(v.depend) do
if type(dependValue) ~= 'string' then
["Fragment"] = function(frame)
error('Invalid "depend" parameter value detected in preprocessArgs')
local Q, demo = Qdemo(frame)
local value, unused, demovalue, propid = InputData(frame, Q, demo)
local text = false
if demo and demovalue and propid then
text = "{{{"..demovalue.."&#x7C;"..imageWDdemo(propid).."}}}"
elseif demo and propid then
text = "{{{"..imageWDdemo(propid).."}}}"
elseif demo and demolabel then
text =  "{{{"..demovalue.."}}}"
elseif value then
return value
end
return text and '|-\n|colspan="2"| '..text.."\n" or ""
end,
["Drzewo"] = function(frame)
local Q, demo = Qdemo(frame)
local headerRow = frame.args["wiersz nagłówka"]
local headerCell = frame.args["pole nagłówka"]
local header = frame.args["nagłówek"]
local row = frame.args["wiersz"] or 'class="tree"'
local cell = frame.args["pole"]
local text = false
if demo then
text = imageWDdemo("'''Skrypt Lua'''")
else
if not Q then
local entity = mw.wikibase.getEntity()
if not entity then
return
end
end
preprocessSingleArg(dependValue)
Q = entity.id
end
end
text = require("Module:Wikidane/Tree").classTree(frame, Q)
end
end
end
if not text then
return
end
if header == "-" then
header = false
row = addClass(row, resources.classSeparator)
elseif header and (#header == 0) then
label = false
end
local result = {}
if header then
table.insert(result, iboxSpan(true, header, headerRow, headerCell))
end
table.insert(result, iboxSpan(false, text, row, cell))
return table.concat(result, "")
end,


-- Get arguments with number suffixes.
["Projekt"] = function(frame)
local a = 1 -- Counter variable.
local Q, demo = Qdemo(frame)
local moreArgumentsExist = true
local entity = mw.wikibase.getEntity(Q)
while moreArgumentsExist == true do
local standardLink = function(sitelink)
moreArgumentsExist = false
return entity and entity.sitelinks and entity.sitelinks[sitelink] and entity.sitelinks[sitelink].title
for i = a, a + step - 1 do
end
for j,v in ipairs(prefixTable) do
local standardProp = function(pid)
local prefixArgName = v.prefix .. tostring(i)
local pid, qid, prop = require("Module:Wikidane/select").selectProperty(pid, {}, Q)
if origArgs[prefixArgName] then
if prop and prop[1] then
-- Do another loop if any arguments are found, even blank ones.
local snak = prop[1].mainsnak
moreArgumentsExist = true
if (snak.snaktype == "value") and (snak.datatype == "string") then
preprocessSingleArg(prefixArgName)
return snak.datavalue.value
end
end
-- Process the depend table if the prefix argument is present
end
-- and not blank, or we are processing "prefix1" and "prefix" is
end
-- present and not blank, and if the depend table is present.
local demoProp = function(sitelink, arg)
if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
local demovalue = false
for j,dependValue in ipairs(v.depend) do
if arg then
local dependArgName = dependValue .. tostring(i)
demovalue = mw.ustring.match(arg, "^{{{(.-)}}}$")
preprocessSingleArg(dependArgName)
end
local result = {}
if demovalue then
table.insert(result, "&#8203;") -- wrap here
table.insert(result, "{{{")
table.insert(result, demovalue)
table.insert(result, "&#x7C;&#8203;")
table.insert(result, imageWDdemo(sitelink))
table.insert(result, "}}}&#8203;")
else
table.insert(result, "&#8203;")
table.insert(result, imageWDdemo(sitelink))
table.insert(result, "&#8203;")
end
return table.concat(result)
end
local projects = {
{
arg = "wikipedia",
icon = "wikipedia",
text = function()
if demo then
return "Wikipedia w języku [[:d:Property:P424|P424]]"
end
local wikilang = arg or standardProp("P424")
if wikilang == "pl" then
return "Wikipedia w [[Wikipedia:Strona główna|języku polskim]]"
end
if wikilang then
return mw.ustring.format("Wikipedia w [[:%s:|języku %s]]", wikilang, mw.loadData("Module:Lang/data")[wikilang].miejscownik)
end
end
end,
},
{
arg = "c",
icon = "commons",
text = function(arg)
local link = false
if demo then
link = demoProp("commonswiki", arg)
elseif arg then
link = arg
else
link = standardLink("commonswiki")
if not link then
local cat = standardProp("P373")
if cat then
link = "Category:"..cat
else
--or standardProp("P910") -- main category article
end
end
end
if link then
return mw.ustring.format("[[commons:%s|Multimedia w Wikimedia Commons]]", link)
end
end,
},
{
arg = "n",
icon = "wikinews",
text = function(arg)
local link = demo and demoProp("plwikinews", arg) or (arg or standardLink("plwikinews"))
if link then
return mw.ustring.format("[[n:%s|Wiadomości w Wikinews]]", link)
end
end,
},
{
arg = "q",
icon = "wikicytaty",
text = function(arg)
local link = demo and demoProp("plwikiquote", arg) or (arg or standardLink("plwikiquote"))
if link then
return mw.ustring.format("[[q:%s|Teksty w Wikicytatach]]", link)
end
end,
},
{
arg = "s",
icon = "wikiźródła",
text = function(arg)
local link = demo and demoProp("plwikisource", arg) or (arg or standardLink("plwikisource"))
if link then
return mw.ustring.format("[[s:%s|Teksty w Wikiźródłach]]", link)
end
end,
},
{
arg = "wikt",
icon = "wikisłownik",
text = function(arg)
-- nie ma jeszcze linków w Wikidanych
local link = arg or (demo and "" or false)
if link then
return mw.ustring.format("[[wikt:%s|Hasło w Wikisłowniku]]", link)
end
end,
},
{
arg = "wikispecies",
icon = "wikispecies",
text = function(arg)
local link = demo and demoProp("specieswiki", arg) or (arg or standardLink("specieswiki"))
if link then
return mw.ustring.format("[[wikispecies:%s|Systematyka w Wikispecies]]", link)
end
end,
},
{
arg = "voy",
icon = "wikipodróże",
text = function(arg)
local link = demo and demoProp("plwikivoyage", arg) or (arg or standardLink("plwikivoyage"))
if link then
return mw.ustring.format("[[voy:%s|Informacje w Wikipodróżach]]", link)
end
end,
},
{
arg = "b",
icon = "wikibooks",
text = function(arg)
local link = demo and demoProp("plwikibooks", arg) or (arg or standardLink("plwikibooks"))
if link then
return mw.ustring.format("[[b:%s|Książki w Wikibooks]]", link)
end
end,
},
{
arg = "wikt:cat",
icon = "wikisłownik",
text = function(arg)
if demo then
return "W Wikisłowniku: słownik języka [[:d:Property:P424|P424]]"
end
if arg then
local data = mw.loadData("Module:Lang/data")[standardProp("P424") or ""]
return mw.ustring.format("W Wikisłowniku: [[wikt:Kategoria:%s|słownik języka%s]]", arg, data and (" "..data["dopełniacz"]) or "")
end
end,
},
}
local result = {}
for _, project in ipairs(projects) do
local param = frame.args[project.arg]
if param then
local text = project.text(#param > 0 and param or nil)
if text then
if #result == 0 then
local header = frame.args["nagłówek"] or resources.defaultProjectHeader
if #header > 0 then
table.insert(result, iboxSpan(true, header, frame.args["wiersz nagłówka"], frame.args["pole nagłówka"]))
end
end
--local icon = "<div style=\"float:left; margin-right: 0.5em\">[[Plik:"..require("Module:Ikona").plik(project.icon).."|20px]]</div>"
local icon = "[[Plik:"..require("Module:Ikona").plik(project.icon).."|20px|link=|alt=]]"
table.insert(result, iboxSpan(false, icon..text, addClass(frame.args["wiersz"], resources.classSisterProject), frame.args["pole"]))
end
end
end
end
end
end
a = a + step
end
return table.concat(result, "")
end
end,


-- Parse the data parameters in the same order that the old {{infobox}} did, so
["Państwo"] = function(frame)
-- that references etc. will display in the expected places. Parameters that
local Q, demo = Qdemo(frame)
-- depend on another parameter are only processed if that parameter is present,
if not Q then
-- to avoid phantom references appearing in article reference lists.
Q = mw.wikibase.getEntityIdForCurrentPage()
local function parseDataParameters()
end
if not Q then
return
end
local statements = mw.wikibase.getBestStatements(Q, "P17")
local errorCat = frame.args.kategoria
local link = frame.args.link
local altlink = frame.args.altlink
local nazwa = frame.args.nazwa
local opis = frame.args.opis
local results = {}
for i, s in ipairs(statements) do
local countryName = mw.wikibase.renderSnak(s.mainsnak)
local templateCountry = mw.title.new("Państwo dane "..countryName, "Szablon")
local result
if templateCountry.exists then
local dependent = frame:expandTemplate{ title = "Terytorium zależne", args = {
[1] = countryName,
[2] = countryName
}}
if dependent and (#dependent == 0) then
dependent = nil
end
result = frame:expandTemplate{ title = templateCountry.text, args = {
[1] = "infobox państwo/core",
wariant = dependent or countryName,
link = link,
altlink = altlink,
nazwa = nazwa,
rozmiar = i == 1 and opis or "&nbsp;"
}}
else -- nie ma szablonu państwa
result = frame:expandTemplate{ title = "Infobox wiersz", args = {
[1] = "[[Państwo]]",
[2] = errorCat.."WD"..tostring(i)..": "..countryName,
kol2 = 'class="linksInherit" style="background:yellow; color:red;"'
}}
end
if result then
table.insert(results, result)
end
end
return table.concat(results)
end,


preprocessSingleArg('autoheaders')
}
preprocessSingleArg('child')
preprocessSingleArg('bodyclass')
preprocessSingleArg('subbox')
preprocessSingleArg('bodystyle')
preprocessSingleArg('title')
preprocessSingleArg('titleclass')
preprocessSingleArg('titlestyle')
preprocessSingleArg('above')
preprocessSingleArg('aboveclass')
preprocessSingleArg('abovestyle')
preprocessArgs({
{prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}}
}, 10)
preprocessSingleArg('subheaderstyle')
preprocessSingleArg('subheaderclass')
preprocessArgs({
{prefix = 'image', depend = {'caption', 'imagerowclass'}}
}, 10)
preprocessSingleArg('captionstyle')
preprocessSingleArg('imagestyle')
preprocessSingleArg('imageclass')
preprocessArgs({
{prefix = 'header'},
{prefix = 'data', depend = {'label'}},
{prefix = 'rowclass'},
{prefix = 'rowstyle'},
{prefix = 'rowcellstyle'},
{prefix = 'class'}
}, 50)
preprocessSingleArg('headerclass')
preprocessSingleArg('headerstyle')
preprocessSingleArg('labelstyle')
preprocessSingleArg('datastyle')
preprocessSingleArg('below')
preprocessSingleArg('belowclass')
preprocessSingleArg('belowstyle')
preprocessSingleArg('name')
-- different behaviour for italics if blank or absent
args['italic title'] = origArgs['italic title']
preprocessSingleArg('decat')
preprocessSingleArg('templatestyles')
preprocessSingleArg('child templatestyles')
preprocessSingleArg('grandchild templatestyles')
end
 
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
function p.infobox(frame)
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame
end
parseDataParameters()
return _infobox()
end
 
-- For calling via #invoke within a template
function p.infoboxTemplate(frame)
origArgs = {}
for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end
parseDataParameters()
return _infobox()
end
return p

Wersja z 17:58, 18 kwi 2025

Q

Funkcja zwraca wartość opcjonalnego pola Q w wywołaniu szablonu (infoboksu), który ma wskazywać na źródłowy element w Wikidanych, jeśli szablon jest używany poza przestrzenią główną. Na stronie definiującej szablon (kod źródłowy infoboksu) zwraca wartość „demo”. Jeśli parametr nie został podany zwraca tekst pusty. Z tego parametru domyślnie korzystają pozostałe funkcje modułu, które próbują uzupełnić automatycznie brakujące dane.

Demo

Funkcja renderująca zapis pola z demonstracją odwołania do Wikidanych. Przyjmuję listę nazw argumentów będących nazwami pól szablonu lub cech z Wikidanych. Cechy są identyfikowane pustą nazwą poprzedzającą.

{{#invoke:Infobox|Demo|nazwa||wd}} → {{{nazwa|wd}}}

Kolejny

Funkcja do wywołania bezpośrednio z infoboksu sprawdzająca czy szablon ją wywołujący jest kolejnym infoboksem na stronie. Działa przy założeniu, że na stronie osadzone są infoboksy różnych typów.

pole wartość domyślna opis
1 tak Treść zwracana jako wynik jeśli szablon infoboksu nie jest pierwszy na stronie.

Test

Funkcja sprawdzająca czy istnieje jakakolwiek zdefiniowana cecha w Wikidanych z podanej listy. Każdą cechę należy podać w oddzielnym parametrze. Na stronie definiującej szablon zwraca niepustą wartość („demo”).

pole wartość domyślna opis
parametr indeksowany brak Identyfikator cechy w postaci Pnnnn.

Tytuł

{{{1}}}
{{{2}}}
{{{3}}}

Funkcja generuje nagłówek infoboksu – odpowiednik {{infobox tytuł}}. Jest to pole nagłówka tabeli definiowane jako |+. Teksty kolejnych poziomów są oddzielane znacznikiem nowej linii (<br>).

pole wartość domyślna opis
kategoria brak brak Nazwa kategorii generowanej w artykule, jeśli wygenerowany nagłówek jest pusty. Można podać pełny wikilink do kategorii lub ostatni człon nazwy (zwykle nazwa pola). Standardowa nazwa [[Kategoria:Infoboksy – brak danych – ''nazwa infoboksu'' – ''kategoria brak'']] zostanie wygenerowana automatycznie. Jeśli parametru nie podano to kategoria nie jest generowana.
pole brak Atrybuty nagłówka tabeli.
cecha P1705 P1448 Lista cech, z których pierwsza niepusta wartość będzie użyta jako treść drugiego poziomu, jeśli nie podano jej jawnie w parametrze. Domyślnie są to „nazwa oryginalna” lub „nazwa oficjalna”.
1 Etykieta z Wikidanych Tekst główny nagłówka infoboksu. Niepusta treść jest owijana w <span class="iboxt1">.
2 Pierwsza niepusta wartość cechy z listy przekazanej przez pole cecha Tekst drugiego poziomu nagłówka infoboksu. Niepusta treść jest owijana w <span class="iboxt2">.
3 brak Tekst trzeciego poziomu nagłówka infoboksu. Niepusta treść jest owijana w <span class="iboxt3">.

Grafika

Funkcja do wstawiania sekcji obrazkowej. Składa się ona z jednego opcjonalnego dużego obrazka i opcjonalnej listy małych ilustracji umieszczanych w parach obok siebie.

pole wartość domyślna opis
wiersz brak Opcjonalne atrybuty wiersza.
dodaj brak Dodatkowy warunek wyświetlania treści infoboksu. Wartość pusta oznacza, że nie zostania wygenerowana żadna treść w infoboksie.
pole brak Atrybuty komórki tabeli z wartością wyświetlaną.
format 250x250px lub 100x100px Zwykle rozmiar obrazka.
grafika brak Nazwa pliku na commons użytego jako ilustracja albo wartość nie w celu wyłączenia wyświetlania ilustracji. Domyślnym formatem dla tej grafiki jest 250x250px.
opis grafiki brak Opcjonalny opis umieszczany pod ilustracją.
cecha brak Identyfikator cechy w Wikidanych zawierającą wskazanie do pliku na commons.
cecha opisu brak Identyfikator cechy z artykułem opisującym ilustrację (np. herb lub flagę).
N. grafika[mini 1] brak Nazwa pliku na commons użytego jako ilustracja albo wartość nie w celu wyłączenia wyświetlania ilustracji. Domyślnym formatem dla tej grafiki jest 100x100px.
N. opis grafiki[mini 1] brak Opcjonalny opis umieszczany pod ilustracją.
N. cecha[mini 1] brak Identyfikator cechy w Wikidanych zawierającą wskazanie do pliku na commons.
N. cecha opisu[mini 1] brak Identyfikator cechy z artykułem opisującym ilustrację (np. herb lub flagę).
  1. 1,0 1,1 1,2 1,3 Lista małych obrazków wprowadzana jest przez parametry z dodatkowym indeksem N. numerowanym od 1 w górę. Są one umieszczane w dwukolumnowej tabeli ze stylem class="ibox2".

Grupa

Funkcja ułatwiająca generowanie grup wierszy z nagłówkiem.

pole wartość domyślna opis
kategoria brak brak Nazwa kategorii generowanej w artykule, jeśli podany (wygenerowany) nagłówek jest pusty. Można podać pełny wikilink do kategorii lub ostatni człon nazwy (zwykle nazwa pola). Standardowa nazwa [[Kategoria:Infoboksy – brak danych – ''nazwa infoboksu'' – ''kategoria brak'']] zostanie wygenerowana automatycznie. Jeśli parametru nie podano to kategoria nie jest generowana.
nagłówek brak Tytuł nagłówka grupy.
pole nagłówka brak Atrybuty pola nagłówka.
wiersz nagłówka brak Atrybuty wiersza nagłówka.
klasa kreski iboxs Klasa dodawana do atrybutu class wiersza tabeli, gdy wymagana jest kreska. Odpowiedni styl powinien być zdefiniowany w globalnym common.css.
parametry indeksowane brak Treść wierszy infoboksu lub „-” w miejscu gdzie ma być separator. Wiersze infoboksu muszą być generowane jako fragment tabeli w wikikodzie.

Blok

{{{nagłówek}}}
{{{1}}}

Elementarny generator pionowego pola infoboksu (z opisem nad wartością). Generowane są tylko niepuste wartości. Domyślnie generowana treść ma postać:

|-
!colspan="2"|{{{nagłówek}}}
|-
|-
|class="iboxa" colspan="2"|{{{1}}}
|-
pole wartość domyślna opis
wiersz nagłówka brak Atrybuty wiersza tabeli z nagłówkiem.
pole nagłówka brak Atrybuty komórki tabeli z nagłówkiem.
wiersz brak Atrybuty wiersza tabeli z wartością wyświetlaną.
nagłówek brak Tytuł nagłówka.
dodaj brak Dodatkowy warunek wyświetlania treści infoboksu. Wartość pusta oznacza, że nie zostania wygenerowana żadna treść w infoboksie.
pole brak Atrybuty komórki tabeli z wartością wyświetlaną.
cecha brak Identyfikator cechy w Wikidanych, której wartość będzie wyświetlana jeśli nie zostanie jawnie przekazana w wywołaniu. Może być również źródłem nazwy nagłówka, jeśli nie jest podany, a jednocześnie istnieje polska etykieta dla podanej cechy w Wikidanych.
kategoria brak brak Nazwa kategorii generowanej w artykule, jeśli wygenerowany tekst jest pusty. Można podać pełny wikilink do kategorii lub ostatni człon nazwy (zwykle nazwa pola). Standardowa nazwa [[Kategoria:Infoboksy – brak danych – ''nazwa infoboksu'' – ''kategoria brak'']] zostanie wygenerowana automatycznie. Jeśli parametru nie podano to kategoria nie jest generowana.
1 brak Wartość wyświetlana.

Wiersz

{{{etykieta}}} {{{1}}}

Elementarny generator pola infoboksu. Generowane są tylko niepuste wartości. Domyślnie generowana treść ma postać:

|-
! {{{etykieta}}}
| class="iboxa"| {{{1}}}
|-
pole wartość domyślna opis
wiersz brak Opcjonalne atrybuty wiersza.
etykieta brak Tytuł pola opisu wartości.
dodaj brak Dodatkowy warunek wyświetlania treści infoboksu. Wartość pusta oznacza, że nie zostania wygenerowana żadna treść w infoboksie.
pole brak Atrybuty komórki tabeli z wartością wyświetlaną.
cecha brak Identyfikator cechy w Wikidanych, której wartość będzie wyświetlana jeśli nie zostanie jawnie przekazana w wywołaniu. Może być również źródłem nazwy nagłówka, jeśli nie jest podany, a jednocześnie istnieje polska etykieta dla podanej cechy w Wikidanych.
kategoria brak brak Nazwa kategorii generowanej w artykule, jeśli wygenerowany tekst jest pusty. Można podać pełny wikilink do kategorii lub ostatni człon nazwy (zwykle nazwa pola). Standardowa nazwa [[Kategoria:Infoboksy – brak danych – ''nazwa infoboksu'' – ''kategoria brak'']] zostanie wygenerowana automatycznie. Jeśli parametru nie podano to kategoria nie jest generowana.
1 brak Wartość wyświetlana.

Drzewo

TODO

Projekt

W projektach Wikimedia

Generator linków do projektów siostrzanych. Aby włączyć linkowanie do określonego projektu siostrzanego należy podać jawny parametr (nawet pusty) odpowiedzialny za jego prezentację.

pole wartość domyślna opis
wiersz nagłówka brak Atrybuty wiersza tabeli z nagłówkiem.
pole nagłówka brak Atrybuty komórki tabeli z nagłówkiem.
wiersz brak Atrybuty wiersza tabeli z wartością wyświetlaną.
nagłówek W projektach Wikimedia Tytuł nagłówka. Jeśli podany pusty to nagłówek nie jest wyświetlany.
pole brak Atrybuty komórki tabeli z wartością wyświetlaną.
wikipedia brak Włącza generowanie linku do innej wersji językowej Wikipedii. Zastosowanie dla {{język infobox}}.
c brak Włącza generowanie linku do commons.
n brak Włącza generowanie linku do Wikinews.
q brak Włącza generowanie linku do Wikicytatów.
s brak Włącza generowanie linku do Wikiźródeł.
wikt brak Włącza generowanie linku do hasła w Wikisłowniku.
wikispecies brak Włącza generowanie linku do Wikispecies.
voy brak Włącza generowanie linku do Wikipodróży.
b brak Włącza generowanie linku do Wikibooks.
wikt:cat brak Włącza generowanie linku do kategorii w Wikisłowniku.

Państwo

Funkcja pomocnicza dla {{Infobox państwo}} generująca wyniki na podstawie cechy [[:d:Property:P17|]] (P17) w Wikidanych.


require("strict")
local resources = mw.loadData("Moduł:Infobox/resources")

local function P(frame, qid, pid)
	local sd = require("Module:Wikidane/select")
	return sd.selectProperty(pid, sd.prepareFilters(frame), qid)
end

local function isNullOrWhiteSpace(text)
	return (text == nil)
		or (#text <= 0)
		or string.match(text, "^%s+$")
end

local function addClass(attributes, class)
	if not class or (#class == 0) then
		return attributes
	end
	
	if not attributes or (#attributes == 0) then
		return "class=\""..class.."\""
	end
	
	local r, c = string.gsub(attributes or "", "%f[%w]class%s*=%s*['\"]", "%0"..class.." ", 1)
	if c == 1 then
		return r
	end
	
	return "class=\""..class.."\" "..attributes
end

local function iboxSpan(header, text, row, cell)
	assert(type(header) == "boolean")

	local result = {}
	table.insert(result, "|-")
	if row and (#row > 0) then
		table.insert(result, " ")
		table.insert(result, row)
	end

	table.insert(result, "\n")
	table.insert(result, header and "!" or "|")
	if cell and (#cell > 0) then
		table.insert(result, cell)
		table.insert(result,' ')
	end
	
	table.insert(result, 'colspan="2"|')
	table.insert(result, text)
	table.insert(result, "\n|-\n")
	return table.concat(result)
end

local function emptyCategory(frame, emptyCat)
	if not emptyCat or (mw.title.getCurrentTitle().namespace ~= 0) then
		return ""
	end
	
	if mw.ustring.match(emptyCat, "%[%[[Kk]ategoria:.-%]%]") then
		return emptyCat
	end
	
	local template = frame:getParent():getTitle()
	local infobox = mw.ustring.match(template, "^Szablon:(.- infobox)$")
	return mw.ustring.format(resources.catMissingData, infobox or template, emptyCat)
end

local function InputData(frame, Q, demo, source, sourcepropid)
	local ns = mw.title.getCurrentTitle().namespace
	local add = frame.args["dodaj"]
	local cell = frame.args["pole"]
	local propid = frame.args[sourcepropid or "cecha"]
	local emptyCat = frame.args["kategoria brak"]
	local value = frame.args[source or 1]
	
	add = (add == nil) or (#add > 0)

	if emptyCat and (#emptyCat == 0) then
		emptyCat = false
	end

	if propid and (#propid == 0) then
		propid = false
	end
	
	if isNullOrWhiteSpace(value) then
		value = false
	end
	
	local demovalue = false
	if value then
		demovalue = mw.ustring.match(value, "^%s*{{{(.-)}}}%s*$")
	end
	
	local wdvalue = false
	if add and not demo and (not value or demovalue) and propid then
		local pid, qid, prop = P(frame, Q, propid)
		if pid and qid and prop then
			value = require("Moduł:Wikidane/format").run(frame, pid, prop)
			if not value or (#value <= 0) then
				value = false
			else
				wdvalue = true
			end
		end
	end

	if add and not demo and (not value or (demovalue and not wdvalue)) and emptyCat then
		cell = addClass(cell, resources.classEmpty)
		value = (value or "") .. emptyCategory(frame, emptyCat)
	end
	
	if not demo and demovalue then
		cell = addClass(cell, resources.classMissingArg)
		if ns == 0 then
			value = value..resources.catMissingArg
		end
	end
	
	return add and value or false, cell, demovalue, propid
end

local function Qdemo(frame)
	local Q = frame:getParent().args.Q
	if Q and string.match(Q, "^%d") then
		Q = "Q"..Q
	end
	
	if Q then
		-- jest Q to nie demo
		return Q, false
	end
	
	for k, v in pairs(frame:getParent().args) do
		-- nie ma Q lecz dowolny argument to również nie demo
		return nil, false
	end

	-- nie ma Q ani żadnego parametru, jeśli to źródło szablonu, to musi to być demo
	return nil, (mw.title.getCurrentTitle().fullText == frame:getParent():getTitle())
end

local function editWDlink(qid, pid)
	return "<span class=\"plainlinks wdlink\" title=\"edytuj dane z infoboxu w Wikidanych\">&#x5B;[https://www.wikidata.org/wiki/"..qid.."#"..pid.." e]&#x5D;</span>"
end

local function imageWDdemo(pid)
	if pid then
		if string.match(pid, "^P%d+$") then
			return "[[:d:Property:"..pid.."|"..pid.."]]"
		end
	
		return "<span class=\"wdimgdemo\">"..pid.."</span>"
	end	
end

local function propertyLabel(frame, propid, propid2)
	local lang = mw.getContentLanguage()
	if not propid2 then
		local pid, qid, prop = P(frame, propid, "P1629")
		if pid and qid and prop then
			mw.logObject(prop, "P1629")
			local value = require("Moduł:Wikidane/format").run(frame, pid, prop)
			if value and (#value > 0) then
				value = mw.ustring.gsub(value, "(|)(%l)", function(bar, lcase) return bar..lang:ucfirst(lcase) end)
				return lang:ucfirst(value)
			end
		end
	end

	local label1 = mw.wikibase.label(propid)
	if not label1 or (#label1 <= 0) then
		return false
	end
	
	if not propid2 then
		return lang:ucfirst(label1)
	end
		
	local label2 = mw.wikibase.label(propid2)
	if not label2 or (#label2 <= 0) then
		return false
	end
		
	local cp1 = { mw.ustring.codepoint(label1, 1, mw.ustring.len(label1)) }
	local cp2 = { mw.ustring.codepoint(label2, 1, mw.ustring.len(label2)) }
	local len = #cp1 < #cp2 and #cp1 or #cp2
	-- find common suffix
	local suffix = false
	for i = 1, len do
		if cp1[#cp1-i+1] ~= cp2[#cp2-i+1] then
			suffix = len - i + 1
			break
		end
	end

	while (suffix < len) and (cp1[#cp1 - suffix + 1] ~= 32) do
		suffix = suffix + 1
	end
	
	if suffix < len then
		label1 = mw.ustring.char(unpack(cp1, 1, #cp1 - suffix))
	end
	
	return lang:ucfirst(mw.text.trim(label1).." i "..mw.text.trim(label2))
end

local function makeDemoArg(wrap, ...)
	local count = select('#', ...)
	if count <= 0 then
		return
	end

	local items = {}
	local index = 1
	while index <= count do
		local v = select(index, ...)
		if v and (type(v) == "string") then
			table.insert(items, v)
		end
		
		index = index + 1
	end
	
	if #items <= 0 then
		return
	end

	local prefix = wrap and "{{{" or ""
	local suffix = wrap and "}}}" or ""
	return prefix..table.concat(items,"&#x7C;")..suffix
end

local function SecondaryInfobox(templateTitle, message)
	local contents = mw.title.getCurrentTitle():getContent()
	local infoboxPattern = "{{ *(%f[%a][%a ]-%f[ ] infobox)%s*|"
	local start = 1
	while true do
		mw.logObject(start, "Kolejny:start")
		local s, e, n = mw.ustring.find(contents, infoboxPattern, start, false)
		if not s then
			break
		end
		
		mw.logObject({s, e, n}, "Kolejny:find{s e n}")
		local prefix = mw.ustring.match(n, "^(%a-):")
		mw.logObject(prefix, "Kolejny:prefix")
		local ns = 10
		if prefix then
			prefix = mw.getCurrentLang():ucfirst(prefix)
			ns = mw.site.namespaces[prefix] or ns
		end
		mw.logObject(ns, "Kolejny:ns")
		local infoboxTitle = mw.title.new(n, ns)
		mw.logObject(infoboxTitle, "Kolejny:infoboxTitle")
		if templateTitle == infoboxTitle then
			mw.logObject(start == 1 and "" or message, "Kolejny:return")
			return start == 1 and "" or message
		end
		
		start = e
	end
	
	mw.log("Kolejny: BRAK")
	return mw.title.getCurrentTitle().namespace == 0
		and "?" -- tego przypadku nie powinno być w przestrzeni głównej
		or false -- a poza nią to nie ma takiego znaczenia
end

return {
	["Q"] = function(frame)
		local Q, demo = Qdemo(frame)
		return demo and "demo" or Q
	end,
	
	["Demo"] = function(frame)
		local args = require('Module:Arguments').getArgs(frame, { trim = false, removeBlanks = false })
		local result = {}
		local i = 1
		local wd = false
		while true do
			local v = args[i]
			i = i + 1
			if not v then
				break
			end
			
			if #v == 0 then
				if wd then
					table.insert(result, "")
				end
				
				wd = true
			else
				table.insert(result, wd and imageWDdemo(v) or v)
				wd = false
			end
		end
		
		if #result then
			local result = "{{{"..table.concat(result,"&#x7C;").."}}}"
			mw.logObject(result, "result")
			return result
		end
	end,
	
	["Kolejny"] = function(frame)
		local message = frame.args[1]
		if not message or (#mw.text.trim(message) == 0) then
			message = "tak"
		end
		
		local templateTitle = mw.title.new(frame:getParent():getTitle())
		return SecondaryInfobox(templateTitle, message)
	end,

	["Test"] = function(frame)
		local Q, demo = Qdemo(frame)
		if demo then
			return "demo"
		end
		
		local i = 1
		local sd = require("Module:Wikidane/select")
		while true do
			local pid = frame.args[i]
			if not pid then
				return
			end
			
			local pid, qid, prop = sd.selectProperty(pid, {}, Q)
			if qid then
				return pid
			end
			
			i = i + 1
		end
	end,

	["Tytuł"] = function(frame)
		local Q, demo = Qdemo(frame)
		local emptyCat = frame.args["kategoria brak"]
		local attrs = frame.args["pole"]
		local props = frame.args["cecha"] or resources.defaultTitle2Property
		local text1 = frame.args[1]
		local text2 = frame.args[2]
		local text3 = frame.args[3]
		
		if isNullOrWhiteSpace(text1) then
			text1 = false
		end
		if isNullOrWhiteSpace(text2) then
			text2 = false
		end
		if isNullOrWhiteSpace(text3) then
			text3 = false
		end

		local demo1 = false
		if text1 then
			demo1 = mw.ustring.match(text1, "^{{{(.-)}}}$")
		end
		local demo2 = false
		if text2 then
			demo2 = mw.ustring.match(text2, "^{{{(.-)}}}$")
		end
		local demo3 = false
		if text3 then
			demo3 = mw.ustring.match(text3, "^{{{(.-)}}}$")
		end

		local Q, demo = Qdemo(frame)

		local builder = mw.html.create()
		builder:wikitext("|+")
		if attrs and (#attrs > 0) then
			builder:wikitext(" ", attrs, " | ")
		end

		local titleWithText = false
		local function appendPart(class)
			if titleWithText then
				builder:tag("br")
			end
			
			titleWithText = true
			return builder:tag("span"):addClass(class)
		end
		
		local label = false
		if demo and demo1 then
			appendPart(resources.classTitle1):wikitext("{{{", demo1, "&#x7C;", imageWDdemo("Etykieta"), "}}}")
		elseif demo then
			appendPart(resources.classTitle1):wikitext(imageWDdemo("Etykieta"))
		elseif text1 and (#text1 > 0) then
			appendPart(resources.classTitle1):wikitext(text1)
		else
			label = mw.wikibase.label(Q)
			if label then
				appendPart(resources.classTitle1):wikitext(label)
			end
		end
		
		local props1 = {}
		local props2 = {}
		for propid in string.gmatch(props, "%S+") do
			table.insert(props1, propid)
			table.insert(props2, "&#x7C;")
			table.insert(props2, imageWDdemo(propid))
		end
		props2 = table.concat(props2, "")
		
		mw.text.split(props, "%s")
		if demo and demo2 then
			appendPart(resources.classTitle2):wikitext("{{{", demo2, props2, "}}}")
		elseif demo and (#props1 > 0) then
			appendPart(resources.classTitle2):wikitext("{{{", props2, "}}}")
		elseif text2 and (#text2 > 0) then
			appendPart(resources.classTitle2):wikitext(text2)
		elseif #props1 > 0 then
			local pid, qid, prop
			for _, propid in ipairs(props1) do
				pid, qid, prop = P(frame, Q, propid)
				if qid and prop then
					local text2 = require("Moduł:Wikidane/format").run(frame, pid, prop)
					if text2 then
						local lang = mw.getContentLanguage()
						local l = label and lang:caseFold(label) or label
						local t1 = text1 and lang:caseFold(text1) or text1
						local t2, _ = mw.ustring.gsub(text2, "</?[A-Za-z]+ ?[^<>]*/?>", "") -- remove HTML tags
						t2 = lang:caseFold(t2)
						if (t2 ~= t1) and (t2 ~= l) then
							appendPart(resources.classTitle2):wikitext(text2)
							break
						end
					end
				end
			end
		end
		
		if text3 and (#text3 > 0) then
			appendPart(resources.classTitle3):wikitext(text3)
		end
		
		if not titleWithText then
			-- use page title
			local title = mw.title.getCurrentTitle()
			local text = title.text
			local nodisambig = mw.ustring.match(text, "^(.-)%s+%([^%(%)]+%)$")
			if nodisambig and (#nodisambig > 0) then
				text = nodisambig
			end
			
			appendPart(resources.classEmpty):wikitext(text, emptyCategory(frame, emptyCat))
		end
		
		if not titleWithText then
			-- no text
			return
		end
		
		builder:wikitext("\n")
		return builder:allDone()
	end,

	["Grafika"] = function(frame)
		local add = frame.args["dodaj"]
		add = (add == nil) or (#add > 0)
		if not add then
			return
		end
		
		local function formatFile(file, alt, format, description)
			
			local function removeLinks(text)
				--mw.logObject(text, "RemoveLinks:input")
				if text then
					text = mw.ustring.gsub(text, "%s+", " ") -- compact white characters into one space
					text = mw.ustring.gsub(text, "%[https?://[^%[%]%s|]+%]", "") -- remove LZ
					text = mw.ustring.gsub(text, "%[https?://[^%[%]%s|]+ ([^%[%]|]+)%]", "%1") -- remove LZ, leave description
					text = mw.ustring.gsub(text, "%[%[[^%[%]|]+|([^%[%]|]*)%]%]", "%1" ) -- remove wikilinks, leave description
					text = mw.ustring.gsub(text, "%[%[([^%[%]|]*)%]%]", "%1" ) -- remove wikilinks, leave description
					text = mw.ustring.gsub(text, "%s+", " ") -- compact white characters into one space again
					text = mw.text.nowiki(text)
				end
				
				--mw.logObject(text, "RemoveLinks:output")
				return text
			end

			local result = {}
			table.insert(result, "[[Plik:")
			table.insert(result, file)
			if format and (#format > 0) then
				table.insert(result, "|")
				table.insert(result, format)
				if mw.ustring.match(format, "^%s*alt%s*=") or mw.ustring.match(format, "|%s*alt%s*=") then
					alt = false
				end
			end
			if alt and (#alt > 0) then
				table.insert(result, "|alt=")
				table.insert(result, removeLinks(alt))
			end
			if description and (#description > 0) then
				table.insert(result, "|")
				table.insert(result, removeLinks(description))
			end
			
			table.insert(result,"]]")
			return table.concat(result)
		end
		
		local function checkIfFileExists(file)
			local pattern, _ = mw.ustring.gsub( file, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
			pattern, _ = mw.ustring.gsub(pattern, "[ _]", "[ _]")
			pattern = "%[%[%s*(%a+)%s*:"..pattern.."%s*[%]|]"
			--mw.logObject(pattern, "Grafika:checkIfFileExists PATTERN")
			local contents = mw.title.getCurrentTitle():getContent()
			local start = 1
			while true do
				--mw.logObject(start, "Grafika:checkIfFileExists NEXT")
				local s, e, n = mw.ustring.find(contents, pattern, start, false)
				if not s then
					--mw.logObject(file, "Grafika:checkIfFileExists FALSE")
					return false
				end
				
				--mw.logObject({n,file}, "Grafika:checkIfFileExists{n,file}")
				local title = mw.title.new(file, n)
				if title and (title.namespace == 6) then
					--mw.logObject(file, "Grafika:checkIfFileExists TRUE")
					return true
				end
				
				start = e
			end
		end
		
		local Q, demo = Qdemo(frame)
		local row = frame.args["wiersz"]
		local cell = frame.args["pole"]
		local format = frame.args["format"]
		local imageTitle = false
		local secondary = false
		local callingTemplate = frame:getParent():getTitle()
		if mw.title.new(callingTemplate) == mw.title.new("Szablon:Infobox grafika") then
			imageTitle = frame:getParent().args["tytuł grafiki"]
			secondary = frame:getParent().args["kolejny"]
		else
			imageTitle = frame.args["tytuł grafiki"]
			if (#callingTemplate > 8) and (mw.ustring.sub(callingTemplate, -8) == " infobox") then
				secondary = SecondaryInfobox(callingTemplate, callingTemplate)
			end
		end

		if format and (#format <= 0) then
			format = nil
		end
		
		mw.logObject(secondary,"secondary")
		
		local wdExists = false
		
		local function loadPicture(file, description, fileProperty, descProperty, defaultFormat)
			if file == "nie" then
				return
			end
			
			if isNullOrWhiteSpace(file)	then
				file = false
				description = false
			elseif isNullOrWhiteSpace(description) then
				description = false
			end
			
			if isNullOrWhiteSpace(fileProperty) then
				fileProperty = false
				descProperty = false
			elseif isNullOrWhiteSpace(descProperty) then
				descProperty = false
			end
			
			local alt = false
			local desc = nil
			local patched = false
			if fileProperty then
				alt = mw.wikibase.label(fileProperty)
			end
			
			local demoFile = false
			local demoDescription = false
			if file then
				demoFile = mw.ustring.match(file, "^{{{(.-)}}}$")
				if not demoFile then
					file = mw.ustring.gsub(file, "%s*[Pp]lik%s*:%s*", "Plik:")
					file = mw.ustring.gsub(file, "%s*[Ff]ile%s*:%s*", "Plik:")
					file = mw.ustring.gsub(file, "%s*[Gg]rafika%s*:%s*", "Plik:")
					file = mw.ustring.gsub(file, "%s*[Ii]mage%s*:%s*", "Plik:")
					if mw.ustring.match(file, "^Plik:(.*)") then
					    file = mw.ustring.match(file, "^Plik:(.*)")
					    patched = true
					elseif mw.ustring.match(file, "%[%[Plik:([^%[%]|]+)[|%]]") then
					    file = mw.ustring.match(file, "%[%[Plik:([^%[%]|]+)[|%]]")
					    patched = true
					end
				end
			end
			if description then
				demoDescription = mw.ustring.match(description, "^{{{(.-)}}}$")
			end
			
			if not demo and (not file or demoFile) and fileProperty then
				if secondary and (#secondary > 0) then
					mw.logObject(secondary, "Grafika: nie ładuję obrazka z Wikidanych na drugim lub kolejnym infoboksie")
					return
				end
				
				local pid, qid, prop = P(frame, Q, fileProperty)
				if pid and qid and prop then
					for _, v in ipairs(prop) do
						if v.mainsnak and (v.mainsnak.snaktype == "value") and (v.mainsnak.datatype == "commonsMedia") and v.mainsnak.datavalue and (v.mainsnak.datavalue.type == "string") then
							local commonMedia = v.mainsnak.datavalue.value
							if not isNullOrWhiteSpace(commonMedia) then
								if checkIfFileExists(commonMedia) then
									mw.logObject(commonMedia, "Grafika: obrazek, który jest oferowany w Wikidanych, już jest umieszczony w kodzie strony")
									wdExists = true
									return
								end
								
								file = commonMedia
								alt = mw.wikibase.label(v.mainsnak.property)
								desc = require("Moduł:Wikidane/format/qualifiers").TEXT1(v, nil, "P2096")
								break
							end
						end
					end
				end
			
				if file and descProperty then
					pid, qid, prop = P(frame, Q, descProperty)
					if pid and qid and prop then
						local v = require("Moduł:Wikidane/format").run(frame, pid, prop)
						if not isNullOrWhiteSpace(v) then
							description = v
						end
					end
				end
			end
		
			if not demo and file then
				return {
					formatFile(file, alt, format or defaultFormat, desc or description)..(patched and resources.catPatchedFile or ""),
					description or desc
				}
			end
		
			if demo and (demoFile or fileProperty) then
				return {
					formatFile(makeDemoArg(true, demoFile, imageWDdemo(fileProperty)), alt, format or defaultFormat, false),
					makeDemoArg(true, demoDescription, imageWDdemo(descProperty))
				}
			end
		end

		local args = {
			file = "grafika", description = "opis grafiki", fileProperty = "cecha", descProperty = "cecha opisu", defaultFormat = "250x250px",
			fileN = "%d. grafika", descriptionN = "%d. opis grafiki", filePropertyN = "%d. cecha", descPropertyN = "%d. cecha opisu", defaultFormatN = "100x100px",
		}
		
		local bigImage = loadPicture(frame.args[args.file], frame.args[args.description], frame.args[args.fileProperty], frame.args[args.descProperty], args.defaultFormat)
		mw.logObject(bigImage, "bigImage")
		local smallImages = {}
		local index = 1
		while true do
			local file = frame.args[mw.ustring.format(args.fileN, index)]
			local description = frame.args[mw.ustring.format(args.descriptionN, index)]
			local fileProperty = frame.args[mw.ustring.format(args.filePropertyN, index)]
			local descProperty = frame.args[mw.ustring.format(args.descPropertyN, index)]
			if not file and not fileProperty then
				break
			end
			
			index = index + 1
			local image = loadPicture(file, description, fileProperty, descProperty, args.defaultFormatN)
			if image then
				table.insert(smallImages, image)
			end
		end
		
		local result = {}
		if wdExists and secondary and (#secondary == 0) and (mw.title.getCurrentTitle().namespace == 0) then
			table.insert(result, '|- style="display:none"\n| colspan="2" |"')
			table.insert(result, resources.catIgnoreImage)
			table.insert(result, '\n')
		end
		
		if bigImage then
			if imageTitle and (#imageTitle > 0) then
				table.insert(bigImage, 1, '<span style="font-weight: bold>'..imageTitle..'</span>')
			end
			
			table.insert(result, iboxSpan(false, table.concat(bigImage, "<br />"), row, cell))
		end
		
		if #smallImages > 0 then
			local index = 1
			table.insert(result, '|-')
			table.insert(result, row)
			table.insert(result, '\n|colspan="2" padding="0" ')
			table.insert(result, cell)
			table.insert(result, '|\n{| class="ibox2"\n')
			
			-- display images in pairs
			while (index + 1) <= #smallImages do
				local image1 = smallImages[index + 0]
				local image2 = smallImages[index + 1]
				-- both files must exists
				table.insert(result, '|-\n|')
				table.insert(result, image1[1])
				table.insert(result, '\n|')
				table.insert(result, image2[1])
				table.insert(result, '\n')
				-- descriptions are optional
				if image1[2] or image2[2] then
					table.insert(result, '|-\n|')
					table.insert(result, image1[2] or "")
					table.insert(result, '\n|')
					table.insert(result, image2[2] or "")
					table.insert(result, '\n')
				end
				
				-- next pair
				index = index + 2
			end
			
			-- display last odd image
			if index == #smallImages then
				local image = smallImages[index]
				table.insert(result, '|-\n|colspan=2|')
				table.insert(result, image[1])
				table.insert(result, '\n')
				if image[2] then
					table.insert(result, '|-\n|colspan=2|')
					table.insert(result, image[2])
					table.insert(result, '\n')
				end
			end
		
			table.insert(result, '|-\n|}\n|-\n')
		end
		
		if (#result > 0) and frame.args["dodaj zamykający wiersz"] then
			-- łatka na wywołanie w szablonie wewnątrz #if:,
			-- który obcina odstępy, w tym znak nowej linii
			-- a domyślnie wynik kończy się tym znakiem
			table.insert(result, '|-\n')
		end
		
		if #result > 0 then
			return table.concat(result)
		end
	end,
	
	["Grupa"] = function(frame)
		local Q, demo = Qdemo(frame)
		local emptyCat = frame.args["kategoria brak"]
		local header = frame.args["nagłówek"]
		local headerRow = frame.args["wiersz nagłówka"]
		local headerCell = frame.args["pole nagłówka"]
		local lineClass = frame.args["klasa kreski"]
		local result = {}
		
		local append = function(text)
			if (#result == 0) and header then
				local cell = headerCell
				if #header == 0 then
					cell = addClass(headerCell, resources.classEmpty)
					header = emptyCategory(frame, emptyCat)
				elseif not demo and mw.ustring.match(header, "^{{{(.-)}}}$") then
					cell = addClass(headerCell, resources.classMissingArg)
				end
				
				table.insert(result, iboxSpan(true, header, headerRow, cell))
			end
		
			table.insert(result, text)
		end
		
		local total = false
		local sep = false
		local i = 1
		while true do
			local arg = frame.args[i]
			if not arg then
				break
			end
			
			i = i + 1
			arg = string.match(arg, "^(.-)%s*$") -- trim remaing space
			if arg == "-" then
				sep = true
			elseif #arg > 0 then -- real content
				local next = false
				for line in mw.text.gsplit(arg, "\n%f[|!]", false) do
					if next then
						append("\n")
					end
					
					next = true
					if sep and (#line >= 2) and (string.byte(line, 1) == 124) and (string.byte(line, 2) == 45) then
						-- row with separator line
						local class = string.match(line, 'class="(.-)"')
						local newClass = resources.classSeparator
						if lineClass and (#lineClass > 0) then
							newClass = newClass.." "..lineClass
						end
						
						if class then
							line = string.gsub(line, 'class="', 'class="'..newClass.." ", 1)
						else
							line = mw.text.trim(line)..' class="'..newClass..'"'
						end
					else
						-- content or row without separator line
						sep = false
					end
					
					append(line)
				end
			end
		end
	
		return table.concat(result)
	end,
	
	["Blok"] = function(frame)
		local Q, demo = Qdemo(frame)
		local headerRow = frame.args["wiersz nagłówka"]
		local headerCell = frame.args["pole nagłówka"]
		local row = frame.args["wiersz"]
		local label = frame.args["nagłówek"]
		local value, cell, demovalue, propid = InputData(frame, Q, demo)

		if label == "-" then
			label = false
			row = addClass(row, resources.classSeparator)
		elseif label and (#label == 0) then
			label = false
		elseif not label and propid then
			label = propertyLabel(frame, propid)
		end
		
		local demolabel = false
		if label then
			demolabel = mw.ustring.match(label, "^{{{(.-)}}}$")
		end
		
		local text = false
		if demo and demovalue and propid then
			text = "{{{"..demovalue.."&#x7C;"..imageWDdemo(propid).."}}}"
		elseif demo and propid then
			text = "{{{"..imageWDdemo(propid).."}}}"
		elseif demo and demolabel then
			text = "{{{"..demovalue.."}}}"
		elseif value then
			text = value
		end
		
		if not text then
			return
		end
		
		local header
		if label == false then
			header = false
		elseif label and (#label > 0) then
			header = label
		elseif demo and demolabel and propid then
			header = "{{{"..demolabel.."&#x7C;"..imageWDdemo("label").."}}}"
		elseif demo and propid then
			header = "{{{"..imageWDdemo("label").."}}}"
		elseif demo and demolabel then
			header = "{{{"..demolabel.."}}}"
		elseif propid then
			header = "{{{nagłówek}}}"..resources.catMissingLabel
		elseif demo then
			header = "{{{nagłówek}}}"
		end
		
		local result = {}
		if header then
			table.insert(result, iboxSpan(true, header, headerRow, headerCell))
		end
		
		table.insert(result, iboxSpan(false, text, row, cell))
		return table.concat(result)
	end,

	["Wiersz"] = function(frame)
		local Q, demo = Qdemo(frame)
		local row = frame.args["wiersz"]
		local label = frame.args["etykieta"]
		local value, cell, demovalue, propid = InputData(frame, Q, demo)

		if label and (#label == 0) then
			label = false
		end
		
		if not label and propid then
			label = propertyLabel(frame, propid)
		end
		
		local demolabel = false
		if label then
			demolabel = mw.ustring.match(label, "^{{{(.-)}}}$")
		end
		
		local builder = mw.html.create()
		builder:wikitext("|-")
		if row and (#row > 0) then
			builder:wikitext(" ", row, " | ")
		end

		builder:wikitext("\n! ")
		
		if label and (#label > 0) then
			builder:wikitext(label)
		elseif demo and demolabel and propid then
			builder:wikitext("{{{", demolabel, "&#x7C;", imageWDdemo("label"), "}}}")
		elseif demo and propid then
			builder:wikitext("{{{", imageWDdemo("label"), "}}}")
		elseif demo and demolabel then
			builder:wikitext("{{{", demolabel, "}}}")
		elseif propid then
			builder:wikitext("{{{etykieta}}}", resources.catMissingLabel)
		else
			builder:wikitext("{{{etykieta}}}")
		end
		
		builder:wikitext("\n| ")
		if cell and (#cell > 0) then
			builder:wikitext(cell)
			builder:wikitext("| ")
		end
		
		if demo and demovalue and propid then
			builder:wikitext("{{{", demovalue, "&#x7C;", imageWDdemo(propid), "}}}")
		elseif demo and propid then
			builder:wikitext("{{{", imageWDdemo(propid), "}}}")
		elseif demo and demovalue then
			builder:wikitext("{{{", demovalue, "}}}")
		elseif value then
			builder:wikitext(value)
		else
			return
		end
		
		builder:wikitext("\n|-")
		return builder:allDone()
	end,
	
	["Wiersz2"] = function(frame)
		local Q, demo = Qdemo(frame)
		local row = frame.args["wiersz"]
		local label = frame.args["etykieta"]
		local label1 = frame.args["etykieta 1"]
		local label2 = frame.args["etykieta 2"]
		local value1, cell, demovalue1, propid1 = InputData(frame, Q, demo, 1, "cecha 1")
		local value2, _, demovalue2, propid2 = InputData(frame, Q, demo, 2, "cecha 2")

		if label and (#label == 0) then
			label = false
		end
		
		if not label and propid1 and propid2 then
			label = propertyLabel(frame, propid1, propid2)
		end

		if label1 and (#label1 == 0) then
			label1 = false
		end
		
		if not label1 and propid1 then
			label1 = propertyLabel(frame, propid1)
		end

		if label2 and (#label2 == 0) then
			label2 = false
		end
		
		if not label2 and propid2 then
			label2 = propertyLabel(frame, propid2)
		end

		local demolabel1 = false
		if label1 then
			demolabel1 = mw.ustring.match(label1, "^{{{(.-)}}}$")
		end
		
		local demolabel2 = false
		if label2 then
			demolabel2 = mw.ustring.match(label2, "^{{{(.-)}}}$")
		end
		
		local builder = mw.html.create()
		builder:wikitext("|-")
		if row and (#row > 0) then
			builder:wikitext(" ", row, " | ")
		end

		builder:wikitext("\n! ")
		
		if demo then
			if label and (#label > 0) then
				builder:wikitext(label)
			else
				if label1 and (#label1 > 0) then
					builder:wikitext(label1)
				elseif demolabel1 and propid1 then
					builder:wikitext("{{{", demolabel1, "&#x7C;", imageWDdemo("label1"), "}}}")
				elseif propid1 then
					builder:wikitext("{{{", imageWDdemo("label1"), "}}}")
				elseif demolabel1 then
					builder:wikitext("{{{", demolabel1, "}}}")
				elseif propid1 then
					builder:wikitext("{{{etykieta 1}}}", resources.catMissingLabel)
				else
					builder:wikitext("{{{etykieta 1}}}")
				end
				builder:wikitext(" i ")
				if label2 and (#label2 > 0) then
					builder:wikitext(label2)
				elseif demolabel2 and propid2 then
					builder:wikitext("{{{", demolabel2, "&#x7C;", imageWDdemo("label2"), "}}}")
				elseif propid2 then
					builder:wikitext("{{{", imageWDdemo("label2"), "}}}")
				elseif demolabel2 then
					builder:wikitext("{{{", demolabel2, "}}}")
				elseif propid2 then
					builder:wikitext("{{{etykieta 2}}}", resources.catMissingLabel)
				else
					builder:wikitext("{{{etykieta 2}}}")
				end
			end
		elseif value1 and value2 and label then
			builder:wikitext(label)
		elseif value1 and value2 and label1 and label2 then
			builder:wikitext(label1, " i ", label2)
		elseif value1 and value2 then
			builder:wikitext("{{{etykieta}}}", resources.catMissingLabel)
		elseif value1 and label1 then
			builder:wikitext(label1)
		elseif value1 then
			builder:wikitext("{{{etykieta 1}}}", resources.catMissingLabel)
		elseif value2 and label2 then
			builder:wikitext(label2)
		elseif value2 then
			builder:wikitext("{{{etykieta 2}}}", resources.catMissingLabel)
		else
			return
		end

		builder:wikitext("\n| ")
		if cell and (#cell > 0) then
			builder:wikitext(cell)
			builder:wikitext("| ")
		end
		
		local br = true
		if demo and demovalue1 and propid1 then
			builder:wikitext("{{{", demovalue1, "&#x7C;", imageWDdemo(propid1), "}}}")
		elseif demo and propid1 then
			builder:wikitext("{{{", imageWDdemo(propid1), "}}}")
		elseif demo and demovalue1 then
			builder:wikitext("{{{", demovalue1, "}}}")
		elseif value1 then
			builder:wikitext(value1)
		else
			br = false
		end
		
		if demo and demovalue2 and propid2 then
			if br then builder:tag("br") end
			builder:wikitext("{{{", demovalue2, "&#x7C;", imageWDdemo(propid2), "}}}")
		elseif demo and propid2 then
			if br then builder:tag("br") end
			builder:wikitext("{{{", imageWDdemo(propid2), "}}}")
		elseif demo and demovalue2 then
			if br then builder:tag("br") end
			builder:wikitext("{{{", demovalue2, "}}}")
		elseif value2 then
			if br then builder:tag("br") end
			builder:wikitext(value2)
		end
		
		builder:wikitext("\n|-")
		return builder:allDone()
	end,
	
	["Fragment"] = function(frame)
		local Q, demo = Qdemo(frame)
		local value, unused, demovalue, propid = InputData(frame, Q, demo)
		local text = false
		if demo and demovalue and propid then
			text = "{{{"..demovalue.."&#x7C;"..imageWDdemo(propid).."}}}"
		elseif demo and propid then
			text = "{{{"..imageWDdemo(propid).."}}}"
		elseif demo and demolabel then
			text =  "{{{"..demovalue.."}}}"
		elseif value then
			return value
		end
		
		return text and '|-\n|colspan="2"| '..text.."\n" or ""
	end,
	
	["Drzewo"] = function(frame)
		local Q, demo = Qdemo(frame)
		local headerRow = frame.args["wiersz nagłówka"]
		local headerCell = frame.args["pole nagłówka"]
		local header = frame.args["nagłówek"]
		local row = frame.args["wiersz"] or 'class="tree"'
		local cell = frame.args["pole"]
		
		local text = false
		if demo then
			text = imageWDdemo("'''Skrypt Lua'''")
		else
			if not Q then
				local entity = mw.wikibase.getEntity()
				if not entity then
					return
				end
				
				Q = entity.id
			end
			
			text = require("Module:Wikidane/Tree").classTree(frame, Q)
		end
		
		if not text then
			return
		end
		
		if header == "-" then
			header = false
			row = addClass(row, resources.classSeparator)
		elseif header and (#header == 0) then
			label = false
		end
		
		local result = {}
		if header then
			table.insert(result, iboxSpan(true, header, headerRow, headerCell))
		end
		
		table.insert(result, iboxSpan(false, text, row, cell))
		return table.concat(result, "")
	end,

	["Projekt"] = function(frame)
		local Q, demo = Qdemo(frame)
		local entity = mw.wikibase.getEntity(Q)
		local standardLink = function(sitelink)
			return entity and entity.sitelinks and entity.sitelinks[sitelink] and entity.sitelinks[sitelink].title
		end
		local standardProp = function(pid)
			local pid, qid, prop = require("Module:Wikidane/select").selectProperty(pid, {}, Q)
			if prop and prop[1] then
				local snak = prop[1].mainsnak
				if (snak.snaktype == "value") and (snak.datatype == "string") then
					return snak.datavalue.value
				end
			end
		end
		local demoProp = function(sitelink, arg)
			local demovalue = false
			if arg then
				demovalue = mw.ustring.match(arg, "^{{{(.-)}}}$")
			end
			
			local result = {}
			if demovalue then
				table.insert(result, "&#8203;") -- wrap here
				table.insert(result, "{{{")
				table.insert(result, demovalue)
				table.insert(result, "&#x7C;&#8203;")
				table.insert(result, imageWDdemo(sitelink))
				table.insert(result, "}}}&#8203;")
			else
				table.insert(result, "&#8203;")
				table.insert(result, imageWDdemo(sitelink))
				table.insert(result, "&#8203;")
			end
			
			return table.concat(result)
		end
		local projects = {
			{
				arg = "wikipedia",
				icon = "wikipedia",
				text = function()
					if demo then
						return "Wikipedia w języku [[:d:Property:P424|P424]]"
					end
					
					local wikilang = arg or standardProp("P424")
					if wikilang == "pl" then
						return "Wikipedia w [[Wikipedia:Strona główna|języku polskim]]"
					end
					
					if wikilang then
						return mw.ustring.format("Wikipedia w [[:%s:|języku %s]]", wikilang, mw.loadData("Module:Lang/data")[wikilang].miejscownik)
					end
				end,
			},
			{
				arg = "c",
				icon = "commons",
				text = function(arg)
					local link = false
					if demo then
						link = demoProp("commonswiki", arg)
					elseif arg then
						link = arg
					else
						link = standardLink("commonswiki")
						if not link then
							local cat = standardProp("P373")
							if cat then
								link = "Category:"..cat
							else
								--or standardProp("P910") -- main category article
							end
						end
					end
				
					if link then
						return mw.ustring.format("[[commons:%s|Multimedia w Wikimedia Commons]]", link)
					end
				end,
			},
			{
				arg = "n",
				icon = "wikinews",
				text = function(arg)
					local link = demo and demoProp("plwikinews", arg) or (arg or standardLink("plwikinews"))
					if link then
						return mw.ustring.format("[[n:%s|Wiadomości w Wikinews]]", link)
					end
				end,
			},
			{
				arg = "q",
				icon = "wikicytaty",
				text = function(arg)
					local link = demo and demoProp("plwikiquote", arg) or (arg or standardLink("plwikiquote"))
					if link then
						return mw.ustring.format("[[q:%s|Teksty w Wikicytatach]]", link)
					end
				end,
			},
			{
				arg = "s",
				icon = "wikiźródła",
				text = function(arg)
					local link = demo and demoProp("plwikisource", arg) or (arg or standardLink("plwikisource"))
					if link then
						return mw.ustring.format("[[s:%s|Teksty w Wikiźródłach]]", link)
					end
				end,
			},
			{
				arg = "wikt",
				icon = "wikisłownik",
				text = function(arg)
					-- nie ma jeszcze linków w Wikidanych
					local link = arg or (demo and "" or false)
					if link then
						return mw.ustring.format("[[wikt:%s|Hasło w Wikisłowniku]]", link)
					end
				end,
			},
			{
				arg = "wikispecies",
				icon = "wikispecies",
				text = function(arg)
					local link = demo and demoProp("specieswiki", arg) or (arg or standardLink("specieswiki"))
					if link then
						return mw.ustring.format("[[wikispecies:%s|Systematyka w Wikispecies]]", link)
					end
				end,
			},
			{
				arg = "voy",
				icon = "wikipodróże",
				text = function(arg)
					local link = demo and demoProp("plwikivoyage", arg) or (arg or standardLink("plwikivoyage"))
					if link then
						return mw.ustring.format("[[voy:%s|Informacje w Wikipodróżach]]", link)
					end
				end,
			},
			{
				arg = "b",
				icon = "wikibooks",
				text = function(arg)
					local link = demo and demoProp("plwikibooks", arg) or (arg or standardLink("plwikibooks"))
					if link then
						return mw.ustring.format("[[b:%s|Książki w Wikibooks]]", link)
					end
				end,
			},
			{
				arg = "wikt:cat",
				icon = "wikisłownik",
				text = function(arg)
					if demo then
						return "W Wikisłowniku: słownik języka [[:d:Property:P424|P424]]"
					end
					
					if arg then
						local data = mw.loadData("Module:Lang/data")[standardProp("P424") or ""]
						return mw.ustring.format("W Wikisłowniku: [[wikt:Kategoria:%s|słownik języka%s]]", arg, data and (" "..data["dopełniacz"]) or "")
					end
				end,
			},
		}
	
		local result = {}
		for _, project in ipairs(projects) do
			local param = frame.args[project.arg]
			if param then
				local text = project.text(#param > 0 and param or nil)
				if text then
					if #result == 0 then
						local header = frame.args["nagłówek"] or resources.defaultProjectHeader
						if #header > 0 then
							table.insert(result, iboxSpan(true, header, frame.args["wiersz nagłówka"], frame.args["pole nagłówka"]))
						end
					end
					
					--local icon = "<div style=\"float:left; margin-right: 0.5em\">[[Plik:"..require("Module:Ikona").plik(project.icon).."|20px]]</div>"
					local icon = "[[Plik:"..require("Module:Ikona").plik(project.icon).."|20px|link=|alt=]]"
					table.insert(result, iboxSpan(false, icon..text, addClass(frame.args["wiersz"], resources.classSisterProject), frame.args["pole"]))
				end
			end
		end
		
		return table.concat(result, "")
	end,

	["Państwo"] = function(frame)
		local Q, demo = Qdemo(frame)
		if not Q then
			Q = mw.wikibase.getEntityIdForCurrentPage()
		end
		if not Q then
			return
		end
		
		local statements = mw.wikibase.getBestStatements(Q, "P17")
		local errorCat = frame.args.kategoria
		local link = frame.args.link
		local altlink = frame.args.altlink
		local nazwa = frame.args.nazwa
		local opis = frame.args.opis
		local results = {}
		for i, s in ipairs(statements) do
			local countryName = mw.wikibase.renderSnak(s.mainsnak)
			local templateCountry = mw.title.new("Państwo dane "..countryName, "Szablon")
			local result
			if templateCountry.exists then
				local dependent = frame:expandTemplate{ title = "Terytorium zależne", args = {
					[1] = countryName,
					[2] = countryName
				}}
				if dependent and (#dependent == 0) then
					dependent = nil
				end
				result = frame:expandTemplate{ title = templateCountry.text, args = {
					[1] = "infobox państwo/core",
					wariant = dependent or countryName,
					link = link,
					altlink = altlink,
					nazwa = nazwa,
					rozmiar = i == 1 and opis or "&nbsp;"
				}}
			else -- nie ma szablonu państwa
				result = frame:expandTemplate{ title = "Infobox wiersz", args = {
					[1] = "[[Państwo]]",
					[2] = errorCat.."WD"..tostring(i)..": "..countryName,
					kol2 = 'class="linksInherit" style="background:yellow; color:red;"'
				}}
			end
			if result then
				table.insert(results, result)
			end
		end
		
		return table.concat(results)
	end,

}