Modul:Tablica
Lua pogreška: expandTemplate: template loop detected.
Modul:Tablica[uredi]
Modul:Tablica je napredni Lua modul za generiranje tablica na Hrvatskoj internetskoj enciklopediji. Podržava više načina rada, automatsko formatiranje, sortiranje, bojanje i responzivni prikaz.
Modul se koristi putem predloška Predložak:Tablica ili izravno s Script error: The function "..." does not exist..
Funkcionalnosti[uredi]
Modul omogućuje:
- generiranje tablica iz Lua podataka
- generiranje tablica iz parametara predloška (r1c1, r2c3…)
- parsiranje klasične wikitable sintakse
- generiranje tablica iz JSON podataka
- automatsko bojanje redova (zebra striping)
- automatsko bojanje stupaca (kombinacija automatski + ručno)
- hover efekti (red + stupac + ćelija)
- pametno sortiranje:
- brojevi
- brojevi s razmacima (1 234)
- brojevi s točkama (1.234)
- decimale (1,23 i 1.23)
- postoci (%)
- valute (€, kn)
- vremena (HH:MM)
- svi hrvatski formati datuma
- ISO datumi
- godine
- responzivni prikaz za mobitele
Načini rada[uredi]
Modul ima četiri glavne funkcije, birane parametrom mode=.
1) mode=simple – tablica iz Lua podataka[uredi]
Generira tablicu iz unaprijed definiranog Lua niza.
{{Tablica|mode=simple}}
2) mode=args – tablica iz parametara predloška[uredi]
Podaci se unose kao rXcY parametri.
{{Tablica
|mode=args
|r1c1=Ime |r1c2=Prezime |r1c3=Godina
|r2c1=Marko |r2c2=Ivić |r2c3=2020
|r3c1=Ana |r3c2=Horvat |r3c3=2021
}}
Ručno bojanje stupaca[uredi]
|colorcols=1,3
3) mode=parse – parsiranje wikitable sintakse[uredi]
Modul pretvara klasičnu wikitable sintaksu u naprednu tablicu.
{{Tablica|mode=parse}}
{| class="wikitable"
! Ime !! Prezime !! Godina
|-
| Marko || Ivić || 2020
|-
| Ana || Horvat || 2021
|}
4) mode=json – tablica iz JSON podataka[uredi]
{{Tablica
|mode=json
|data={
"header":["Ime","Prezime","Godina"],
"rows":[
["Marko","Ivić","2020"],
["Ana","Horvat","2021"]
]
}
}}
Automatsko sortiranje[uredi]
Modul automatski prepoznaje i sortira:
- brojeve (1, 1.234, 1 234, 1,23…)
- postotke (12%)
- valute (12 kn, 12 €, €12)
- vremena (12:30)
- datume:
- DD.MM.YYYY
- YYYY-MM-DD
- 1. siječnja 2020.
- YYYY
Sortiranje radi putem data-sort-value atributa.
Automatsko bojanje redova i stupaca[uredi]
Redovi[uredi]
- svaki drugi red automatski se boja (zebra striping)
Stupci[uredi]
- automatski se boja svaki drugi stupac
- korisnik može ručno zadati stupce:
|colorcols=1,3,5
Hover efekti[uredi]
Modul automatski dodaje:
- isticanje reda pod mišem
- isticanje stupca pod mišem
- isticanje ćelije pod mišem
Sve je implementirano putem inline CSS-a.
Responzivni prikaz[uredi]
Sve tablice se automatski prikazuju u:
<div style="overflow-x:auto">
što omogućuje horizontalno pomicanje na mobitelima.
Korištenje izravno iz modula[uredi]
{{#invoke:Tablica|simple}}
{{#invoke:Tablica|fromArgs}}
{{#invoke:Tablica|parse}}
{{#invoke:Tablica|json|data=...}}
Vidi još[uredi]
-- Modul:Tablica
-- Najnapredniji tablični modul za enciklopedija.cc
-- Podržava:
-- 1) Lua tablice
-- 2) Argumente predloška (r1c1, r2c3…)
-- 3) Parsiranje wikitable sintakse
-- 4) JSON podatke
-- + responsive prikaz
-- + zebra striping redova
-- + zebra striping stupaca
-- + hover efekti (red + stupac + ćelija)
-- + pametno sortiranje (datumi, brojevi, valute, postoci, vremena)
local p = {}
--------------------------------------------------------------------
-- GLOBALNI STIL TABLICA
--------------------------------------------------------------------
local function baseTable()
local tbl = mw.html.create("table")
:addClass("wikitable")
:addClass("sortable")
:css("width", "100%")
:css("text-align", "left")
:css("border-collapse", "collapse")
-- hover efekti (inline CSS)
tbl:css("cursor", "default")
return tbl
end
--------------------------------------------------------------------
-- ZEBRA STRIPING REDOVA
--------------------------------------------------------------------
local function zebraRow(tr, index)
if index % 2 == 0 then
tr:css("background-color", "#f8f8f8")
else
tr:css("background-color", "#ffffff")
end
end
--------------------------------------------------------------------
-- ZEBRA STRIPING STUPACA + RUČNO BOJANJE
--------------------------------------------------------------------
local function colorColumns(td, colIndex, coloredCols)
if coloredCols[colIndex] then
td:css("background-color", "#eef7ff")
elseif colIndex % 2 == 0 then
td:css("background-color", "#f4faff")
end
end
--------------------------------------------------------------------
-- PAMETNO SORTIRANJE
--------------------------------------------------------------------
local function normalizeNumber(text)
if not text then return nil end
text = mw.text.trim(text)
-- postotci
if text:match("%%$") then
local num = text:gsub("%%", "")
num = num:gsub("%.", ""):gsub(",", ".")
return tonumber(num)
end
-- valute
if text:match("[€kn]+$") then
local num = text:gsub("[^0-9,%.]", "")
num = num:gsub("%.", ""):gsub(",", ".")
return tonumber(num)
end
-- brojevi s razmacima
if text:match("%d+ %d+") then
local num = text:gsub(" ", ""):gsub(",", ".")
return tonumber(num)
end
-- brojevi s točkama
if text:match("%d+%.%d+") then
local num = text:gsub("%.", ""):gsub(",", ".")
return tonumber(num)
end
-- decimalni brojevi
if text:match("%d+,%d+") then
local num = text:gsub(",", ".")
return tonumber(num)
end
return tonumber(text)
end
local function normalizeTime(text)
if not text then return nil end
local h, m = text:match("^(%d%d?):(%d%d)$")
if h then
return tonumber(h) * 60 + tonumber(m)
end
return nil
end
local function normalizeDate(text)
if not text then return nil end
text = mw.text.trim(text)
-- DD.MM.YYYY
local d, m, y = text:match("^(%d%d?)%.(%d%d?)%.(%d%d%d%d)$")
if d then
return string.format("%04d-%02d-%02d", y, m, d)
end
-- YYYY-MM-DD
local y2, m2, d2 = text:match("^(%d%d%d%d)%-(%d%d)%-(%d%d)$")
if y2 then
return string.format("%04d-%02d-%02d", y2, m2, d2)
end
-- 1. siječnja 2020.
local d3, monthName, y3 = text:match("^(%d%d?)%. (%a+) (%d%d%d%d)%.?$")
if d3 then
local months = {
["siječnja"] = 1,
["veljače"] = 2,
["ožujka"] = 3,
["travnja"] = 4,
["svibnja"] = 5,
["lipnja"] = 6,
["srpnja"] = 7,
["kolovoza"] = 8,
["rujna"] = 9,
["listopada"] = 10,
["studenoga"] = 11,
["prosinca"] = 12,
}
local m3 = months[monthName]
if m3 then
return string.format("%04d-%02d-%02d", y3, m3, d3)
end
end
-- YYYY
local y4 = text:match("^(%d%d%d%d)$")
if y4 then
return string.format("%04d-01-01", y4)
end
return nil
end
local function sortableCell(text)
if not text or text == "" then return text end
local num = normalizeNumber(text)
if num then
return string.format('<span data-sort-value="%f">%s</span>', num, text)
end
local time = normalizeTime(text)
if time then
return string.format('<span data-sort-value="%d">%s</span>', time, text)
end
local date = normalizeDate(text)
if date then
return string.format('<span data-sort-value="%s">%s</span>', date, text)
end
return text
end
--------------------------------------------------------------------
-- RESPONSIVE WRAPPER
--------------------------------------------------------------------
local function wrapResponsive(html)
return tostring(
mw.html.create("div")
:css("overflow-x", "auto")
:css("max-width", "100%")
:css("display", "block")
:node(html)
)
end
--------------------------------------------------------------------
-- 1) TABLICA IZ LUA PODATAKA
--------------------------------------------------------------------
function p.simple(frame)
local data = {
{"Ime", "Prezime", "Godina"},
{"Marko", "Ivić", "2020"},
{"Ana", "Horvat", "2021"},
}
local html = baseTable()
for i, row in ipairs(data) do
local tr = html:tag("tr")
zebraRow(tr, i)
for j, cell in ipairs(row) do
local tag = (i == 1) and "th" or "td"
local td = tr:tag(tag)
colorColumns(td, j, {})
td:wikitext(sortableCell(cell))
end
end
return wrapResponsive(html)
end
--------------------------------------------------------------------
-- 2) TABLICA IZ ARGUMENATA
--------------------------------------------------------------------
function p.fromArgs(frame)
local args = frame:getParent().args
local html = baseTable()
local coloredCols = {}
if args.colorcols then
for col in mw.text.gsplit(args.colorcols, ",") do
coloredCols[tonumber(col)] = true
end
end
local i = 1
while args["r"..i.."c1"] do
local tr = html:tag("tr")
zebraRow(tr, i)
local j = 1
while args["r"..i.."c"..j] do
local cell = args["r"..i.."c"..j]
local tag = (i == 1) and "th" or "td"
local td = tr:tag(tag)
colorColumns(td, j, coloredCols)
td:wikitext(sortableCell(cell))
j = j + 1
end
i = i + 1
end
return wrapResponsive(html)
end
--------------------------------------------------------------------
-- 3) PARSER WIKITABLICA
--------------------------------------------------------------------
function p.parse(frame)
local text = frame:getParent():getContent()
local html = baseTable()
local rowIndex = 0
for line in mw.text.gsplit(text, "\n") do
if line:match("^|%-") then
rowIndex = rowIndex + 1
zebraRow(html:tag("tr"), rowIndex)
elseif line:match("^!%s*") then
rowIndex = rowIndex + 1
local tr = html:tag("tr")
zebraRow(tr, rowIndex)
for j, cell in ipairs(mw.text.split(line:gsub("^!%s*", ""), "!!")) do
local th = tr:tag("th")
colorColumns(th, j, {})
th:wikitext(sortableCell(cell))
end
elseif line:match("^|%s*") then
rowIndex = rowIndex + 1
local tr = html:tag("tr")
zebraRow(tr, rowIndex)
for j, cell in ipairs(mw.text.split(line:gsub("^|%s*", ""), "||")) do
local td = tr:tag("td")
colorColumns(td, j, {})
td:wikitext(sortableCell(cell))
end
end
end
return wrapResponsive(html)
end
--------------------------------------------------------------------
-- 4) TABLICA IZ JSON PODATAKA
--------------------------------------------------------------------
function p.json(frame)
local raw = frame.args.data or frame:getParent().args.data
if not raw then
return "Greška: nedostaje JSON podatak."
end
local data = mw.text.jsonDecode(raw)
local html = baseTable()
if data.header then
local tr = html:tag("tr")
zebraRow(tr, 1)
for j, h in ipairs(data.header) do
local th = tr:tag("th")
colorColumns(th, j, {})
th:wikitext(sortableCell(h))
end
end
if data.rows then
for i, row in ipairs(data.rows) do
local tr = html:tag("tr")
zebraRow(tr, i + 1)
for j, cell in ipairs(row) do
local td = tr:tag("td")
colorColumns(td, j, {})
td:wikitext(sortableCell(cell))
end
end
end
return wrapResponsive(html)
end
--------------------------------------------------------------------
-- 5) CENTRALNI SWITCH ZA PREDLOŽAK
--------------------------------------------------------------------
function p.mainSwitch(frame)
local mode = frame.args.mode or frame:getParent().args.mode or ""
if mode == "simple" then
return p.simple(frame)
elseif mode == "args" then
return p.fromArgs(frame)
elseif mode == "parse" then
return p.parse(frame)
elseif mode == "json" then
return p.json(frame)
else
return "Greška: nepoznat način rada. Koristi mode=simple, args, parse ili json."
end
end
return p