Module:NPO Radio 2 Top 2000
Deze module gebruikt de volgende sjablonen: |
Deze module maakt gebruik van de volgende Wikidata-eigenschap:
|
Deze module maakt gebruik van data afkomstig uit Module:NPO Radio 2 Top 2000/data. |
Deze module maakt gebruik van TemplateStyles: |
Module:NPO Radio 2 Top 2000
[brontekst bewerken]Deze module wordt gebruikt om tabellen aan te maken voor noteringen in de NPO Radio 2 Top 2000, een eindejaarslijst die sinds 1999 jaarlijks een week lang non-stop wordt uitgezonden op radio, televisie en internet.
Input
[brontekst bewerken]Argumenten
[brontekst bewerken]De module moet worden aangeroepen via het sjabloon {{Tabel NPO Radio 2 Top 2000}}.
Twee verplichte argumenten worden bepaald door het sjabloon: het argument bezig
(ja/nee) en laatste_editie
(jaartal: xxxx). De eerste geeft aan of er op dit moment gewerkt wordt aan het verwerken van nieuwe noteringen, de tweede is het jaartal van de recentste lijst, bij bezig=ja
is dat het jaartal van de nieuwe lijst.
Daarnaast zijn er twee optionele argumenten die meegegeven kunnen worden aan het sjabloon: qid
(Wikidata-ID: Qxxxx of lijst van Wikidata-ID's gescheiden door komma's: Qxxxx,Qxxxx,Qxxxx) en artiesten
(ja/nee). Eerstgenoemde kent twee mogelijkheden: één Wikidata-ID behorend bij een artiest met noteringen in de hitlijst óf één of meerdere Wikidata-ID's behorend bij nummers met noteringen in de hitlijst (ongeacht of ze van dezelfde artiest zijn). Met het argument artiesten
kan worden aangegeven of achter de titel van het nummer de medeartiesten getoond moeten worden, iets wat alleen bepaald kan worden als een tabel wordt gemaakt voor de noteringen van een of meerdere nummers. In het geval van een tabel van alle nummers met noteringen van een artiest, worden medeartiesten standaard getoond, alsmede wanneer het sjabloon op Lijst van Radio 2-Top 2000's wordt aangeroepen (wat niet kan door limitaties in de Wikimedia-software).
Databestand
[brontekst bewerken]De daadwerkelijk gebruikte data staat opgeslagen in het databestand: Module:NPO Radio 2 Top 2000/data. Zie die pagina voor uitleg over de structuur van de data en definities van de verschillende kenmerken.
Werking
[brontekst bewerken]De module bestaat uit vier functies. De functie main is de enige aan te roepen functie, de lokale functie Top2000table wordt door eerstgenoemde aangeroepen. Daarnaast zijn er de lokale functies get_coartists en get_link. De moduleargumenten hebben in de module een andere naam: bezig=wip
en laatste_editie=last_edition_year
, alsmede een van de sjabloonargumenten: artiesten=show_artists
.
main
[brontekst bewerken]De functie main begint met de definitie van de twee verplichte argumenten en het definiëren van enkele strings. Daarna wordt het argument qid
omgezet in een lijst met Wikidata-ID's (al dan niet met de lengte 1) of, als dat argument niet was opgegeven, is de enige Wikidata-ID die van de Wikidata-pagina gekoppeld aan de pagina waarvandaan het sjabloon wordt aangeroepen. Wat vervolgens gebeurt, verschilt per situatie:
- Als de lijst lengte 1 heeft en die ene Wikidata-ID hoort bij een nummer met noteringen in het databestand, dan wordt een tabel gemaakt met de noteringen van dat nummer.
- Als de lijst lengte 1 heeft en die ene Wikidata-ID hoort bij een artiest met nummers met noteringen in het databestand, dan wordt een tabel gemaakt met de noteringen van die nummers.
- Als de lijst een lengte langer dan 1 heeft en al die Wikidata-ID's horen bij een nummer met noteringen in het databestand, dan wordt een tabel gemaakt met de noteringen van die nummers.
- Is geen van deze drie opties het geval, dan wordt een gepaste foutmelding geretourneerd. Pagina's met foutmeldingen komen terecht in Categorie:Wikipedia:Foutmelding NPO Radio 2 Top 2000.
Er is in de code eigenlijk nog een vierde optie, dat is het aanroepen van het sjabloon op de pagina Lijst van Radio 2-Top 2000's, waarbij de lijst met Wikidata-ID's leeg zou kunnen blijven. Het idee is dat de tabel dan een tabel maakt met alle nummers erin, maar vanwege limitaties in de Wikimedia-software werkt dit niet.
Top2000table
[brontekst bewerken]Deze functie creëert een tabel. Van de functie main krijgt deze functie drie relevante argumenten:
keys
: een lijst met Wikidata-ID's van de nummers die in de tabel komen te staan.data
: een lijst met dataobjecten van die nummers, afkomstig uit het databestand.artist_qid
: de Wikidata-ID van de artiest (alleen in het geval van optie 2 hierboven, of in het geval van de niet-werkende optie 4 de string list).
Op basis van dit laatste argument onderscheidt deze functie drie soorten tabellen: een nummertabel (artist_qid
is leeg), een artiestentabel (artist_qid
is een Wikidata-ID) of de volledige lijst (artist_qid
is lijst). Als er maar één nummer is met één notering, wordt geen tabel maar een simpele zin geretourneerd. In het geval van een artiestentabel is het nummer gelinkt, verder hangt de precieze output af van de waarde van wip
in combinatie met het jaartal van die ene notering en een eventueel titelextra
-veld, afkomstig uit het databestand.
Vervolgens wordt een dictionary gemaakt met de jaartallen waarin minstens een van de nummers in de aan te maken tabel een notering had. Daarna wordt het title
-veld in data
uitgebreid met eventuele titelextra en wordt voor ieder nummer de hoogste notering (laagste waarde) opgeslagen in een nieuw veld highest_position
.
Daarop volgt het meest geavanceerde deel van de code, het aanmaken van de tabelinhoud. Jaren waarin geen enkel van de beschouwde nummers een notering had, krijgen ook een kolom, maar worden waar mogelijk gecombineerd met aangrenzende jaren zonder noteringen. Nummers zonder noteringen in bepaalde jaren of in zogenoemde tussenjaren (waarin geen enkel nummer een notering had) krijgen een kruisje (×) als ze toen nog niet uitgebracht waren en een streepje (-) als het nummer al wel bestond. Bij aangrenzende tussenjaren (die dus een kolom delen) wordt hiervoor gekeken naar het laatste jaar in die periode. Er wordt voor gezorgd dat iedere hoogste notering dikgedrukt wordt gemaakt. Als er aan de huidige editie gewerkt wordt (wip=ja
), wordt een kolom met vraagtekens toegevoegd, al dan niet voorafgegaan door een of meerdere tussenjaren. Al wel bekende noteringen uit de laatste editie worden dan al wel ingevuld, bijvoorbeeld die in de top 10 die al een week eerder bekend is dan de rest van de lijst.
Het aanmaken van de tabelinhoud wordt afgesloten met het opsommen van de medeartiesten voor ieder nummer, waarvoor gebruik wordt gemaakt van de functie get_coartists. Ten slotte wordt alle tabelinhoud achter elkaar gezet (titel, medeartiesten en posities met sterretjes, streepjes en vraagtekens) zodat een deel van de daadwerkelijke tabel ontstaat. Als laatste worden noten toegevoegd, waar relevant, die uitleg bevatten over de betekenis van streepjes, kruisjes en vraagtekens. Als er niet direct noteringen waren in de eerste editie (1999), wordt bij de eerste kolom in de tabel (behorend bij het eerste jaar met noteringen) hierover een noot getoond. Ook komt er een noot over het jaar van de laatste update van de tabel, indien er in de tabel geen noteringen zijn in de laatste editie (last_edition_year
) (wat ook het geval kan zijn met wip=ja
op een nummerpagina als geen van de nummers in de nieuwe editie een notering had). Ten slotte wordt de hele tabel in elkaar gezet, inclusief kopcellen, noten en referentielijst en wordt dit als resultaat geretourneerd.
get_coartists
[brontekst bewerken]Deze functie somt de medeartiesten van een bepaald nummer op, waarbij deze alleen genoemd worden in het geval van een artiestentabel, de volledige lijst of een nummertabel met artiesten=ja
. Er wordt niet gelinkt bij een nummertabel. In het geval van een artiestentabel wordt de artiest in kwestie niet getoond, maar wordt/worden de medeartiest(en) voorafgegaan door "met".
get_link
[brontekst bewerken]Als er een link naar een ander artikel aangemaakt moet worden, wordt deze functie gebruikt. Als het maken van de link, wat gebeurt met gegevens uit Wikidata, niet goed lukt, wordt teruggevallen op de label (in een andere taal) en wordt de pagina toegevoegd aan de categorie met foutmeldingen.
local p = {}
function p.main(frame)
wip = frame.args.bezig
last_edition_year = tonumber(frame.args.laatste_editie)
local t_args = frame:getParent().args
show_artists = t_args.artiesten
table_start_1 = frame:extensionTag{ name = 'templatestyles', args = { src = "Sjabloon:Tabel Radio 2 Top 2000/styles.css" } } .. '\n{| class="wikitable'
table_start_2 = '" style="margin: 0.2em 0 0.2em 0; font-size:85%; text-align:center;"\n! max-width="220" | Nummer'
table_start_3 = ' met noteringen<br />in de [[Top 2000 (Nederland)|NPO Radio 2 Top 2000]]'
noot_wip = ' Een \'?\' betekent dat de notering nog niet is verwerkt.'
noot_symbols_1 = 'Een getal geeft de notering aan'
noot_symbols_hyphen = ', een \'-\' betekent dat het nummer niet was genoteerd'
noot_symbols_cross = ', een \'×\' betekent dat het nummer nog niet was uitgebracht'
noot_symbols_2 = ' en een vetgedrukt getal geeft de hoogste notering '
cat_error_link = '[[Categorie:Wikipedia:Foutmelding NPO Radio 2 Top 2000]]'
local list_page_name = 'Gebruiker:Ennomien/Kladblok2'--'Lijst van Radio 2-Top 2000\'s'
local qid = t_args.qid or mw.wikibase.getEntityIdForCurrentPage()
local qids = qid and mw.text.split(qid, ',') or ''
if qids[#qids] == '' then qids[#qids] = nil end
local data = require('Module:NPO Radio 2 Top 2000/data')
-- het sjabloon voor de totaallijst aanroepen op "Lijst van Radio 2-Top 2000's" werkt niet, het maken van de tabel is te complex
if mw.title.getCurrentTitle().prefixedText == list_page_name then
local keys, all_data = data.all()
keysn = {}
all_datan = {}
for i=3000,#all_data do
table.insert(keysn, keys[i])
table.insert(all_datan, all_data[i])
end
ok, result = pcall(Top2000table, frame, keysn, all_datan, 'list')
elseif #qids > 0 then
local song_data = {}
local unknown_songs = {}
for k,v in ipairs(qids) do
local song = data.get({ qid=v })
if song == nil then
table.insert(unknown_songs, '[[d:' .. v .. '|' .. v .. ']]')
end
table.insert(song_data, song)
end
if #song_data == #qids then
ok, result = pcall(Top2000table, frame, qids, song_data)
elseif #qids > 1 then
local diff = #qids - #song_data
local plural = diff > 1
if #song_data == 0 then diff = 'alle' end
message = 'Van ' .. diff .. ' van de opgegeven nummers zijn geen noteringen in de NPO Radio 2 Top 2000 bekend. Weet wel dat het opgeven van meerdere artiesten of een combinatie van nummers en artiesten niet geldig is, omdat dat geen logische tabel geeft. Het opgeven van meerdere nummers kan daarentegen wel. ' .. (plural and 'Wikidata-ID\'s die' or 'De Wikidata-ID die') .. ' de module niet herkende: ' .. table.concat(unknown_songs, ', ') .. '.' .. (wip == 'ja' and ' Voeg dit sjabloon pas toe als de noteringen van de nieuwe editie verwerkt zijn.' or '')
else
artist_qid = qids[1]
local keys, artist_data = data.find_artist({ qid=artist_qid })
if #artist_data > 0 then
ok, result = pcall(Top2000table, frame, keys, artist_data, artist_qid)
else
message = 'Van deze artiest of dit nummer ([[d:' .. artist_qid .. '|' .. artist_qid .. ']]) zijn geen noteringen in de NPO Radio 2 Top 2000 bekend.' .. (wip == 'ja' and ' Voeg dit sjabloon pas toe als de noteringen van de nieuwe editie verwerkt zijn.' or '')
end
end
else
message = 'Zorg dat je dit sjabloon alleen aanroept op een pagina gekoppeld aan Wikidata, of geef zelf een Wikidata-ID mee (zie [[Sjabloon:Tabel NPO Radio 2 Top 2000|uitleg]]).'
end
if result then
if ok == true then
return result
else
return frame:expandTemplate{ title='Error', args={'De module gaf een foutmelding:<br />' .. result .. cat_error_link} }
end
else
return message .. cat_error_link
end
end
function Top2000table(frame, keys, data, artist_qid)
page = artist_qid == 'list' and 'list' or artist_qid and 'artist' or 'song'
local one_song = #data == 1
local last_edition_index = last_edition_year - 1999 + 1
-- als er maar sprake is van één nummer met één notering
if one_song then
local in_list = 0
for k,v in ipairs(data[1].posities) do
if v ~= 0 then
in_list = in_list + 1
index = k
end
end
if in_list == 1 then
if page == 'song' then
title = mw.wikibase.getLabel(keys[1])
else
title = get_link(frame, keys[1])
end
title = '\'\'' .. title .. '\'\''
if data[1].titelextra then title = title .. ' (' .. data[1].titelextra .. ')' end
title = title .. get_coartists(frame, data[1])
local year = 1999 + index - 1
if page == 'song' then
if year == last_edition_year then
result_2 = title .. ' stond in ' .. year .. ' voor het eerst'
else
result_2 = title .. ' stond alleen in ' .. year
end
else
result_2 = 'Van deze artiest stond alleen ' .. title .. ' in ' .. year
end
result = result_2 .. ' in de [[Top 2000 (Nederland)|NPO Radio 2 Top 2000]], op plek ' .. data[1].posities[index] .. '.'
if wip == 'ja' and page == 'artist' then
if data[1].posities[last_edition_index] ~= nil then
result = result .. ' De noteringen van ' .. last_edition_year .. ' voor eventuele andere nummers zijn nog niet verwerkt.'
else
result = result .. ' De noteringen van ' .. last_edition_year .. ' voor dit nummer en eventuele andere nummers zijn nog niet verwerkt.'
end
elseif wip == 'ja' and data[1].posities[last_edition_index] == nil then
result = result .. ' De noteringen van ' .. last_edition_year .. ' zijn nog niet verwerkt.'
end
return result
end
end
-- uitzoeken bij welke jaren er een of meer noteringen waren
local years_listed = {}
local minus_one = wip == 'ja' and 1 or 0
for year=1999, last_edition_year - minus_one do
local index = year - 1999 + 1
for k,v in ipairs(data) do
if v.posities[index] ~= 0 then
years_listed[year] = true
break
end
end
end
-- voor ieder nummer de al dan niet gelinkte titel maken (met eventuele titelextra), de hoogste notering berekenen en uitzoeken of de notering in een eventueel wip-jaar al is verwerkt
local last_edition_column = page ~= 'song'
for k,v in ipairs(data) do
v.positions = ''
if page == 'song' then
v.title = mw.wikibase.getLabel(keys[k])
elseif page == 'list' then
v.title = v.titel
else
v.title = get_link(frame, keys[k])
end
v.title = '\'\'' .. v.title .. '\'\''
if v.titelextra then v.title = v.title .. ' (' .. v.titelextra .. ')' end
local positions_greater_zero = {}
for i,w in ipairs(v.posities) do
if w ~= 0 then
table.insert(positions_greater_zero, w)
end
end
v.highest_position = math.min(unpack(positions_greater_zero))
if v.posities[last_edition_index] == nil or v.posities[last_edition_index] and v.posities[last_edition_index] ~= 0 then
last_edition_column = true
end
end
local first_year = true
local last_year = 1999
local interval = 0
local years = ''
-- de tabelinhoud maken
for year=1999, last_edition_year do
year_listed = years_listed[year]
-- als een of meerdere nummers dit jaar een notering hadden
if year_listed then
last_year = year
-- als in het geheugen nog een aantal "tussenjaren" > 0 zit (en deze niet vóór de allereerste notering zijn), moet er eerst nog een lege kolom toegevoegd worden
if interval > 0 and first_year == false then
years = years .. '!! data-sort-type="number" | \'' .. mw.ustring.sub(year - interval, 3, 4)
-- als het aantal tussenjaren groter dan 1 was, doe dan x-y ipv alleen x
if interval > 1 then
years = years .. '-\'' .. mw.ustring.sub(year - 1, 3, 4)
end
-- een lege kolom toevoegen, dus voor ieder nummer een streepje of kruisje (voor de bepaling hiervan wordt het laatste tussenjaar gebruikt, een streepje krijgt dus "voorrang" op een kruisje)
for k,v in ipairs(data) do
if year - 1 >= v.eerstmogelijkejaar then
add = '-'
hyphen = true
else
add = '×'
cross = true
end
v.positions = v.positions .. '||' .. add
end
end
-- het jaar toevoegen aan de rij met jaren
years = years .. '!! data-sort-type="number" | \'' .. mw.ustring.sub(year, 3, 4)
-- als dit het eerste jaar met notering is en niet de eerste Top 2000-editie (1999), voeg een opmerking toe
if first_year and year > 1999 then
-- als een artiest maar één nummer in de Top 2000 had, klinkt "dit nummer" beter
if one_song then word = 'dit nummer'
elseif page == 'artist' then word = 'deze artiest'
else word = 'een van deze nummers' end
first_year_noot = year .. ' was het eerste jaar met een notering voor ' .. word .. '.'
years = years .. 'first_year_noot_placeholder'
end
first_year = false
interval = 0
-- voor ieder nummer de juiste notering toevoegen, mits die er is (niet 0 is), anders een streepje of kruisje
local index = year - 1999 + 1
for k,v in ipairs(data) do
local add = year >= v.eerstmogelijkejaar and '-' or '×'
position = v.posities[index]
if position ~= 0 then
add = position
if position == v.highest_position then
add = '\'\'\'' .. position .. '\'\'\''
end
end
if add == '-' then hyphen = true end
if add == '×' then cross = true end
v.positions = v.positions .. '||' .. add
end
-- als geen nummer een notering had, wordt het aantal tussenjaren vermeerderd met 1
else
interval = interval + 1
end
end
-- als aan de huidige editie wordt gewerkt, komt er een kolom met vraagtekens en al bekende noteringen bij (tenzij van alle nummers bekend is dat ze niet in de huidige editie voorkomen en het een nummertabel betreft)
if wip == 'ja' and last_edition_column then
for k,v in ipairs(data) do
-- als er een editie tussen de huidige editie en de recentste editie met een genoteerd nummer zit, voeg dan eerst nog een lege kolom toe (er komt dan nog een kolom met tussenjaren)
if last_year + 1 ~= last_edition_year then
v.positions = v.positions .. '||' .. '-'
hyphen = true
end
-- misschien zijn voor dit nieuwe jaar de noteringen (of geen notering: 0) voor sommige nummers al bekend, voeg die dan wel toe
local wip_position = v.posities[last_edition_index]
if wip_position and wip_position ~= 0 then
add = wip_position
if wip_position == v.highest_position then
add = '\'\'\'' .. wip_position .. '\'\'\''
end
elseif wip_position == 0 then
add = '-'
hyphen = true
else
add = '?'
question_mark = true
end
v.positions = v.positions .. '||' .. add
end
-- als er een kolom tussenjaren moet komen
if last_year + 1 ~= last_edition_year then
-- de juiste jaartallen daarvoor berekenen en als het aantal tussenjaren groter dan 1 is, doe dan x-y ipv alleen x
years = years .. '!! data-sort-type="number" | \'' .. mw.ustring.sub(last_year + 1, 3, 4)
if last_year + 1 ~= last_edition_year - 1 then
years = years .. '-\'' .. mw.ustring.sub(last_edition_year - 1, 3, 4)
end
end
-- het jaar van de aankomende editie toevoegen aan de rij met jaren
years = years .. '!! data-sort-type="number" | \'' .. mw.ustring.sub(last_edition_year, 3, 4)
end
-- de titels van de tabelrijen sorteren op alfabet
table.sort(data, function(a, b) return a.title:gsub("[%(.']", ""):gsub("É", "E"):gsub("Ç", "C"):lower() < b.title:gsub("[%(.']", ""):gsub("É", "E"):gsub("Ç", "C"):lower() end)
local content = ''
-- eventuele medeartiesten toevoegen
for k,v in ipairs(data) do
coartists = get_coartists(frame, v)
-- de tabelrijen aan elkaar toevoegen
content = content .. '\n|-\n|' .. v.title .. coartists .. v.positions
end
-- de cel linksboven aanmaken met gebruik van meervoud als er meerdere nummers zijn
local table_start = table_start_1 .. (one_song and '' or ' sortable top2000') .. table_start_2 .. (one_song and '' or 's') .. table_start_3
-- alleen de relevante uitleg geven in de noot
local noot_symbols = frame:expandTemplate{ title='Refn', args={noot_symbols_1 .. (hyphen and noot_symbols_hyphen or '') .. (cross and noot_symbols_cross or '') .. noot_symbols_2 .. (not one_song and 'van een nummer ' or '') .. 'aan.' .. (question_mark and noot_wip or ''), group='noot', name='T2000'} }
-- als er een noot is over het eerste jaar met een notering, wordt die hier pas toegevoegd (vanwege referentievolgorde)
if first_year_noot then
years = years:gsub('first_year_noot_placeholder', frame:expandTemplate{ title='Refn', args={first_year_noot, group='noot'} })
end
-- als de laatste Top 2000-editie niet voorkomt in de tabel (als er aan de huidige editie wordt gewerkt ook niet als het een nummertabel is en geen van de nummers een notering in die editie heeft), wordt een noot toegevoegd over de laatste keer dat de tabel is bijgewerkt
if not last_edition_column then
years = years .. frame:expandTemplate{ title='Refn', args={'Deze tabel is bijgewerkt tot de laatste editie (' .. last_edition_year .. ').', group='noot'} }
end
local table_end = '\n|}\n' .. frame:expandTemplate{ title='References', args={'85%', group='noot'} }
return table_start .. noot_symbols .. years .. content .. table_end
end
function get_coartists(frame, data)
local coartists = ''
local add = nil
-- alleen (mede)artiesten toevoegen als het een artiestenpagina betreft en er meerdere artiesten zijn of als de sjabloonparameter "artiesten" (alleen op een nummerpagina) de waarde "ja" heeft of als de grote lijst wordt aangemaakt
if page == 'artist' and #data.artiest > 1 or page == 'song' and show_artists == 'ja' or page == 'list' then
coartists = ' ('
local added = false
if #data.artiest > 1 then
if page == 'artist' then coartists = coartists .. 'met ' end
-- iedere artiest van het nummer langsgaan en toevoegen, mits niet de "eigen" artiest (in het geval van een artiestenpagina)
for i,w in ipairs(data.artiest) do
if w ~= artist_qid then
if added then coartists = coartists .. ', ' end
-- het toevoegen van de medeartiesten loopt als het ware één achter, omdat van tevoren niet bekend is of de laatste in de lijst de "eigen" artiest is, maar vóór de laatste artiest wel een & ipv , moet staan
if add then
coartists = coartists .. add
added = true
end
-- bij een nummerpagina de artiest niet linken, bij een artiestenpagina of de grote lijst wel
if page == 'song' then
add = mw.wikibase.getLabel(w)
elseif page == 'list' then
add = w
else
add = get_link(frame, w)
end
end
end
if added then coartists = coartists .. ' & ' end
-- in het geval van een nummerpagina en artiesten=ja met maar één artiest of de grote lijst met maar één artiest
else
if page == 'song' then
add = mw.wikibase.getLabel(data.artiest[1])
elseif page == 'list' then
add = data.artiest[1]
else
add = get_link(frame, data.artiest[1])
end
end
coartists = coartists .. add .. ')'
end
return coartists
end
function get_link(frame, qid)
local link = frame:expandTemplate{ title='Wikidata', args={'label', 'short', 'linked', qid} }
if link ~= '' then
return link
else
label = mw.wikibase.getLabel(qid)
return label .. cat_error_link
end
end
return p