UWAGA |
---|
Większość artykułów w portalu to nasze własne teksty z kluczowych dziedzin związanych z naszą misją. Spora część materiałów pochodzi też z polskiej wersji Wikipedii, gdzie były odrzucone ze względu na politykę redaktorów (przeczytaj o krytyce Wikipedii). Są też i takie, które zostały przeniesione na nasze strony, gdyż stanowią istotne uzupełnienie merytorycznej treści naszego serwisu. Wszystkie artykuły podlegają edycji przez naszych Użytkowników, dlatego ich wersje mogą się różnić od prezentowanych na innych witrynach. |
Moduł:Navbox
Moduł z funkcją generowania szablonu nawigacyjnego.
Użycie
{{#invoke:Navbox|Navbox|...}}
Opis parametrów
Typowe ogólne wywołanie
{{#invoke:Navbox|Navbox |tytuł = {{{tytuł}}} |góra = {{{góra}}} |przed = {{{przed}}} |opis1 = {{{opis1}}} |spis1 = {{{spis1}}} |opis2 = {{{opis2}}} |opis2.1 = {{{opis2.1}}} |spis2.1 = {{{spis2.1}}} |opis2.2 = {{{opis2.2}}} |spis2.2 = {{{spis2.2}}} |opis3 = {{{opis3}}} |spis3 = {{{spis3}}} |po = {{{po}}} |dół = {{{dół}}} }}
Układ z kolumnami
Włączane przez | spis = * kolumny *
.
{{#invoke:Navbox|Navbox |tytuł = {{{tytuł}}} |spis = * kolumny * |opis1 = {{{opis1}}} |spis1 = {{{spis1}}} |opis2 = {{{opis2}}} |spis2 = {{{spis2}}} |opis3 = {{{opis3}}} |spis3 = {{{spis3}}} }}
Układ z grupami
Włączane przez | spis = * grupa *
. Zwijaniem można sterować przez | zwijanie.N = zwinięte
, | zwijanie.N = rozwinięte
lub | zwijanie.N = auto
. Ostatni tryb pozostawia grupę rozwiniętą jeśli znajduje się link do bieżącej strony. Jednak na stronie szablonu treść jest zawsze w postaci rozwiniętej.
{{#invoke:Navbox|Navbox |tytuł = {{{tytuł}}} |spis = * grupa * |opis1 = {{{opis1}}} |spis1 = {{{spis1}}} |zwijanie.2 = rozwinięte |opis2 = {{{opis2}}} |spis2 = {{{spis2}}} |zwijanie.3 = zwinięte |opis3 = {{{opis3}}} |spis3 = {{{spis3}}} }}
Wywołanie z nietypową zawartością
Treść przekazywana przez | spis =
.
{{#invoke:Navbox|Navbox |tytuł = {{{tytuł}}} |spis = {{{spis}}} }}
Inny
Włączane przez | spis = * inny *
. Generuje drzewo zagnieżdżonych elementów <div>
. Przeznaczony do ręcznego dostosowywania przez dedykowany CSS.
{{#invoke:Navbox|Navbox |tytuł = {{{tytuł}}} |spis = * inny * |opis1 = {{{opis1}}} |spis1 = {{{spis1}}} |opis2 = {{{opis2}}} |spis2 = {{{spis2}}} |opis3 = {{{opis3}}} |spis3 = {{{spis3}}} }}
Stylizacja
Za dodatkowe sterowanie wyglądem służy | klasa =
, do którego można przekazać zbiór opcjonalnych wartości:
pionowy
- włącza generowanie pionowego szablonu nawigacyjnego
medaliści
- włącza kolorowanie tła pierwszych trzech nagłówków pierwszego poziomu na złoto, srebro i brąz.
kz-linia
- zezwala na wyświetlanie dekoracyjnych ikon linii transportu publicznego miast lub aglomeracji
hwrap
- zezwala na łamanie linii wewnątrz elementów list
Błędy
Błędy należy zgłaszać na stronie Wikipedia:Kawiarenka/Kwestie techniczne.
require ("strict")
local res = mw.loadData('Moduł:Navbox/res')
local function encodeClass(name)
local t = mw.getContentLanguage():lcfirst(name)
local s = mw.ustring.gsub(t, ".", { ['ł'] = 'l', ['Ł'] = 'L', ['_'] = ' '}) -- wstępne zmiany ł->l i _-> spacja
local p = mw.ustring.gsub(s, "%p+", "-") -- znaczki nieliterowe na minusy
local q = mw.ustring.gsub(p, "%s+", "_") -- odstępy na podkreślenia
local r = mw.ustring.toNFD(q) -- wyodrębnij diakrytyki
local e = string.gsub(r,"[\127-\255]+",'') -- usuń to czego nie ma w ASCII
return e
end
local function getPrinter(name)
local printer = res.printers[name]
return printer and require(printer) or nil
end
local function printSubTree(container, tree, currentPrinter, printlog)
local function printList(container, node, collapsibleContent)
local mwCCC = collapsibleContent and 'mw-collapsible-content' or nil
if #node <= 0 then
if printlog then
printlog.printedLeafs = (printlog.printedLeafs or 0) + 1
end
local leaf
if (currentPrinter.leaf == 'table') and mwCCC then
-- zwijanie tabelki i skórka timeless się gryzą
leaf = container:tag('div')
:addClass(mwCCC)
:tag(currentPrinter.leaf)
elseif currentPrinter.leaf then
leaf = container:tag(currentPrinter.leaf)
:addClass(mwCCC)
else
leaf = container
:addClass(mwCCC)
end
if currentPrinter.update then currentPrinter.update(leaf, true, node, printlog) end
leaf
:addClass(node.odd())
:addClass(node.even())
:newline()
:wikitext(node.get(res.arg.list.name))
:newline()
else
local subprinter = getPrinter(node.peek(res.arg.list.name))
if subprinter then
node.use(res.arg.list.name)
else
subprinter = getPrinter(true)
end
local subtag = subprinter.root or subprinter.leaf or 'div'
local subtree = ((subtag == 'table') and mwCCC)
and container:tag('div'):addClass(mwCCC):tag(subtag) -- zwijanie tabelki i skórka timeless się gryzą
or container:tag(subtag):addClass(mwCCC)
if currentPrinter.update then currentPrinter.update(subtree, false, node, printlog) end
printSubTree(subtree, node, subprinter, printlog)
end
end
currentPrinter.print(container, tree, printList, printlog)
end
local function argsService(templateContext)
local args = {}
local function add(k, v, prefix)
if v and #v > 0 then
args[k] = v
end
end
local peekName = function(name)
if not args[name] and templateContext and templateContext.aliases then
local alias = templateContext.aliases[name]
if alias and args[alias] then
return alias
end
end
return name
end
local function peek(name)
return args[peekName(name)]
end
local function get(name)
return peek(peekName(name)) or (res.aux.missingArgNamePrefix..name..res.aux.missingArgNameSuffix)
end
local function dump()
return mw.text.jsonEncode(args)
end
return {
add = add,
peek = peek,
use = peek,
get = get,
dump = dump,
}
end
local function loadArgsTree(args, printlog, templateContext)
local dynamicArgs = {}
for k, v in pairs(res.arg) do
if templateContext and templateContext.aliases then
local alias = templateContext.aliases[v.name]
if v.dynamic and alias then dynamicArgs[alias] = v.dynamic end
end
if v.dynamic then dynamicArgs[v.name] = v.dynamic end
end
local splitArgName = function(name)
if type(name) ~= "string" then
--mw.logObject(name, "to nie jest tekst")
return false, nil
end
local prefix, suffix = mw.ustring.match(name, "^(.-)([1-9][%.0-9]*)$")
if not prefix or not dynamicArgs[prefix] then
--mw.logObject(name, "wzór nie pasuje lub nierozpoznany")
return false, nil
end
local keys = mw.text.split(suffix,'.',true)
for i = 1, #keys do
keys[i] = tonumber(keys[i])
if not keys[i] or (keys[i] == 0) then
--mw.logObject({name, keys, i, keys[i]}, "wzór ma błędy")
return false, nil
end
end
return prefix, keys
end
local updateIndex = function(node, k)
node.index = node.index or {}
for i, v in ipairs(node.index) do
if v == k then
return
end
end
table.insert(node.index, k)
table.sort(node.index)
end
local argsTree = not printlog
and argsService(templateContext)
or require('Moduł:Navbox/diag').argsService(templateContext)
local argsTree_add = argsTree.add
argsTree.add = nil
local argsTree_tree = nil
local tree = function()
if not argsTree_tree or (#argsTree_tree <= 0) then
return nil
end
local function createNode(v)
local peekName = function(name)
if not v.address then
return nil
end
if argsTree.peek(name..v.address) then
return name..v.address
end
if templateContext and templateContext.aliases then
local alias = templateContext.aliases[name]
if alias and peek(alias..v.address) then
return alias..v.address
end
end
return nil
end
local node = {
address = function() return v.address and "a"..string.gsub(v.address, '%.', '_') or nil end,
peek = function(name)
return peekName(name)
and argsTree.peek(peekName(name))
or (templateContext and templateContext.defaults and templateContext.defaults[name])
end,
use = function(name) return peekName(name) and argsTree.use(peekName(name)) or nil end,
get = function(name) return peekName(name) and argsTree.get(peekName(name)) or nil end,
odd = function() return v.odd and res.class.odd or nil end,
even = function() return v.even and res.class.even or nil end,
}
local function calculateTest()
local pattern = mw.loadData("Moduł:Navbox/title").wikilinkPattern
local s1 = argsTree.peek(res.arg.group.name..v.address)
if s1 and mw.ustring.match(s1, pattern) then return true end
local s2 = argsTree.peek(res.arg.list.name..v.address)
if s2 and mw.ustring.match(s2, pattern) then return true end
for i, n in ipairs(node) do
if n.test(pattern) then return true end
end
return false
end
local testCache
node.test = function()
if testCache == nil then
testCache = calculateTest()
end
return testCache
end
return node
end
local function buildTree(buffer, tree)
for i, v in ipairs(tree.index) do
local data = tree[v]
local node = createNode(data)
table.insert(buffer, node)
if data.index then
buildTree(node, data)
end
end
end
local rootNode = createNode({})
buildTree(rootNode, argsTree_tree)
return rootNode
end
local function analyzeArg(k, v, prefix, keys)
argsTree_add(k, v, prefix)
if prefix and v and (#v > 0) then
argsTree_tree = argsTree_tree or {}
local node = argsTree_tree
for i = 1, #keys do
local k = keys[i]
local child = node[k]
updateIndex(node, k)
if not child then
child = {
address = node.address and (node.address..'.'..tostring(k)) or tostring(k),
}
node[k] = child
end
node = child
end
end
end
for k, v in pairs(args) do
local prefix, keys = splitArgName(k)
local json, subargs
if (prefix == res.arg.list.name) and v and (#v > 0) then
json, subargs = pcall(mw.text.jsonDecode, v)
end
if json then
--analyzeArg(k, '* szablon *', prefix, keys)
for vk, vv in pairs(subargs) do
local vprefix, vkeys = splitArgName(vk)
if not vprefix and (vk == res.arg.list.name) then
vprefix = vk
vkeys = {}
end
if vprefix and prefix then
local newKeys = {}
for j, u in ipairs(keys) do table.insert(newKeys, u) end
for j, u in ipairs(vkeys) do table.insert(newKeys, u) end
local n = {}
for j, u in ipairs(newKeys) do table.insert(n, tostring(u)) end
local name = vprefix..table.concat(n, '.')
analyzeArg(name, vv, vprefix, newKeys)
end
end
else
analyzeArg(k, v, prefix, keys)
end
end
if templateContext and getPrinter(templateContext.list) then
analyzeArg(res.arg.list.name, templateContext.list, nil, nil)
end
if argsTree_tree then
local tree = argsTree_tree
local function loadLeafNodes(tree, buffer, level)
if not tree.index then
table.insert(buffer, tree)
else
local n = level
for i, v in ipairs(tree.index) do
local k = loadLeafNodes(tree[v], buffer, level + 1)
if k > n then
n = k
end
end
level = n
end
return level
end
local buffer = {}
local levels = loadLeafNodes(tree, buffer, 0)
for i, v in ipairs(buffer) do
v.odd = (i % 2) == 1
v.even = (i % 2) == 0
end
if printlog then
printlog.levels = levels
printlog.leafs = #buffer
end
end
argsTree.tree = tree
--mw.logObject(printlog, 'printlog')
--mw.logObject(argsTree, 'argsTree')
return argsTree
end
local function drawMiniNavBar(container, title, tags)
local pde = container:tag('ul')
:addClass('tnavbar')
:addClass('noprint')
:addClass('plainlinks')
:addClass('hlist')
-- p
local p = pde:tag('li'):wikitext("[[", title.nsText, ':', title.text, '|')
p:tag('span'):attr('title', res.navbar.p):wikitext(tags.p)
p:wikitext(']]')
-- d
if not title.isTalkPage then
local tt = title.talkPageTitle
local d = pde:tag('li'):wikitext("[[", tt.nsText, ':', tt.text, '|')
d:tag('span'):attr('title', res.navbar.d):wikitext(tags.d)
d:wikitext(']]')
end
-- e
pde:tag('li')
:attr('title', res.navbar.e)
:wikitext('[', title:fullUrl("action=edit"), ' ', tags.e, ']')
-- U
if mw.title.equals(title, mw.title.getCurrentTitle()) and (title.namespace == 10) then
local fullpagenamee = mw.uri.encode(title.fullText, "WIKI")
pde:tag('li')
:attr('title', res.navbar.U)
:wikitext('[https://tools.wmflabs.org/templatetransclusioncheck/index.php?lang=pl&name=', fullpagenamee, ' ', tags.U, ']')
end
end
local function splitCustomClasses(customClasses, navboxName)
if not customClasses then
return {}
end
local result = {}
local cc = mw.text.split(customClasses,"%s+")
for i, v in ipairs(cc) do
result[v] = res.validExtraClasses[v] ~= nil
end
-- pionowy szablon tylko na początku artykułu
if result.pionowy and navboxName then
local title = mw.title.getCurrentTitle()
if title and title.namespace == 0 then
local content = title:getContent()
if content then
local navboxStart = mw.ustring.find(content, "{{%s*"..mw.ustring.gsub( navboxName, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ).."%s*}}")
if navboxStart then
local firstSectionStart = mw.ustring.find(content, "\n==.-==[ \t]*\n")
if firstSectionStart and (firstSectionStart < navboxStart) then
mw.logObject(result, "splitCustomClasses KASUJĘ pionowy bo nie jest na początku artykułu")
result.pionowy = false
end
end
end
end
end
return result
end
local function makeContainer(args, title, contentTag, printlog)
local templateClassName = (title and (title.namespace > 0) and not title.isTalkPage)
and encodeClass(title.namespace == 10 and title.text or title.fullText)
or nil
local builder = mw.html.create('div')
:addClass(res.class.navbox)
:addClass('do-not-make-smaller')
local classes = splitCustomClasses(args.use(res.arg.class.name), args.peek(res.arg.name.name))
for c, valid in pairs(classes) do
builder:addClass((valid and res.validExtraClasses[c]) and c or nil)
end
if title and mw.title.equals(title, mw.title.getCurrentTitle()) or (classes[templateClassName] ~= nil) then
builder:addClass(templateClassName and res.class.name..templateClassName or nil)
end
builder:wikitext(mw.getCurrentFrame():extensionTag( 'templatestyles', '', {src = "Szablon:Navbox/styles.css"}))
local privateCSS = false
if classes[templateClassName] ~= nil then
privateCSS = tostring(title.fullText.."/styles.css")
builder:wikitext(mw.getCurrentFrame():extensionTag( 'templatestyles', '', {src = privateCSS}))
end
if not classes.pionowy then
builder:addClass('mw-collapsible'):attr('data-expandtext', res.aux.expandText):attr('data-collapsetext', res.aux.collapseText)
local collapse = function()
if mw.title.getCurrentTitle().namespace == 0 then
return 'mw-collapsed'
end
if args.peek(res.arg.collapsible.name) == res.arg.collapsible.collapsed then
return 'mw-collapsed'
end
if mw.title.getCurrentTitle().namespace ~= 10 then
return 'autocollapse'
end
return nil
end
if title then
builder:addClass(not mw.title.equals(title, mw.title.getCurrentTitle()) and collapse() or nil)
drawMiniNavBar(builder, title, res.navbar.mini)
else
builder
:addClass(mw.title.getCurrentTitle().namespace ~= 10 and collapse() or nil)
:tag('span'):addClass(res.navbar.fake)
end
end
builder:tag('div')
:addClass(res.class.caption)
:wikitext(args.get(res.arg.title.name))
local content
if not args.peek(res.arg.above.name) and not args.peek(res.arg.below.name) and not args.peek(res.arg.before.name) and not args.peek(res.arg.after.name) and not classes.pionowy then
if contentTag == 'table' then -- zwijanie tabeli gryzie się ze skórką timeless
content = builder:tag('div')
:addClass('mw-collapsible-content')
:tag(contentTag)
else
content = builder:tag(contentTag)
:addClass('mw-collapsible-content')
end
elseif not args.peek(res.arg.above.name) and not args.peek(res.arg.below.name) and not classes.pionowy then
local flex = builder:tag('div')
:addClass('mw-collapsible-content')
:addClass(res.class.flex)
if args.peek(res.arg.before.name) then flex:tag('div'):addClass(res.class.before):newline():wikitext(args.get(res.arg.before.name)):newline() end
content = flex:tag(contentTag)
if args.peek(res.arg.after.name) then flex:tag('div'):addClass(res.class.after):newline():wikitext(args.get(res.arg.after.name)):newline() end
else
local content1 = builder:tag('div')
:addClass('mw-collapsible-content')
if args.peek(res.arg.above.name) then content1:tag('div'):addClass(res.class.hlist):addClass(res.class.above):newline():wikitext(args.get(res.arg.above.name)):newline() end
local flex = (not classes.pionowy and ((args.peek(res.arg.before.name) or args.peek(res.arg.after.name)))) and content1:tag('div'):addClass(res.class.flex) or content1
if args.peek(res.arg.before.name) then flex:tag('div'):addClass(res.class.before):newline():wikitext(args.get(res.arg.before.name)):newline() end
content = flex:tag(contentTag)
if args.peek(res.arg.after.name) then flex:tag('div'):addClass(res.class.after):newline():wikitext(args.get(res.arg.after.name)):newline() end
if (title and classes.pionowy) or args.peek(res.arg.below.name) then
local below = content1:tag('div'):addClass(res.class.hlist):addClass(res.class.below)
if args.peek(res.arg.below.name) then
below:newline():wikitext(args.get(res.arg.below.name)):newline()
end
if title and classes.pionowy then
if args.peek(res.arg.below.name) then
below:wikitext("----"):newline()
end
drawMiniNavBar(below, title, res.navbar.short)
end
end
end
content:addClass(res.class.main)
for c, valid in pairs(classes) do
content:addClass((valid and not res.validExtraClasses[c]) and c or nil)
end
if printlog then
printlog.pionowy = classes.pionowy
printlog.templateClassName = templateClassName
printlog.privateCSS = privateCSS
for c, valid in pairs(classes) do
if not valid and (c ~= templateClassName) then
local u = printlog.unknownClasses or {}
table.insert(u, c)
printlog.unknownClasses = u
end
end
end
return builder, content
end
local function createNavbox(args, title, printlog)
local rootPrinter = getPrinter(args.peek(res.arg.list.name))
if rootPrinter then
args.use(res.arg.list.name)
end
local rootTree = args.tree()
local rootTag = 'div'
if rootTree then
rootPrinter = rootPrinter or getPrinter(true)
rootTag = rootPrinter and (rootPrinter.root or rootPrinter.leaf) or 'div'
end
local builder, content = makeContainer(args, title, rootTag, printlog)
if rootTree then
printSubTree(content, rootTree, rootPrinter or getPrinter(true), printlog)
elseif not rootPrinter and args.peek(res.arg.list.name) then
if printlog then printlog.notree = true end
content
:newline()
:wikitext(args.get(res.arg.list.name))
:newline()
else
if printlog then printlog.example = true end
local exampleTree = {{
address = function() return res.class.address.."1" end,
peek = function(name) return nil end,
use = function(name) return nil end,
get = function(name) return args.get(name.."1") end,
odd = function(name) return nil end,
even = function(name) return nil end,
}}
printSubTree(content, exampleTree, rootPrinter or getPrinter(true), printlog)
end
return not printlog and tostring(builder) or require('Moduł:Navbox/diag').diagnosticView(builder, args, printlog)
end
return {
["Navbox"] = function(frame)
local title = mw.title.new(frame:getParent():getTitle())
local printlog = mw.title.equals(title,mw.title.getCurrentTitle()) and {} or nil
local args = loadArgsTree(frame.args, printlog)
return createNavbox(args, title, printlog)
end,
["Template"] = function(frame)
mw.log('\n== '..frame:getParent():getTitle()..' ==\n')
-- specjalne traktowanie nazwy
local name = frame:getParent().args[res.arg.name.name]
local expectedTitle = (name and (#name > 0)) and mw.title.new(name, "Template") or nil
local printlog = false
if expectedTitle then
local currentTitle = mw.title.getCurrentTitle()
if (currentTitle.namespace == expectedTitle.namespace)
and (currentTitle.namespace ~= 0) -- bez artykułów
and (currentTitle.namespace ~= 2) -- bez brudnopisów
and not currentTitle.isTalkPage
and (currentTitle.subpageText ~= res.aux.docSubpageText) -- bez opisów
and (not expectedTitle.exists or not require('Moduł:Navbox/diag').verifyTemplateName(currentTitle, expectedTitle, frame:getParent():getTitle())) then
printlog = {}
printlog.badName = true
elseif mw.title.equals(currentTitle, expectedTitle) then
printlog = {}
end
elseif name and (#name > 0) then
-- tutaj nie ma żadnych możliwości sprawdzenia czy to jest szablon
-- czy jego transkluzja
local currentTitle = mw.title.getCurrentTitle()
if (currentTitle.namespace ~= 0) and not currentTitle.isTalkSpace then
printlog = {}
printlog.badName = true
end
end
local status, templateContext = pcall(mw.text.jsonDecode, frame.args.context or '[]')
if not status then
-- mw.logObject(frame.args.context, templateContext)
templateContext = {}
end
-- mw.logObject(templateContext, 'templateContext')
local args = loadArgsTree(frame:getParent().args, printlog, templateContext)
if args.peek(res.arg.name.name) then args.use(res.arg.name.name) end
--mw.logObject(mw.text.jsonDecode(args.dump()), 'args.dump()')
if printlog and templateContext.list then
printlog.useTemplateCategories = true
end
local navbox = args.peek(res.arg.name.name)
or args.peek(res.arg.title.name)
or args.peek(res.arg.class.name)
or args.peek(res.arg.above.name)
or args.peek(res.arg.below.name)
or args.peek(res.arg.before.name)
or args.peek(res.arg.after.name)
if navbox then
-- mw.log("----> createNavbox")
return createNavbox(args, expectedTitle, printlog)
end
-- mw.log("----> dump")
return args.dump()
end,
}