Moduł:Parser wikiprojektów
Moduł służy do wyświetlania spisu wikiprojektów w sposób czytelny dla osób nietechnicznych. Wczytuje listę w formacie JSON ze strony Wikipedia:Wikiprojekt/Spis wikiprojektów.json.
Moduł eksportuje jedną bezargumentową funkcję: Lista
, odpowiedzialną za wczytanie, przetworzenie i wyświetlenie listy. Sposób wywołania:
{{#invoke:Parser wikiprojektów|Lista}}
Powyższy opis jest dołączany ze strony Moduł:Parser wikiprojektów/opis. (edytuj | historia)
Zobacz podstrony tego modułu.
Zobacz podstrony tego modułu.
-- Definiuje kolejność sekcji z dziedzinami
-- oraz dopuszczalne dziedziny
-- Nierozpoznane jest na pierwszym miejscu, aby zwracać uwagę
local projectCategoryUnknown = 'Nierozpoznane'
local standardProjectCategories = {
projectCategoryUnknown,
'Nauki ścisłe i przyrodnicze',
'Nauki społeczne i humanistyczne',
'Społeczeństwo',
'Geografia',
'Polska',
'Kultura',
'Sport',
'Technika'
}
-- Lua sortuje stringi jakby to były ciągi bajtów,
-- więc trzeba zdefiniować klucz sortowania składający się tylko z ASCII
function createSortKey(name)
local replacements = {
['ą'] = 'azz',
['ć'] = 'czz',
['ę'] = 'ezz',
['ł'] = 'lzz',
['ń'] = 'nzz',
['ó'] = 'ozz',
['ś'] = 'szz',
['ź'] = 'zzy',
['ż'] = 'zzz',
['Ą'] = 'AZZ',
['Ć'] = 'CZZ',
['Ę'] = 'EZZ',
['Ł'] = 'LZZ',
['Ń'] = 'NZZ',
['Ó'] = 'OZZ',
['Ś'] = 'SZZ',
['Ź'] = 'ZZY',
['Ż'] = 'ZZZ'
}
name = mw.ustring.gsub(name, '%a', replacements)
return name
end
-- Uzupełnia opcjonalne pola
function normalizeWikiproject(wikiproject)
wikiproject['name_sortkey'] = createSortKey(wikiproject['name'])
if wikiproject['page'] == nil then
wikiproject['page'] = 'Wikiprojekt:' .. wikiproject['name']
end
if wikiproject['talk'] == nil then
wikiproject['talk'] = 'Dyskusja wikiprojektu:' .. wikiproject['name']
end
if wikiproject['report_link'] == nil then
wikiproject['report_link'] = 'Specjalna:Nowa_sekcja/' .. wikiproject['talk']
end
if wikiproject['join'] ~= nil then
wikiproject['join'] = string.gsub(wikiproject['join'], ' ', '_')
end
if wikiproject['portal_page'] == nil and wikiproject['portal_name'] ~= nil then
if type(wikiproject['portal_name']) == 'string' then
wikiproject['portal_page'] = 'Portal:' .. wikiproject['portal_name']
else
wikiproject['portal_page'] = {}
for i, portal_name in ipairs(wikiproject['portal_name']) do
table.insert(wikiproject['portal_page'], 'Portal:' .. portal_name)
end
end
end
if type(wikiproject['portal_name']) == 'string' then
wikiproject['portal_name'] = { wikiproject['portal_name'] }
wikiproject['portal_page'] = { wikiproject['portal_page'] }
end
if wikiproject['portal_name'] == nil then
wikiproject['portal_name'] = {}
wikiproject['portal_page'] = {}
end
if wikiproject['category_leader'] == nil then
wikiproject['category_leader'] = false
end
if wikiproject['children'] == nil then
wikiproject['children'] = {}
end
for i, child in ipairs(wikiproject['children']) do
normalizeWikiproject(child)
end
end
-- Dzieli projekty na aktywne i nieaktywne
function groupByActivity(wikiprojects)
local active = {}
local inactive = {}
for i, wikiproject in ipairs(wikiprojects) do
if wikiproject['active'] then
table.insert(active, wikiproject)
else
table.insert(inactive, wikiproject)
end
end
return active, inactive
end
-- Grupuje projekty według typów
function groupByType(wikiprojects)
local result = {}
for i, wikiproject in ipairs(wikiprojects) do
if result[wikiproject['type']] == nil then
result[wikiproject['type']] = {}
end
table.insert(result[wikiproject['type']], wikiproject)
end
return result
end
-- Grupuje projekty według dziedziny wiedzy (kategorii)
function groupByCategory(wikiprojects)
local grouped = {}
local noGroup = projectCategoryUnknown
for i, wikiproject in ipairs(wikiprojects) do
-- Sprawdź, czy wikiprojekt jest w zdefiniowanej kategorii
local isKnownCategory = false
for j, category in ipairs(standardProjectCategories) do
if wikiproject['category'] == category then
isKnownCategory = true
break
end
end
if not isKnownCategory then
wikiproject['category'] = nil
end
-- Przypisz do podtabeli odpowiedniej dla kategorii
if wikiproject['category'] ~= nil then
if grouped[wikiproject['category']] == nil then
grouped[wikiproject['category']] = {}
end
table.insert(grouped[wikiproject['category']], wikiproject)
else
if grouped[noGroup] == nil then
grouped[noGroup] = {}
end
table.insert(grouped[noGroup], wikiproject)
end
end
return grouped
end
function sortWikiprojects(wikiprojects)
table.sort(wikiprojects, function(a, b)
if a['category_leader'] ~= b['category_leader'] then
if a['category_leader'] then
return true
else
return false
end
end
if a['active'] ~= b['active'] then
-- Nieaktywny jest oznaczany jako false,
-- Aktywne mogą mieć stringa lub true
if not b['active'] then
return true
end
if not a['active'] then
return false
end
end
return a['name_sortkey'] < b['name_sortkey']
end)
for i, wikiproject in ipairs(wikiprojects) do
if wikiproject['children'] ~= nil then
sortWikiprojects(wikiproject['children'])
end
end
end
-- Tworzy tabelę dla wikiprojektów
function buildTable(wikiprojects, isActive, headerFunction, rowFunction, width)
sortWikiprojects(wikiprojects)
local tbl = mw.html.create('table')
tbl:addClass('wikitable')
:addClass('sortable')
:css('width', width)
if not isActive then
tbl:addClass('mw-collapsible')
:addClass('mw-collapsed')
end
tbl:node(headerFunction(isActive))
for i, wikiproject in pairs(wikiprojects) do
local rows = rowFunction(wikiproject, 0, isActive)
for i, row in pairs(rows) do
tbl:node(row)
end
end
return tbl
end
-- =============================================================
-- OBSŁUGA ZWYKŁYCH WIKIPROJEKTÓW
-- =============================================================
-- Tworzy nagłówek tabeli dla zwykłych wikiprojektów
function buildTableHeaderForStandard(isActive)
local header = mw.html.create('tr')
header:node(mw.html.create('th'):attr('width', '25%')
:wikitext('Projekt (strona główna)'))
if isActive then
header:node(mw.html.create('th'):addClass('unsortable'):attr('width', '20%')
:wikitext('Koordynacja działań (dyskusja)'))
header:node(mw.html.create('th'):addClass('unsortable'):attr('width', '20%')
:wikitext('Uczestnicy'))
end
header:node(mw.html.create('th'):attr('width', '10%')
:wikitext('Data założenia'))
header:node(mw.html.create('th'):addClass('unsortable'):attr('width', '25%')
:wikitext('Powiązane portale'))
return header
end
-- Tworzy wiersz tabeli dla zwykłych wikiprojektów oraz wiersze dla projektów "potomnych"
function buildTableRowsForStandard(wikiproject, childLevel, isActive)
local tr = mw.html.create('tr')
local paddingLeft = nil
if childLevel > 0 then
paddingLeft = (1.5 * childLevel) .. 'em'
end
if wikiproject['users'] == nil then
wikiproject['users'] = '|<b style="color:red;">Brakuje strony: </b>'
end
tr:node(mw.html.create('th'):wikitext(
'[[' .. wikiproject['page'] .. '|' .. wikiproject['name'] .. ']]'
):attr('scope', 'row'):css('padding-left', paddingLeft):css('text-align', 'left'))
if isActive then
tr:node(mw.html.create('td'):wikitext(
'[[' .. wikiproject['talk'] .. '|(Dyskusja)]] → [[' .. wikiproject['report_link'] .. '|zgłoś problem]]'
))
if wikiproject['join'] ~= nil then
tr:node(mw.html.create('td'):wikitext(
'[[' .. wikiproject['users'] .. '|Uczestnicy]] → [' .. wikiproject['join'] .. ' zapisz się]'
):addClass('plainlinks'))
else
tr:node(mw.html.create('td'):wikitext(
'[[' .. wikiproject['users'] .. '|Uczestnicy → zapisz się]]'
))
end
end
tr:node(mw.html.create('td'):wikitext(
wikiproject['started']
))
local portalsWikitext = ''
if #wikiproject['portal_page'] == 1 then
portalsWikitext = portalsWikitext .. '[[' .. wikiproject['portal_page'][1] .. '|' .. wikiproject['portal_name'][1] .. ']]'
else
for i = 1, #wikiproject['portal_page'] do
if i > 1 then
portalsWikitext = portalsWikitext .. '<br/>'
end
portalsWikitext = portalsWikitext .. '[[' .. wikiproject['portal_page'][i] .. '|' .. wikiproject['portal_name'][i] .. ']]'
end
end
tr:node(mw.html.create('td'):wikitext(
portalsWikitext
))
local rowsList = { tr }
if #wikiproject['children'] > 0 then
for i, child in pairs(wikiproject['children']) do
childRows = buildTableRowsForStandard(child, childLevel + 1, isActive)
for i, row in pairs(childRows) do
table.insert(rowsList, row)
end
end
end
return rowsList
end
-- =============================================================
-- OBSŁUGA WIKIPROJEKTÓW SPECJALNYCH
-- =============================================================
-- Tworzy nagłówek tabeli dla wikiprojektów specjalnych
function buildTableHeaderForSpecial(isActive)
local header = mw.html.create('tr')
header:node(mw.html.create('th'):wikitext('Projekt (strona główna)'))
if isActive then
header:node(mw.html.create('th'):wikitext('Koordynacja działań (dyskusja)'):addClass('unsortable'))
end
header:node(mw.html.create('th'):wikitext('Data założenia'))
return header
end
-- Tworzy wiersz tabeli dla wikiprojektów specjalnych oraz wiersze dla ew. projektów "potomnych"
function buildTableRowsForSpecial(wikiproject, childLevel, isActive)
local tr = mw.html.create('tr')
local paddingLeft = nil
if childLevel > 0 then
paddingLeft = (1.5 * childLevel) .. 'em'
end
tr:node(mw.html.create('th'):wikitext(
'[[' .. wikiproject['page'] .. '|' .. wikiproject['name'] .. ']]'
):attr('scope', 'row'):css('padding-left', paddingLeft):css('text-align', 'left'))
if isActive then
tr:node(mw.html.create('td'):wikitext(
'[[' .. wikiproject['talk'] .. '|(Dyskusja)]] → [[' .. wikiproject['report_link'] .. '|zgłoś problem]]'
))
end
tr:node(mw.html.create('td'):wikitext(
wikiproject['started']
))
local rowsList = { tr }
if #wikiproject['children'] > 0 then
for i, child in pairs(wikiproject['children']) do
childRows = buildTableRowsForSpecial(child, childLevel + 1, isActive)
for i, row in pairs(childRows) do
table.insert(rowsList, row)
end
end
end
return rowsList
end
-- =============================================================
-- OBSŁUGA WIKIPROJEKTÓW INSTYTUCJONALNYCH
-- =============================================================
-- Tworzy nagłówek tabeli dla wikiprojektów instytucjonalnych
function buildTableHeaderForInstitutional(isActive)
local header = mw.html.create('tr')
header:node(mw.html.create('th'):wikitext('Projekt (strona główna)'))
header:node(mw.html.create('th'):wikitext('Uczestnicy projektu'):addClass('unsortable'))
header:node(mw.html.create('th'):wikitext('Status'))
return header
end
-- Tworzy wiersz tabeli dla wikiprojektów specjalnych oraz wiersze dla ew. projektów "potomnych"
function buildTableRowsForInstitutional(wikiproject, childLevel, isActive)
local tr = mw.html.create('tr')
local paddingLeft = nil
if childLevel > 0 then
paddingLeft = (1.5 * childLevel) .. 'em'
end
if type(wikiproject['active']) == 'boolean' then
if wikiproject['active'] then
wikiproject['active'] = 'trwający'
else
wikiproject['active'] = 'zakończony'
end
end
tr:node(mw.html.create('th'):wikitext(
'[[' .. wikiproject['page'] .. '|' .. wikiproject['name'] .. ']]'
):attr('scope', 'row'):css('padding-left', paddingLeft):css('text-align', 'left'))
if wikiproject['users'] ~= nil then
if wikiproject['join'] ~= nil then
tr:node(mw.html.create('td'):wikitext(
'[[' .. wikiproject['users'] .. '|Uczestnicy]] → [' .. wikiproject['join'] .. ' zapisz się]'
):addClass('plainlinks'))
else
tr:node(mw.html.create('td'):wikitext(
'[[' .. wikiproject['users'] .. '|Uczestnicy → zapisz się]]'
))
end
else
tr:node(mw.html.create('td'))
end
tr:node(mw.html.create('td'):wikitext(
wikiproject['active']
))
local rowsList = { tr }
if #wikiproject['children'] > 0 then
for i, child in pairs(wikiproject['children']) do
childRows = buildTableRowsForInstitutional(child, childLevel + 1, isActive)
for i, row in pairs(childRows) do
table.insert(rowsList, row)
end
end
end
return rowsList
end
local p = {}
function p.Lista(frame)
local jsonPage = mw.title.new('Wikipedia:Wikiprojekt/Spis_wikiprojektów.json')
local wikiprojects = mw.text.jsonDecode(jsonPage:getContent())
for i, wikiproject in pairs(wikiprojects) do
normalizeWikiproject(wikiproject)
end
local output = {}
local activeProjects, inactiveProjects = groupByActivity(wikiprojects)
activeByType = groupByType(activeProjects)
standardByCategory = groupByCategory(activeByType['normal'])
table.insert(output, '== Aktywne wikiprojekty ==')
table.insert(output, '=== Według dziedzin wiedzy ===')
for i, category in ipairs(standardProjectCategories) do
projects = standardByCategory[category]
if projects ~= nil then
table.insert(output, '==== ' .. category .. ' ====')
table.insert(output, tostring(buildTable(
projects, true, buildTableHeaderForStandard, buildTableRowsForStandard, '100%'
)))
end
end
table.insert(output, '=== Wikiprojekty specjalne ===')
table.insert(output, 'Są to szczególne wikiprojekty, które od \'\'zwykłych\'\' odróżniają się tym, że nie są nastawione na merytoryczny rozwój [[Pomoc:Przestrzeń nazw#(główna)|przestrzeni głównej]].<br/>W większości są to \'\'metawikiprojekty\'\': koordynują działanie innych wikiprojektów lub zajmują się [[Pomoc:Słowniczek#M|metastronami]] Wikipedii (kategoriami, szablonami, plikami, zasadami Wikipedii, społecznością Wikipedii itd.).')
table.insert(output, tostring(buildTable(
activeByType['special'], true, buildTableHeaderForSpecial, buildTableRowsForSpecial, nil
)))
table.insert(output, '=== Wikiprojekty instytucjonalne ===')
table.insert(output, 'Tutaj znajdują się wikiprojekty, które współtworzone są formalnie przez zewnętrzne instytucje, przy wsparciu Stowarzyszenia Wikimedia Polska.')
table.insert(output, frame:expandTemplate{ title = 'Zobacz też', args = {'Wikipedia:Projekty szkolne i akademickie'}})
table.insert(output, tostring(buildTable(
activeByType['institutional'], true, buildTableHeaderForInstitutional, buildTableRowsForInstitutional, '100%'
)))
local inactiveByType = groupByType(inactiveProjects)
table.insert(output, '== Nieaktywne wikiprojekty ==')
table.insert(output, 'Poniższe wikiprojekty nie funkcjonują, a ich listy uczestników mogą być od dawna nieaktualne. Jeśli chcesz reaktywować któryś z nich, znajdź najpierw zespół wikipedystów, który będzie współpracował.\n\n; Jak to zrobić?\n* sprawdź, którzy z zapisanych uczestników są aktywni i czy nadal zajmują się przedmiotem zainteresowania wikiprojektu,\n* zaproś wikipedystów na nowych członków zespołu,\n* skreśl nieaktywnych wikipedystów i zarchiwizuj stare dyskusje,\n* o ile nowa grupa podejmie współpracę, wikiprojekt zyska nowe życie.')
table.insert(output, '=== Nieaktywne wikiprojekty zwykłe ===')
table.insert(output, tostring(buildTable(
inactiveByType['normal'], false, buildTableHeaderForStandard, buildTableRowsForStandard, '100%'
)))
table.insert(output, '=== Nieaktywne wikiprojekty specjalne ===')
table.insert(output, 'W odróżnieniu od \'\'zwykłych\'\' nieaktywnych wikiprojektów, które można wskrzesić, niektóre z poniższych są historyczne i ich aktywność nie jest już możliwa (np. [[Wikiprojekt:Sortowanie stubów|Wikiprojekt Sortowanie stubów]]).')
table.insert(output, tostring(buildTable(
inactiveByType['special'], false, buildTableHeaderForSpecial, buildTableRowsForSpecial, nil
)))
return table.concat(output, '\n')
end
return p