Module:Wd

Scoutpedia.nl, dé Scouting wiki
Ga naar:navigatie, zoeken
Informatiepictogram Wellicht wilt u gebruikmaken van de gebruiksvriendelijke wrapper-sjabloon {{Wikidata}} in plaats van deze module direct aan te roepen.

Deze module is bedoeld om data van Wikidata op te halen met of zonder link naar het gekoppelde Wikipedia-artikel en met vele andere opties.

Gebruik[brontekst bewerken]

De algemene structuur van een aanroep van deze module is als volgt. Merk op dat de basisstructuur bestaat uit positionele commando's, opties en argumenten, welke allemaal een vaste positie hebben.

{{#invoke:wd|commando1|optie1a|optie1b|optie1c|commando2|optie2a|optie2b|optie2c|optie0a|optie0b|optie0c|arg1|arg2|arg3}}

Gebruik verschillende commando's om verschillende soorten waardes op te halen van Wikidata. Minstens één commando moet worden opgegeven en meerdere commando's kunnen worden gecombineerd in één aanroep zoals hierboven is getoond (in willekeurige volgorde, meer dan twee is ook mogelijk), maar dit geldt alleen voor commando's uit de bewering-klasse; aanroepen die een commando bevatten uit de algemeen-klasse kunnen geen ander commando bevatten. Elk commando kan worden gevolgd door een willekeurig aantal commando-opties, welke optioneel zijn en kunnen worden gebruikt om de uitvoer die gegenereerd wordt door dat commando aan te passen.

De commando's en hun opties kunnen worden gevolgd door een willekeurig aantal configuratie-opties, welke ook optioneel zijn en de selectie van data en het algemene gedrag van deze module beïnvloeden. De aanroep wordt afgesloten met de positionele argumenten, welke al dan niet verplicht zijn afhankelijk van het opgegeven commando of de opgegeven commando's. Er bestaan tevens een aantal benoemde argumenten, evenals een verzameling benoemde opties voor geavanceerd gebruik die gebruikt kunnen worden om de manier aan te passen waarop opgehaalde waardes in de uitvoer worden samengevoegd.

Deze module is ontworpen om de basisbehoeften van het ophalen van data van Wikidata te verschaffen, maar veel kan worden bereikt middels verschillende combinaties van aanroepen. Voor het gemak zouden zulke combinaties kunnen worden samengebonden in nieuwe sjablonen die aan een specifieke behoefte voldoen. Zie ook de sectie over veelvoorkomende toepassingen hieronder voor een aantal voorbeelden van nuttige "bouwstenen". Op een soortgelijke manier kan de functionaliteit van deze module worden uitgebreid door het maken van wrapper-sjablonen die gebruikmaken van het commando main dat wordt geboden door deze module.

Veelvoorkomende toepassingen[brontekst bewerken]

Hieronder volgt een lijst van veelvoorkomende toepassingen. In de toekomst zouden er voor meer gemak plaatsvervangende commando's kunnen worden geïmplementeerd die equivalent zijn aan deze aanroepen.

Aanroep Toepassing
{{#invoke:wd|label|raw}} Retourneert het Q-nummer van het Wikidata-item dat gekoppeld is aan de huidige pagina (bijvoorbeeld "Q55").
{{#if:{{#invoke:wd|label|raw}}|...}} Voert een controle uit om te bepalen of de huidige pagina een Wikidata-item heeft.

Merk op dat deze bewering vertrouwt op een geretourneerde waarde die leeg dan wel niet leeg is en dat het belangrijk is om de optie raw op te geven. Zonder deze optie zou de gewone label van een bestaand item worden geretourneerd welke leeg kan zijn, wat een ongewenst resultaat oplevert. Als de optie daarentegen wel is opgegeven, dan wordt altijd een niet-leeg Q-nummer geretourneerd als een item bestaat en een lege waarde als een item niet bestaat.

Commando's[brontekst bewerken]

De commando's (commando1, commando2, ...) bepalen welke soorten waardes worden geretourneerd. Eén aanroep kan alleen commando's van een enkele klasse bevatten.

Bewering-klasse[brontekst bewerken]

De bewering-klasse-commando's kunnen worden gecombineerd, wat betekent dat meerdere commando's van verschillende types uit deze klasse tegelijkertijd kunnen worden opgegeven (zie hierboven voor gebruik).

Combineer meerdere commando's in één aanroep van deze module, in plaats van meerdere aanroepen van deze module te doen met elk één commando, om er zeker van te zijn dat alle geretourneerde stukken informatie bij elkaar horen (zie ook de onderstaande voorbeelden).

Type Commando Retourneert Basisgebruik Beschrijving
I property eerste overeenkomst* {{#invoke:wd|property|P1}} Retourneert de opgevraagde eigenschap (property) – of lijst van eigenschappen (properties) – van de huidige item-entiteit of van een opgegeven entiteit.

Dit commando kan slechts één keer worden opgegeven in een aanroep.

properties alle overeenkomsten {{#invoke:wd|properties|P1}}
II qualifier eerste overeenkomst** {{#invoke:wd|qualifier|P1|P2}} Retourneert de opgevraagde kwalificatie (qualifier) – of lijst van kwalificaties (qualifiers) – van de opgegeven eigenschap (property) van de huidige item-entiteit of van een opgegeven entiteit.

In tegenstelling tot de andere bewering-klasse-commando's kan dit commando meerdere keren in één aanroep opgegeven worden om verschillende kwalificaties op te halen.

qualifiers alle overeenkomsten {{#invoke:wd|qualifiers|P1|P2}}
III reference eerste overeenkomst** {{#invoke:wd|reference|P1}} Retourneert een bron (reference) – of lijst van bronnen (references) – van de opgegeven eigenschap (property) van de huidige item-entiteit of van een opgegeven entiteit.***

Dit commando kan slechts één keer worden opgegeven in een aanroep.

references alle overeenkomsten {{#invoke:wd|references|P1}}
* Retourneert slechts een enkele waarde in plaats van meerdere (als meerdere beweringen overeenkomen). De geretourneerde waarde is de eerste overeenkomst die gevonden is uit de beweringen met de beste rang.
** Retourneert slechts een enkele waarde in plaats van meerdere voor elke overeenkomende bewering. Om in totaal hoogstens één waarde te krijgen in het geval het commando property niet ook gebruikt wordt, gebruik daarnaast de configuratie-optie single.
*** Alleen bronnen die geldig zijn volgens de Wikidata-richtlijnen voor bronnen worden geretourneerd (d.w.z. bronnen die ten minste de eigenschap (P248) of (P854) hebben).

Algemeen-klasse[brontekst bewerken]

De algemeen-klasse-commando's kunnen niet worden gecombineerd.

Type Commando Retourneert Basisgebruik Beschrijving
I label {{#invoke:wd|label}} Retourneert de label (label) van de huidige item-entiteit of van de opgegeven entiteit indien aanwezig.
II title {{#invoke:wd|title}} Retourneert de titel (title) van de pagina die gekoppeld is aan de huidige item-entiteit of aan de opgegeven entiteit indien zo'n pagina bestaat.
III description {{#invoke:wd|description}} Retourneert de beschrijving (description) van de huidige item-entiteit of van de opgegeven entiteit indien aanwezig.
IV alias eerste overeenkomst* {{#invoke:wd|alias}} Retourneert een alias (alias) – of lijst van aliassen (aliases) – van de huidige item-entiteit of van de opgegeven entiteit indien aanwezig.
aliases alle overeenkomsten {{#invoke:wd|aliases}}
V badge eerste overeenkomst* {{#invoke:wd|badge}} Retourneert een badge (badge) – of lijst van badges (badges) – voor de pagina die gekoppeld is aan de huidige item-entiteit of aan de opgegeven entiteit indien zo'n pagina bestaat.
badges alle overeenkomsten {{#invoke:wd|badges}}
* Retourneert slechts een enkele waarde in plaats van meerdere (als meerdere waardes aanwezig zijn).

Hoofd-klasse

Het commando main wordt altijd in eenzaamheid gebruikt en neem geen opties of argumenten aan. Het maakt het mogelijk voor bovenliggende sjablonen om hun parameters aan deze module door te geven in de vorm van commando's.

Commando Basisgebruik Beschrijving
main {{#invoke:wd|main}} Bedoeld voor gebruik door wrapper-sjablonen (om deze module heen) om één of meerdere van bovenstaande commando's aan te roepen en hun bijbehorende uitvoer te retourneren.

De parameters die aan de wrapper-sjabloon worden gegeven zijn die, die zullen worden gebruikt door de module, bijvoorbeeld {{wikidata|property|P1549}}{{#invoke:wd|main}}{{#invoke:wd|main|property|P1549}}.

Derhalve zullen parameters die gezet zijn door de wrapper-sjabloon zelf worden verworpen, bijvoorbeeld {{wikidata|property|P1549}}{{#invoke:wd|main|qualifier|P1082|P585}}{{#invoke:wd|main|property|P1549}}.

Opties[brontekst bewerken]

De volgende opties zijn beschikbaar, die kunnen worden gebruikt om het gedrag van deze module aan te passen. De opties dienen opgegeven te worden na het (eerste) commando en voor de positionele argumenten. Voor het gemak zijn lege opties (d.w.z. ||) toegestaan, welke simpelweg zullen worden genegeerd.

Commando-opties[brontekst bewerken]

Deze opties (optie1*, optie2*, ...) zijn van toepassing op het commando dat ze direct voorgaat.

Optie Beschrijving
raw Retourneert de ruwe waarde indien toepasselijk.

Als deze optie wordt gebruikt met item- of property-datatypes, dan zal dit het Q-nummer of P-nummer retourneren in plaats van de gewone label.

Voor hoeveelheid-datatypes zal deze optie alle meeteenheden afstrippen, tenzij ook de optie unit is opgegeven in welk geval de ruwe meeteenheid (het Q-nummer ervan) zal worden geretourneerd.

Als deze optie wordt gebruikt met tijd-datatypes, dan zal de geretourneerde datum in het formaat jjjj-mm-dd zijn (bijvoorbeeld 1731-02-11), of jjjj-mm, of jjjj afhankelijk van de datums precisie. Datums in de Juliaanse kalender die zijn opgeslagen met een precisie van dagen tot en met millennia zullen /Juliaans aan de uitvoer vastgeplakt hebben (bijvoorbeeld 1731-02-11/Juliaans, wat afgesplitst zou kunnen worden door middel van de {{#titleparts}} sjabloonfunctie).

Als het wordt gebruikt met geografische coördinaten-datatypes, dan vervangt het de verschillende symbolen met schuine strepen naar voren in de geretourneerde waarde (bijvoorbeeld 52/5/3/N/4/19/3/E, wat in delen gesplitst zou kunnen worden door middel van de {{#titleparts}} sjabloonfunctie).

linked Voegt een link toe naar het Wikipedia-artikel dat gekoppeld is aan de eigenschap (property) of kwalificatie (qualifier) als het bestaat. Ook meeteenheden die al dan niet worden toegevoegd aan waardes krijgen hiermee een link.

Als deze parameter wordt weggelaten, dan wordt de kale eigenschaps- of kwalificatiewaarde geretourneerd.

short [DUUR] Retourneert de (P1813) van elke geretourneerde entiteit als die beschikbaar is. Als dat niet het geval is, dan volgt het standaardgedrag waarbij de label van de entiteit wordt geretourneerd.
multilanguage Retourneert waardes van het type enkeltalige tekst in welke beschikbare taal dan ook, niet alleen in de taal van de huidige wiki.
unit Retourneert alleen de meeteenheid van hoeveelheid-datatypes.

Configuratie-opties[brontekst bewerken]

Deze opties (optie0*) zijn algemene configuratie-opties en kunnen overal na het eerste commando worden opgegeven (maar vóór de positionele argumenten).

Optie Beschrijving Commando-klasse
Combinatie van: preferred Stelt beperkingen aan de rang van de geselecteerde beweringen. De rangen zijn voorkeursrang (preferred), normale rang (normal) en afgekeurde rang (deprecated).

De eerste drie opties bepalen de rangen van de beweringen die zullen worden geselecteerd. Ze kunnen eventueel worden gevolgd door een + of een -, bijvoorbeeld normal+ or preferred-, waar de eerste beweringen selecteert met een normale rang of hoger en de tweede beweringen met een voorkeursrang of lager. Om beweringen van alle rangen te krijgen, gebruik preferred- of deprecated+.

Als de optie best daarnaast is opgegeven, dan zullen alleen de beweringen die de hoogste rang onder de geselecteerde beweringen hebben worden geretourneerd.

De standaard is normal+|best (dus standaard worden beweringen met een afgekeurde rang nooit geretourneerd).

Uitvoer is altijd gesorteerd van hoogste naar laagste rang (ongeacht of een van deze opties is opgegeven).

bewering
normal
deprecated
best
Combinatie van: future Stelt beperkingen aan de geldigheid op basis van tijd van de geselecteerde beweringen: toekomstig (future), actueel (current) en voormalig (former). Gebruikt de bewerings kwalificaties (qualifiers) (P580) en (P582) om te bepalen of de bewering geldig is voor de geselecteerde tijdsperiode(s).

De standaard is future|current|former (dus standaard worden beweringen die voor welke tijdsperiode dan ook geldig zijn geretourneerd), behalve wanneer date= is opgegeven (zie hieronder) in welk geval de standaard current is.

bewering
current
former
mdy Retourneert datumwaardes in de volgorde maand-dag-jaar in plaats van dag-maand-jaar. bewering
single Retourneert slechts een enkele bewering in plaats van meerdere (als meerdere beweringen overeenkomen). Heeft geen effect als het commando property/properties is opgegeven, in welk geval deze optie overtollig zou zijn. bewering
sourced Retourneert alleen beweringen die minstens één geldige bron (reference) hebben. bewering
Een van: edit Voegt een klikbaar icoon toe na de uitvoer dat door lezers kan worden gebruikt om de geretourneerde bewering op Wikidata te bewerken.

Als edit@end wordt gebruikt, dan zal het icoon aan het einde van de regel worden geplaatst voor nette uitlijning in infoboxen.

bewering, algemeen
edit@end

Argumenten[brontekst bewerken]

De argumenten bepalen waar alle geretourneerde waardes vandaan worden gehaald.

Positionele argumenten[brontekst bewerken]

De volgende tabel geeft een overzicht van de beschikbare positionele argumenten (arg*) in hun vaste volgorde. Voor elk commando is de toepasselijke set van argumenten gemarkeerd. Als meerdere commando's opgegeven zijn, dan is de toepasselijke set de vereniging van de individuele sets. Bijvoorbeeld, als de commando's properties en qualifiers opgegeven zijn, dan moeten ook minstens allebei de argumenten property_id en qualifier_id opgegeven worden.

Meer dan één qualifier/qualifiers-commando kan worden opgegeven. De volgorde waarin deze commando's met hun opties zijn opgegeven komt overeen met de volgorde waarin de bijbehorende qualifier_id-argumenten zijn opgegeven.

(verplicht) (optioneel) (optioneel) (verplicht) (optioneel) (verplicht) (verplicht)
{{#invoke:wd commando's opties entiteit_id property_id ruwe_waarde qualifier_id qualifier_id }}
label, title,
description,
alias/aliases,
badge/badges
property/properties
reference/references
qualifier/qualifiers
qualifier/qualifiers (optionele 2de, 3de, etc.)

Hieronder volgt een beschrijving van alle positionele argumenten.

Argument Beschrijving
entiteit_id

(optioneel)

[DUUR] Q-nummer van de uit te lezen item-entiteit (bijvoorbeeld Q55), P-nummer (of een beschikbare alias) van de uit te lezen property-entiteit voorafgegaan door het voorvoegsel Property: (bijvoorbeeld Property:P38), of paginatitel van het Wikipedia-artikel waarvan de gekoppelde item-entiteit moet worden uitgelezen voorafgegaan door :, een voorgevoegde dubbele punt (bijvoorbeeld :Nederland).

In het geval van de algemeen-klasse-commando's mag het voorvoegsel Property: worden weggelaten voor P-nummers (bijvoorbeeld P38).

Als deze parameter wordt weggelaten, dan zal de item-entiteit die is gekoppeld aan de huidige pagina worden gebruikt (behalve wanneer eid= of page= is opgegeven, zie hieronder). Als deze parameter is opgegeven, maar met een lege waarde (d.w.z. ||), dan zal het vanwege de parameters positie worden geïnterpreteerd als een lege optie en dus worden genegeerd, wat hetzelfde resultaat oplevert als wanneer het was weggelaten. Zie ook de benoemde argumenten eid= en page= hieronder welke ook kunnen worden gebruikt om een entiteit-ID of paginatitel op te geven, maar zonder dat er standaard wordt teruggevallen op de item-entiteit die is gekoppeld aan de huidige pagina.

property_id P-nummer (of een beschikbare alias) van de eigenschap (property) binnen de uit te lezen entiteit, zonder het voorvoegsel Property: (bijvoorbeeld P35).
ruwe_waarde

(optioneel)

Ofwel het Q-nummer gelijk aan de waarde van de eigenschap (bijvoorbeeld Q29574) of een letterlijke waarde (d.w.z. tekenreeks of hoeveelheid etc., geen entiteitslabel) gelijk aan de ruwe waarde van de eigenschap van de uit te lezen bewering.

Datums als letterlijke waardes moeten worden gegeven in het formaat jjjj-mm-dd (bijvoorbeeld 1731-02-11) voor datums met een precisie van dagen, jjjj-mm (bijvoorbeeld 1731-02) voor datums met een precisie van maanden, en jjjj (bijvoorbeeld 1731) voor datums met een lagere precisie. Datums v.g.j. vereisen een minteken voor het jaar (bijvoorbeeld -2950-01-31). Datums opgeslagen in de Juliaanse kalender moeten /Juliaans aan het einde hebben (bijvoorbeeld 1731-02-11/Juliaans). Decennia zoals de jaren 2010 moeten worden gegeven als 2010 (maar de jaren 2010 v.g.j. als -2019), eeuwen zoals de 20ste eeuw als 1901 (maar de 20ste eeuw v.g.j. als -2000), en millennia zoals het 3de millennium als 2001 (maar het 3de millennium v.g.j. als -3000).

Geografische coördinaten als letterlijke waardes moeten worden gegeven met schuine strepen naar voren (d.w.z. /) in plaats van symbolen tussen de delen (bijvoorbeeld 52/5/3/N/4/19/3/E) zonder enige spaties of voorafgaande nullen, waarbij de aanduidingen van de halfronden de Engelse afkortingen zijn: "N" voor noord, "S" voor zuid, "E" voor oost en "W" voor west.

Het speciale type 'geen waarde' kan worden opgegeven met de lege tekst (d.w.z. ||) en het speciale type 'onbekende waarde' kan worden opgegeven met een enkele underscore (d.w.z. |_|). Om een letterlijke underscore te krijgen, maskeer het door er een schuine streep naar achteren \ direct voor te plaatsen (d.w.z. \_); hetzelfde geldt voor een letterlijke schuine streep naar achteren (d.w.z. \\).

Om een letterlijk verticaal streepje | te krijgen, gebruik {{!}} of |.

Als deze parameter wordt weggelaten, dan zullen alle beweringen (die voldoen aan enige andere beperkingen) die vallen onder de opgegeven eigenschap worden uitgelezen.

qualifier_id P-nummer (of een beschikbare alias) van de kwalificatie (qualifier) binnen de uit te lezen entiteit, zonder het voorvoegsel Property: (bijvoorbeeld P580).

Benoemde argumenten[brontekst bewerken]

Hieronder volgt een beschrijving van alle benoemde argumenten, welke naam/waarde-paren zijn (d.w.z. |naam=waarde). Deze zijn allemaal optioneel en kunnen overal na het eerste commando worden opgegeven.

Argument Beschrijving Commando-klasse
eid= [DUUR] Dit argument kan worden gebruikt om het Q-nummer (bijvoorbeeld |eid=Q55) of P-nummer (of een beschikbare alias) van de uit te lezen entiteit op te geven. Het biedt dezelfde functionaliteit als het positionele argument entiteit_id, met één verschil: als het argument is opgegeven maar met een lege waarde (d.w.z. |eid=), dan zal geen enkele entiteit worden uitgelezen in plaats van de item-entiteit die is gekoppeld aan de huidige pagina. Dit is nuttig in sommige gevallen waarin een variabele entiteit-ID wordt verwacht, maar waarbij de item-entiteit die is gekoppeld aan de huidige pagina niet standaard moet worden uitgelezen.

Tevens mag het voorvoegsel Property: worden weggelaten voor P-nummers (bijvoorbeeld |eid=P38) in alle gevallen.

Dit argument heeft alleen effect als het positionele argument entiteit_id is weggelaten.

bewering, algemeen
page= [DUUR] Dit argument kan worden gebruikt om de paginatitel (bijvoorbeeld |page=Nederland) van het Wikipedia-artikel waarvan de gekoppelde item-entiteit moet worden uitgelezen op te geven. Het gedraagt zich net zoals het benoemde argument eid= en kan worden gebruikt in plaats van het positionele argument entiteit_id (merk op dat geen voorgevoegde dubbele punt, :, benodigd is). Als het argument is opgegeven maar met een lege waarde (d.w.z. |page=), dan zal geen enkele entiteit worden uitgelezen in plaats van de item-entiteit die is gekoppeld aan de huidige pagina.

Dit argument heeft alleen effect als het positionele argument entiteit_id en het benoemde argument eid= zijn weggelaten.

bewering, algemeen
date= Dit argument kan worden gebruikt om een bepaalde datum in te stellen (bijvoorbeeld |date=1731-02-11) ten opzichte waarvan beweringen worden gezocht die overeenkomen met de gebruikte opties future, current en former, in plaats van ten opzichte van vandaag. Het stelt de standaard van deze opties in op current zodat standaard alleen beweringen die geldig waren op de opgegeven datum worden geretourneerd (op basis van de bewerings kwalificaties (qualifiers) (P580) en (P582)).

De datum moet worden opgegeven in het formaat jjjj-mm-dd (bijvoorbeeld 1731-02-11), jjjj-mm (bijvoorbeeld 1731-02) of jjjj (bijvoorbeeld 1731).

bewering
<kwalificatie>= De <kwalificatie> is een placeholder voor een set van argumenten die bepalen welke beweringen uitgelezen moeten worden op basis van kwalificatiewaarde (qualifier-waarde), overeenkomstig met het paar positionele argumenten property_id en ruwe_waarde (die toegang bepalen op basis van eigenschapswaarde (property-waarde)).

Zodoende is <kwalificatie> het P-nummer (of een beschikbare alias) van een kwalificatie (qualifier) zonder het voorvoegsel Property: (bijvoorbeeld P518). De waarde is ofwel het Q-nummer dat gelijk is aan de waarde van een van de kwalificaties (bijvoorbeeld Q27561) of een letterlijke waarde (d.w.z. tekenreeks of hoeveelheid etc., geen entiteitslabel) gelijk aan de ruwe waarde van een van de kwalificaties van de uit te lezen bewering. Het formaat van de waarde is hetzelfde als voor het positionele argument ruwe_waarde. Het speciale type 'geen waarde' opgegeven door de lege tekst komt ook overeen met de totale afwezigheid binnen de bewering van de kwalificatie.

Voorbeeld: |P518=Q27561

Meerdere argumenten van dit type kunnen worden opgegeven om meerdere kwalificatiewaardes gelijktijdig overeen te laten komen voor elke bewering.

bewering

Eigenschapsaliassen[brontekst bewerken]

Eigenschapsaliassen (property-aliassen) zijn andere namen voor P-nummers die in plaats daarvan kunnen worden gebruikt. De volgende eigenschapsaliassen (die hoofdlettergevoelig zijn) zijn momenteel beschikbaar:

Alias vertaalt
naar
P-nummer
coord P625
image P18
author P50
publisher P123
importedFrom P143
statedIn P248
pages P304
language P407
hasPart P527
publicationDate P577
startTime P580
endTime P582
chapter P792
retrieved P813
referenceURL P854
sectionVerseOrParagraph P958
archiveURL P1065
title P1476
formatterURL P1630
quote P1683
shortName P1813
definingFormula P2534
archiveDate P2960
inferredFrom P3452
typeOfReference P3865
column P3903

Geavanceerd gebruik[brontekst bewerken]

De opmaak van de uitvoer van (een combinatie van) commando's die zowel een enkelvoudige als een meervoudige vorm hebben (bijvoorbeeld property/properties) kan worden aangepast door middel van een aantal benoemde opties, welke naam/waarde-paren zijn (d.w.z. |optie=waarde), die overal na het eerste commando opgegeven kunnen worden. De onderstaande tabel geeft een overzicht van de beschikbare benoemde opties.

Om een spatie aan het begin of eind van een waarde de plaatsen, gebruik een underscore _. Om een letterlijke underscore te krijgen, maskeer het door er een schuine streep naar achteren \ direct voor te plaatsen (d.w.z. \_); hetzelfde geldt voor een letterlijke schuine streep naar achteren (d.w.z. \\). Om een letterlijk verticaal streepje | te krijgen, gebruik {{!}} of &#124;.

Benoemde optie Standaardwaarde Standaardcriterium Beschrijving
format= %p[%s][%r] als het commando property/properties was opgegeven en het commando qualifier/qualifiers niet was opgegeven Het formaat van een enkele bewerking. De beschikbare parameters zijn als volgt.
Parameter Beschrijving
%p De eigenschapswaarde van de bewering ingevuld door het commando property/properties.
%q1, %q2, %q3, ... De kwalificatiewaarde of lijst van kwalificatiewaardes van de bewering ingevuld door het overeenkomstige qualifier/qualifiers-commando.
%q De verzameling van kwalificatiewaardes ingevuld door ieder qualifier/qualifiers-commando (d.w.z. %q1 + %q2 + %q3 + ...). Als slechts één qualifier/qualifiers-commando is opgegeven, dan is deze parameter gelijk aan %q1.
%r De bronwaarde of lijst van bronwaardes van de bewering ingevuld door het commando reference/references.
%a De alias van de entiteit ingevuld door het commando alias/aliases.
%b De pagina-badge van de entiteit ingevuld door het commando badge/badges.
%s De placeholder voor het verplaatsbare scheidingsteken. Dit is een speciale parameter die niet wordt ingevuld door een commando, maar in plaats daarvan automatisch wordt ingevuld tussen elk paar beweringen, aliassen of badges (als een lijst van beweringen, aliassen of badges wordt geretourneerd). Dit is vooral handig in het geval tevens een bron van een bewering wordt geretourneerd, omdat dit het mogelijk maakt om de bron achter het leesteken te plaatsen zoals voorgeschreven in Wikipedia's conventies. De standaardwaarde is een komma (,) en kan worden overschreven met de optie sep%s (zie hieronder).

Optionele parameters kunnen worden opgegeven door deze in te sluiten tussen vierkante haakjes: [...]. Alle inhoud tussen de vierkante haakjes wordt alleen weergegeven als voor elke optionele parameter die gedefinieerd is tussen dezelfde haakjes een waarde is gevonden. Optionele inhoud kan ook in elkaar worden gestapeld.

Om gebruik te maken van twee openende vierkante haakjes die elkaar direct volgen (d.w.z. [[), gebruik {{!((}}.

Minstens één niet-optionele parameter moet worden opgegeven, terwijl de parameter %s altijd als optioneel moet worden gedefinieerd.

Om een letterlijke [, ], % of \ te krijgen, maskeer het teken door er een schuine streep naar achteren \ direct voor te plaatsen (bijvoorbeeld \%). Zie ook de beschrijving direct boven deze tabel voor meer.

%q[%s][%r] als het commando property/properties niet was opgegeven en het commando qualifier/qualifiers was opgegeven
%r als alleen het commando reference/references was opgegeven
%p[ <span style="font-size:85\%">(%q)</span>][%s][%r] als het commando property/properties was opgegeven en het commando qualifier/qualifiers was opgegeven
%a[%s] als het commando alias/aliases was opgegeven
%b[%s] als het commando badge/badges was opgegeven
sep= _ standaard Het vaste scheidingsteken tussen elk paar beweringen, aliassen of badges.
als alleen het commando reference/references was opgegeven zonder de optie raw
sep%s= , standaard Het verplaatsbare scheidingsteken tussen elk paar beweringen, aliassen of badges. Dit zal de waarde zijn van de parameter %s die wordt ingevuld voor alle beweringen, aliassen of badges, behalve de laatste in de lijst (welke kan worden ingesteld met de optie punc).
; als het commando property/properties niet was opgegeven en het commando qualifier/qualifiers was opgegeven
sep%q1=, sep%q2=, sep%q3=, ... ,_ standaard Het scheidingsteken tussen elk paar kwalificaties van een enkele bewering. Dit zijn de scheidingstekens tussen de waardes voor de parameters %q1, %q2, %q3, ...

Als slechts één qualifier/qualifiers-commando was opgegeven, dan is de optie sep%q1 gelijk aan sep%q.

sep%q= ,_ als precies één qualifier/qualifiers-commando was opgegeven Het scheidingsteken tussen elke set van kwalificaties van een enkele bewering. Dit is het scheidingsteken tussen de waardes voor de parameter %q.

Als slechts één qualifier/qualifiers-commando was opgegeven, dan is deze optie gelijk aan sep%q1.

;_ als meer dan één qualifier/qualifiers-commando was opgegeven
sep%r= standaard Het scheidingsteken tussen elk paar bronnen van een enkele bewering. Dit is het scheidingsteken tussen de waardes voor de parameter %r.
_ als de optie raw was opgegeven voor het commando reference/references
punc= standaard Een leesteken dat aan het einde van de uitvoer geplaatst wordt. Dit wordt geplaatst door er de parameter %s van de laatste bewering (of alias of badge) in de lijst mee in te vullen.

Dit maakt het mogelijk om bronnen van de laatste bewering achter het leesteken te plaatsen wanneer de uitvoer wordt gebruikt als onderdeel van een zin.

Voorbeelden[brontekst bewerken]

Parameters en uitvoertypes Voorbeeld Beschrijving
Q55 = "Eurojam (CES)", P395 = ""

[tekenreeks]

{{#invoke:wd|property|Q55|P395}}

Haalt een tekenreekswaarde op.
P395 = ""

[tekenreeks]

{{#invoke:wd|property|P395}}

Als de module is opgenomen in de pagina (die gekoppeld is aan Q55), dan kan de Q55 worden weggelaten.
Q55 = "Eurojam (CES)", P395 = ""

[tekenreeks]

{{#invoke:wd|property|eid=Q55|P395}}

Een entiteit-ID kan ook worden opgegeven door middel van het argument eid=.
P395 = ""

[tekenreeks]

{{#invoke:wd|property|page=|P395}}

Een paginatitel kan worden opgegeven in plaats van een entiteit-ID door middel van het argument page=.
Q55 = "Eurojam (CES)", P395 = ""

[tekenreeks]

{{#invoke:wd|property|edit|Q55|P395}}

Voegt een klikbaar icoon toe dat kan worden gebruikt om de geretourneerde waarde op Wikidata te bewerken.
Q55 = "Eurojam (CES)", P395 = ""

[tekenreeks]

{{#invoke:wd|property|edit@end|Q55|P395}}

Plaatst het bewerkingsicoon aan het einde van de regel.
Q55 = "Eurojam (CES)", P1082 = ""

[hoeveelheid]

{{#invoke:wd|property|normal+|Q55|P1082}}

Haalt een enkele eigenschapswaarde op van beweringen met een normale rang of hoger.
Q55 = "Eurojam (CES)", P1082 = ""

[hoeveelheid]

{{#invoke:wd|properties|normal+|Q55|P1082}}

Haalt meerdere eigenschapswaarde op van beweringen met een normale rang of hoger.
Q55 = "Eurojam (CES)", P1082 = "", P585 = ""

[hoeveelheid], [tijd]

{{#invoke:wd|properties|qualifier|normal+|Q55|P1082|P585}}

Haalt een enkele kwalificatiewaarde op voor elke bewering, bovenop de eigenschapswaarde.
Q55 = "Eurojam (CES)", P1082 = "", P585 = ""

[hoeveelheid], [tijd], [bron]

{{#invoke:wd|properties|qualifier|references|normal+|Q55|P1082|P585}}

Haalt bronnen op voor elke bewering.
Q55 = "Eurojam (CES)", P1082 = ""

[hoeveelheid], [bron]

Een totaal aantal van {{#invoke:wd|property|references|Q55|P1082}} mensen wonen in Nederland.

Een totaal aantal van mensen wonen in Nederland.
Haalt een eigenschap op met bijbehorende bronnen.
Q55 = "Eurojam (CES)", P1082 = ""

[hoeveelheid], [bron]

Nederland heeft een inwonertal van {{#invoke:wd|property|references|Q55|P1082|punc=.}}

Nederland heeft een inwonertal van
Voegt een leesteken toe aan het einde van de uitvoer, vóór de bron.
Q55 = "Eurojam (CES)", P1082 = "", P585 = ""

[hoeveelheid], [tijd], [bron]

<ul>{{#invoke:wd|properties|qualifier|references|normal+|Q55|P1082|P585|format=<li>%p[%r][<ul><li>%q</li></ul>]</li>}}</ul>

    Retourneert de uitvoer in een aangepast formaat.
    Q55 = "Eurojam (CES)", P1082 = "", P585 = ""

    [tijd]

    {{#invoke:wd|qualifier|normal+|Q55|P1082|P585}}

    Haalt een enkele kwalificatie op per bewering, standaard voor meerdere overeenkomende beweringen.
    Q55 = "Eurojam (CES)", P1082 = "", P585 = ""

    [tijd]

    {{#invoke:wd|qualifier|normal+|single|Q55|P1082|P585}}

    Om een enkele kwalificatie op te halen voor slechts een enkele bewering, geef ook de optie single op zodat slechts een enkele bewering zal worden uitgelezen.
    Q55 = "Eurojam (CES)", P1082 = "", P585 = ""

    [tijd]

    {{#invoke:wd|qualifier|Q55|P1082|'|P585}}

    Haalt een kwalificatie op van beweringen waarvan de (ruwe) eigenschapswaarde overeenkomt met een opgegeven letterlijke waarde.
    Q55 = "Eurojam (CES)", P1082 = "", P585 = ""

    [tijd]

    {{#invoke:wd|qualifier|mdy|Q55|P1082||P585}}

    Haalt datums op in de volgorde maand-dag-jaar.
    Q55 = "Eurojam (CES)", P1082 = "", P585 = ""

    [tijd]

    {{#invoke:wd|qualifier|raw|Q55|P1082||P585}}

    Haalt een ruwe datumwaarde op.
    Q55 = "Eurojam (CES)", P1082 = ""

    [bron]

    {{#invoke:wd|'references|Q55|P1082|'}}

    Haalt de bronnen op van een bepaalde bewering.
    Q55 = "Eurojam (CES)", P1082 = ""

    [bron]

    {{#invoke:wd|'references|raw|Q55|P1082|'}}

    Haalt bronnen op van een bepaalde bewering in hun ruwe vorm.
    Q55 = "Eurojam (CES)", P1081 = ""

    [hoeveelheid], [bron]

    {{#invoke:wd|properties|references|normal+|Q55|P1081}}

    Haalt eigenschappen op van elke bewering met alle eventuele bijbehorende bronnen.
    Q55 = "Eurojam (CES)", P1081 = ""

    [hoeveelheid], [bron]

    {{#invoke:wd|properties|references|normal+|sourced|Q55|P1081}}

    Haalt alleen eigenschappen op van beweringen die minstens één bron hebben.
    Q55 = "Eurojam (CES)", P2855 = "", P518 = ""

    [entiteitslabel]

    {{#invoke:wd|qualifier|Q55|P2855|P518}}

    Haalt een enkele kwalificatiewaarde op (voor elke overeenkomende bewering).
    Q55 = "Eurojam (CES)", P2855 = "", P518 = ""

    [entiteitslabel]

    {{#invoke:wd|qualifiers|Q55|P2855|P518}}

    Haalt meerdere kwalificatiewaardes op (voor elke overeenkomende bewering).
    Q55 = "Eurojam (CES)", P2855 = "", P518 = ""

    [hoeveelheid], [entiteitslabel]

    {{#invoke:wd|properties|qualifiers|Q55|P2855|P518}}

    Haalt meerdere eigenschapswaardes op samen met meerdere kwalificatiewaardes.
    Q55 = "Eurojam (CES)", P2855 = "", P518 = ""

    [hoeveelheid], [entiteitslabel]

    {{#invoke:wd|properties|qualifiers|Q55|P2855|P518|sep=_+_|sep%s=|sep%q=_/_}}

    Retourneert de uitvoer met aangepaste scheidingstekens.
    Q55 = "Eurojam (CES)", P35 = "", P580 = "", P582 = ""

    [entiteitslabel], [tijd]

    {{#invoke:wd|properties|qualifier|qualifier|normal+|Q55|P35|P580|P582}}

    Haalt twee verschillende kwalificatiewaardes op voor elke bewering.
    Q55 = "Eurojam (CES)", P35 = "", P580 = "", P582 = ""

    [entiteitslabel], [tijd]

    {{#invoke:wd|properties|qualifier|qualifier|normal+|Q55|P35|P580|P582|sep%q=_–_}}

    Retourneert de uitvoer met een aangepast scheidingsteken.
    Q55 = "Eurojam (CES)", P35 = "", P580 = "", P582 = ""

    [entiteitslabel], [tijd]

    {{#invoke:wd|properties|qualifier|qualifier|normal+|Q55|P35|P580|P582|format=%p[ <span style="font-size:85\%">(%q1[ – %q2])</span>][%s][%r]}}

    Retourneert de uitvoer in een aangepast formaat in plaats van met een aangepast scheidingsteken.
    Q55 = "Eurojam (CES)", P35 = "", P580 = "", P582 = ""

    [entiteitslabel], [tijd]

    {{#invoke:wd|properties|qualifier|qualifier|normal+|Q55|P35|P580|P582|format=%p[ <span style="font-size:85\%">([<![]--%q2]sinds [%q2--[]>]%q1[ – %q2])</span>][%s][%r]}}

    Om tekst toe te voegen alleen wanneer een bepaalde waarde niet aanwezig is, zoals het toevoegen van het woord sinds indien er geen einddatum is, plaats deze tussen twee optionele blokken met HTML commentaar-tags en de betreffende parameter (dit voorkomt ook dat de tekst in de paginabron wordt opgenomen).
    Q55 = "Eurojam (CES)", P35 = "", Q29574 = "", P580 = "", P582 = ""

    [entiteitslabel], [tijd]

    {{#invoke:wd|properties|qualifier|raw|qualifier|normal+|Q55|P35|Q29574|P580|P582|format=%p[ <span style="font-size:85\%">(%q1[ – %q2])</span>][%s][%r]}}

    Haalt een eigenschap met kwalificaties op van beweringen waarvan de eigenschap overeenkomt met een opgegeven Q-nummer, met een van de kwalificatiewaardes in ruwe vorm.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item", P518 = ""

    [entiteitslabel]

    {{#invoke:wd|properties|qualifiers|normal+|current|Q55|P38|P518}}

    Haalt beweringen op die actueel zijn.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item", P518 = ""

    [entiteitslabel]

    {{#invoke:wd|properties|linked|qualifiers|normal+|current|Q55|P38|P518}}

    Haalt beweringen op met gelinkte eigenschapswaardes.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item", P518 = ""

    [entiteitslabel]

    {{#invoke:wd|properties|qualifiers|linked|normal+|current|Q55|P38|P518}}

    Haalt beweringen op met gelinkte kwalificatiewaardes.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item", P518 = ""

    [entiteitslabel]

    {{#invoke:wd|properties|linked|short|qualifiers|linked|normal+|current|Q55|P38|P518}}

    Haalt beweringen op met gelinkte eigenschaps- en kwalificatiewaardes, met verkorte eigenschapswaardes waar beschikbaar.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item", Q4917 = "", P518 = ""

    [entiteitslabel]

    {{#invoke:wd|qualifiers|normal+|current|Q55|P38|Q4917|P518}}

    Haalt kwalificaties op van beweringen waarvan de (ruwe) eigenschapswaarde overeenkomt met een opgegeven Q-nummer.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item", P518 = "", Q27561 = ""

    [entiteitslabel]

    {{#invoke:wd|properties|normal+|current|Q55|P38|P518=Q27561}}

    Haalt eigenschappen op van beweringen waarvan een (ruwe) kwalificatiewaarde overeenkomt met een opgegeven Q-nummer.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item"

    [entiteitslabel]

    {{#invoke:wd|properties|normal+|former|Q55|P38}}

    Haalt beweringen op die voorheen geldig waren.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item"

    [entiteitslabel]

    {{#invoke:wd|properties|raw|normal+|former|Q55|P38}}

    Haalt ruwe eigenschapswaardes op.
    Q55 = "Eurojam (CES)", P38 = "Wikidata-item"

    [entiteitslabel]

    {{#invoke:wd|properties|raw|linked|normal+|former|Q55|P38}}

    Haalt ruwe eigenschapswaardes op die gelinkt zijn naar Wikidata.
    Q55 = "Eurojam (CES)", P1549 = ""

    [enkeltalige tekst]

    {{#invoke:wd|property|Q55|P1549}}

    Haalt een waarde van het type enkeltalige tekst op in de taal van de huidige wiki.
    Q55 = "Eurojam (CES)", P1549 = "", P407 = "", Q36846 = ""

    [enkeltalige tekst]

    {{#invoke:wd|property|multilanguage|Q55|P1549|P407=Q36846}}

    Haalt een waarde van het type enkeltalige tekst op in welke beschikbare taal dan ook.
    Q55 = "Eurojam (CES)", P2884 = ""

    [hoeveelheid]

    {{#invoke:wd|property|Q55|P2884}}

    Haalt een hoeveelheidswaarde op met bijbehorende meeteenheid.
    Q55 = "Eurojam (CES)", P2884 = ""

    [hoeveelheid]

    {{#invoke:wd|property|linked|Q55|P2884}}

    Haalt een hoeveelheidswaarde op met een gelinkte meeteenheid.
    Q55 = "Eurojam (CES)", P2884 = ""

    [hoeveelheid]

    {{#invoke:wd|property|raw|Q55|P2884}}

    Haalt een ruwe hoeveelheidswaarde op.
    Q55 = "Eurojam (CES)", P2884 = ""

    [hoeveelheid]

    {{#invoke:wd|property|unit|Q55|P2884}}

    Haalt alleen de meeteenheid op.
    Q55 = "Eurojam (CES)", P2884 = ""

    [quantity]

    {{#invoke:wd|property|unit|raw|Q55|P2884}}

    Haalt de ruwe meeteenheid op.
    Q55 = "Eurojam (CES)", P625 = ""

    [geografische coördinaten]

    {{#invoke:wd|property|Q55|P625}}

    Haalt een waarde van het type geografische coördinaten op.
    Q55 = "Eurojam (CES)", P625 = ""

    [geografische coördinaten]

    {{#invoke:wd|property|linked|Q55|P625}}

    Haalt een gelinkte waarde van het type geografische coördinaten op.
    Q55 = "Eurojam (CES)", P625 = ""

    [geografische coördinaten]

    {{#invoke:wd|property|raw|Q55|P625}}

    Haalt een ruwe waarde van het type geografische coördinaten op.
    Q55 = "Eurojam (CES)", P625 = ""

    [geografische coördinaten]

    {{#invoke:wd|property|Q55|coord}}

    Een eigenschapsalias kan worden gebruikt in plaats van het P-nummer.
    Q55 = "Eurojam (CES)", P41 = ""

    [commons-media]

    {{#invoke:wd|property|linked|Q55|P41}}

    Haalt de naam van een mediabestand op en voegt een link toe naar Commons.
    Q55 = "Eurojam (CES)", P41 = ""

    [commons-media]

    {{#invoke:wd|property|raw|Q55|P41|format=\[\[File:%p {{!}} thumb {{!}} left\]\]}}

    Een mediabestand van Commons kan in de pagina worden opgenomen precies zoals het is door de opties linked en raw weg te laten, maar door de optie raw te gebruiken kan het op allerlei manieren worden opgemaakt.
    Q55 = "Eurojam (CES)", P41 = ""

    [commons-media]

    {{#invoke:wd|property|raw|date=1700-05-06|Q55|P41|format=\[\[File:%p {{!}} thumb {{!}} left\]\]}}

    Om de waarde van een eigenschap op te halen die geldig was op een bepaalde datum kan het argument date= worden gebruikt.
    Q55 = "Eurojam (CES)", P41 = ""

    [commons-media]

    {{#invoke:wd|property|raw|date=1700-05-06|former|Q55|P41|format=\[\[File:%p {{!}} thumb {{!}} left\]\]}}

    De opties voor geldigheid werken ten opzichte van de datum die is opgegeven met het argument date=.
    Q915684 = "", P2534 = ""

    [wiskundig]

    {{#invoke:wd|property|Q915684|P2534}}

    Haalt een wiskundige uitdrukking op.
    Q915684 = "", P527 = "", P416 = "", P2534 = ""

    [entiteitslabel], [tekenreeks], [wiskundig]

    <ul>{{#invoke:wd|properties|linked|qualifier|qualifier|Q915684|P527|P416|P2534|format=<li>%p[ (%q)]</li>}}</ul>

      Wiskundige uitdrukkingen kunnen worden gecombineerd met gewone tekst, zoals gewoonlijk.
      Q6256 = "", P3896 = ""

      [geografische vorm]

      {{#invoke:wd|property|linked|Q6256|P3896}}

      Haalt de databestandsnaam van een geografische vorm op en voegt een link toe naar Commons.
      Q4917 = ""

      [entiteitslabel]

      {{#invoke:wd|label|Q4917}}

      Haalt het label van een item op.
      Q4917 = ""

      [entiteitslabel]

      {{#invoke:wd|label|short|linked|Q4917}}

      Haalt het verkorte en gelinkte label van een item op.
      P38 = "Wikidata-item"

      [entiteitslabel]

      {{#invoke:wd|label|P38}}

      Wikidata-item
      Haalt het label van een property op.
      P38 = "Wikidata-item"

      [entiteitslabel]

      {{#invoke:wd|label|linked|P38}}

      Wikidata-item
      Haalt het label van een property op dat gelinkt is naar Wikidata.
      Q776 = "Kaa"

      [entiteitslabel]

      {{#invoke:wd|label|Q776}}

      Kaa
      Haalt het label van een item op.
      Q776 = "Kaa"

      [entiteitslabel]

      {{#invoke:wd|label|linked|Q776}}

      Kaa
      Haalt het gelinkte label van een item op.


      [entiteitslabel]

      {{#invoke:wd|label}}

      Kaa
      Als de module is opgenomen in de pagina Kaa (die gekoppeld is aan Q776), dan kan de Q776 worden weggelaten.


      [entiteitslabel]

      {{#invoke:wd|label|raw}}

      Q776
      Als slechts het commando label met de optie raw is opgegeven, dan wordt het Q-nummer van het item dat gekoppeld is aan de huidige pagina geretourneerd.


      [entiteitslabel]

      {{#invoke:wd|label|raw|linked}}

      Q776
      Als daarnaast de optie linked is opgegeven, dan wordt het Q-nummer van het item dat gekoppeld is aan de huidige pagina gelinkt naar Wikidata.
      Q776 = "Kaa"

      [paginatitel]

      {{#invoke:wd|title|Q776}}

      Kaa
      Haalt de titel op van de pagina op de huidige wiki die gekoppeld is aan het opgegeven item.
      Q776 = "Kaa"

      [paginatitel]

      {{#invoke:wd|title|linked|Q776}}

      Kaa
      Haalt de gelinkte titel op van de pagina op de huidige wiki die gekoppeld is aan het opgegeven item.


      [paginatitel]

      {{#invoke:wd|title}}

      Kaa
      Als de module is opgenomen in de pagina Kaa (die gekoppeld is aan Q776), dan kan de Q776 worden weggelaten.
      Q55 = "Eurojam (CES)"

      [entiteitsbeschrijving]

      {{#invoke:wd|description|Q55}}

      Haalt de beschrijving van een item op.


      [entiteitsbeschrijving]

      {{#invoke:wd|description}}

      Als de module is opgenomen in de pagina (die gekoppeld is aan Q55), dan kan de Q55 worden weggelaten.
      Q55 = "Eurojam (CES)"

      [entiteitsalias]

      {{#invoke:wd|alias|Q55}}

      Haalt een van de aliassen van een item op.
      Q55 = "Eurojam (CES)"

      [entiteitsalias]

      {{#invoke:wd|aliases|Q55}}

      Haalt alle aliassen van een item op.
      Q55 = "Eurojam (CES)"

      [entiteitsalias]

      {{#invoke:wd|alias|linked|Q55}}

      Haalt een gelinkte alias van een item op.


      [entiteitsalias]

      {{#invoke:wd|alias}}

      Als de module is opgenomen in de pagina (die gekoppeld is aan Q55), dan kan de Q55 worden weggelaten.
      Q2 = ""

      [pagina-badge]

      {{#invoke:wd|badges|Q2}}

      Haalt de badges op voor de pagina op de huidige wiki die gekoppeld is aan het opgegeven item.
      Q2 = ""

      [pagina-badge]

      {{#invoke:wd|badges|raw|Q2}}

      Haalt de ruwe badges op voor de pagina op de huidige wiki die gekoppeld is aan het opgegeven item.


      [pagina-badge]

      {{#invoke:wd|badges}}

      Als de module is opgenomen in de pagina (die gekoppeld is aan Q2), dan kan de Q2 worden weggelaten.

      Voorbeeldbronnen[brontekst bewerken]

      Zie ook[brontekst bewerken]

      • {{Wikidata}}, een gebruiksvriendelijke wrapper-sjabloon voor deze module.

      -- Original module located at [[:en:Module:Wd]] and [[:en:Module:Wd/i18n]].
      
      local p = {}
      local arg = ...
      local i18n
      
      local function loadI18n(aliasesP, frame)
      	local title
      
      	if frame then
      		-- current module invoked by page/template, get its title from frame
      		title = frame:getTitle()
      	else
      		-- current module included by other module, get its title from ...
      		title = arg
      	end
      
      	if not i18n then
      		i18n = require(title .. "/i18n").init(aliasesP)
      	end
      end
      
      p.claimCommands = {
      	property   = "property",
      	properties = "properties",
      	qualifier  = "qualifier",
      	qualifiers = "qualifiers",
      	reference  = "reference",
      	references = "references"
      }
      
      p.generalCommands = {
      	label       = "label",
      	title       = "title",
      	description = "description",
      	alias       = "alias",
      	aliases     = "aliases",
      	badge       = "badge",
      	badges      = "badges"
      }
      
      p.flags = {
      	linked        = "linked",
      	short         = "short",
      	raw           = "raw",
      	multilanguage = "multilanguage",
      	unit          = "unit",
      	-------------
      	preferred     = "preferred",
      	normal        = "normal",
      	deprecated    = "deprecated",
      	best          = "best",
      	future        = "future",
      	current       = "current",
      	former        = "former",
      	edit          = "edit",
      	editAtEnd     = "edit@end",
      	mdy           = "mdy",
      	single        = "single",
      	sourced       = "sourced"
      }
      
      p.args = {
      	eid  = "eid",
      	page = "page",
      	date = "date"
      }
      
      local aliasesP = {
      	coord                   = "P625",
      	-----------------------
      	image                   = "P18",
      	author                  = "P50",
      	publisher               = "P123",
      	importedFrom            = "P143",
      	statedIn                = "P248",
      	pages                   = "P304",
      	language                = "P407",
      	hasPart                 = "P527",
      	publicationDate         = "P577",
      	startTime               = "P580",
      	endTime                 = "P582",
      	chapter                 = "P792",
      	retrieved               = "P813",
      	referenceURL            = "P854",
      	sectionVerseOrParagraph = "P958",
      	archiveURL              = "P1065",
      	title                   = "P1476",
      	formatterURL            = "P1630",
      	quote                   = "P1683",
      	shortName               = "P1813",
      	definingFormula         = "P2534",
      	archiveDate             = "P2960",
      	inferredFrom            = "P3452",
      	typeOfReference         = "P3865",
      	column                  = "P3903"
      }
      
      local aliasesQ = {
      	percentage              = "Q11229",
      	prolepticJulianCalendar = "Q1985786",
      	citeWeb                 = "Q5637226",
      	citeQ                   = "Q22321052"
      }
      
      local parameters = {
      	property  = "%p",
      	qualifier = "%q",
      	reference = "%r",
      	alias     = "%a",
      	badge     = "%b",
      	separator = "%s",
      	general   = "%x"
      }
      
      local formats = {
      	property              = "%p[%s][%r]",
      	qualifier             = "%q[%s][%r]",
      	reference             = "%r",
      	propertyWithQualifier = "%p[ <span style=\"font-size:85\\%\">(%q)</span>][%s][%r]",
      	alias                 = "%a[%s]",
      	badge                 = "%b[%s]"
      }
      
      local hookNames = {              -- {level_1, level_2}
      	[parameters.property]         = {"getProperty"},
      	[parameters.reference]        = {"getReferences", "getReference"},
      	[parameters.qualifier]        = {"getAllQualifiers"},
      	[parameters.qualifier.."\\d"] = {"getQualifiers", "getQualifier"},
      	[parameters.alias]            = {"getAlias"},
      	[parameters.badge]            = {"getBadge"}
      }
      
      -- default value objects, should NOT be mutated but instead copied
      local defaultSeparators = {
      	["sep"]      = {" "},
      	["sep%s"]    = {","},
      	["sep%q"]    = {"; "},
      	["sep%q\\d"] = {", "},
      	["sep%r"]    = nil,  -- none
      	["punc"]     = nil   -- none
      }
      
      local rankTable = {
      	["preferred"]  = 1,
      	["normal"]     = 2,
      	["deprecated"] = 3
      }
      
      local Config = {}
      
      -- allows for recursive calls
      function Config:new()
      	local cfg = {}
      	setmetatable(cfg, self)
      	self.__index = self
      
      	cfg.separators = {
      		-- single value objects wrapped in arrays so that we can pass by reference
      		["sep"]   = {copyTable(defaultSeparators["sep"])},
      		["sep%s"] = {copyTable(defaultSeparators["sep%s"])},
      		["sep%q"] = {copyTable(defaultSeparators["sep%q"])},
      		["sep%r"] = {copyTable(defaultSeparators["sep%r"])},
      		["punc"]  = {copyTable(defaultSeparators["punc"])}
      	}
      
      	cfg.entity = nil
      	cfg.entityID = nil
      	cfg.propertyID = nil
      	cfg.propertyValue = nil
      	cfg.qualifierIDs = {}
      	cfg.qualifierIDsAndValues = {}
      
      	cfg.bestRank = true
      	cfg.ranks = {true, true, false}  -- preferred = true, normal = true, deprecated = false
      	cfg.foundRank = #cfg.ranks
      	cfg.flagBest = false
      	cfg.flagRank = false
      
      	cfg.periods = {true, true, true}  -- future = true, current = true, former = true
      	cfg.flagPeriod = false
      	cfg.atDate = {parseDate(os.date('!%Y-%m-%d'))}  -- today as {year, month, day}
      
      	cfg.mdyDate = false
      	cfg.singleClaim = false
      	cfg.sourcedOnly = false
      	cfg.editable = false
      	cfg.editAtEnd = false
      
      	cfg.inSitelinks = false
      
      	cfg.langCode = mw.language.getContentLanguage().code
      	cfg.langName = mw.language.fetchLanguageName(cfg.langCode, cfg.langCode)
      	cfg.langObj = mw.language.new(cfg.langCode)
      
      	cfg.siteID = mw.wikibase.getGlobalSiteId()
      
      	cfg.states = {}
      	cfg.states.qualifiersCount = 0
      	cfg.curState = nil
      
      	cfg.prefetchedRefs = nil
      
      	return cfg
      end
      
      local State = {}
      
      function State:new(cfg, type)
      	local stt = {}
      	setmetatable(stt, self)
      	self.__index = self
      
      	stt.conf = cfg
      	stt.type = type
      
      	stt.results = {}
      
      	stt.parsedFormat = {}
      	stt.separator = {}
      	stt.movSeparator = {}
      	stt.puncMark = {}
      
      	stt.linked = false
      	stt.rawValue = false
      	stt.shortName = false
      	stt.anyLanguage = false
      	stt.unitOnly = false
      	stt.singleValue = false
      
      	return stt
      end
      
      local function replaceAlias(id)
      	if aliasesP[id] then
      		id = aliasesP[id]
      	end
      
      	return id
      end
      
      local function errorText(code, param)
      	local text = i18n["errors"][code]
      	if param then text = mw.ustring.gsub(text, "$1", param) end
      	return text
      end
      
      local function throwError(errorMessage, param)
      	error(errorText(errorMessage, param))
      end
      
      local function replaceDecimalMark(num)
      	return mw.ustring.gsub(num, "[.]", i18n['numeric']['decimal-mark'], 1)
      end
      
      local function padZeros(num, numDigits)
      	local numZeros
      	local negative = false
      
      	if num < 0 then
      		negative = true
      		num = num * -1
      	end
      
      	num = tostring(num)
      	numZeros = numDigits - num:len()
      
      	for _ = 1, numZeros do
      		num = "0"..num
      	end
      
      	if negative then
      		num = "-"..num
      	end
      
      	return num
      end
      
      local function replaceSpecialChar(chr)
      	if chr == '_' then
      		-- replace underscores with spaces
      		return ' '
      	else
      		return chr
      	end
      end
      
      local function replaceSpecialChars(str)
      	local chr
      	local esc = false
      	local strOut = ""
      
      	for i = 1, #str do
      		chr = str:sub(i,i)
      
      		if not esc then
      			if chr == '\\' then
      				esc = true
      			else
      				strOut = strOut .. replaceSpecialChar(chr)
      			end
      		else
      			strOut = strOut .. chr
      			esc = false
      		end
      	end
      
      	return strOut
      end
      
      local function buildWikilink(target, label)
      	if not label or target == label then
      		return "[[" .. target .. "]]"
      	else
      		return "[[" .. target .. "|" .. label .. "]]"
      	end
      end
      
      -- used to make frame.args mutable, to replace #frame.args (which is always 0)
      -- with the actual amount and to simply copy tables
      function copyTable(tIn)
      	if not tIn then
      		return nil
      	end
      
      	local tOut = {}
      
      	for i, v in pairs(tIn) do
      		tOut[i] = v
      	end
      
      	return tOut
      end
      
      -- used to merge output arrays together;
      -- note that it currently mutates the first input array
      local function mergeArrays(a1, a2)
      	for i = 1, #a2 do
      		a1[#a1 + 1] = a2[i]
      	end
      
      	return a1
      end
      
      local function split(str, del)
      	local out = {}
      	local i, j = str:find(del)
      
      	if i and j then
      		out[1] = str:sub(1, i - 1)
      		out[2] = str:sub(j + 1)
      	else
      		out[1] = str
      	end
      
      	return out
      end
      
      local function parseWikidataURL(url)
      	local id
      
      	if url:match('^http[s]?://') then
      		id = split(url, "Q")
      
      		if id[2] then
      			return "Q" .. id[2]
      		end
      	end
      
      	return nil
      end
      
      function parseDate(dateStr, precision)
      	precision = precision or "d"
      
      	local i, j, index, ptr
      	local parts = {nil, nil, nil}
      
      	if dateStr == nil then
      		return parts[1], parts[2], parts[3]  -- year, month, day
      	end
      
      	-- 'T' for snak values, '/' for outputs with '/Julian' attached
      	i, j = dateStr:find("[T/]")
      
      	if i then
      		dateStr = dateStr:sub(1, i-1)
      	end
      
      	local from = 1
      
      	if dateStr:sub(1,1) == "-" then
      		-- this is a negative number, look further ahead
      		from = 2
      	end
      
      	index = 1
      	ptr = 1
      
      	i, j = dateStr:find("-", from)
      
      	if i then
      		-- year
      		parts[index] = tonumber(mw.ustring.gsub(dateStr:sub(ptr, i-1), "^\+(.+)$", "%1"), 10)  -- remove '+' sign (explicitly give base 10 to prevent error)
      
      		if parts[index] == -0 then
      			parts[index] = tonumber("0")  -- for some reason, 'parts[index] = 0' may actually store '-0', so parse from string instead
      		end
      
      		if precision == "y" then
      			-- we're done
      			return parts[1], parts[2], parts[3]  -- year, month, day
      		end
      
      		index = index + 1
      		ptr = i + 1
      
      		i, j = dateStr:find("-", ptr)
      
      		if i then
      			-- month
      			parts[index] = tonumber(dateStr:sub(ptr, i-1), 10)
      
      			if precision == "m" then
      				-- we're done
      				return parts[1], parts[2], parts[3]  -- year, month, day
      			end
      
      			index = index + 1
      			ptr = i + 1
      		end
      	end
      
      	if dateStr:sub(ptr) ~= "" then
      		-- day if we have month, month if we have year, or year
      		parts[index] = tonumber(dateStr:sub(ptr), 10)
      	end
      
      	return parts[1], parts[2], parts[3]  -- year, month, day
      end
      
      local function datePrecedesDate(aY, aM, aD, bY, bM, bD)
      	if aY == nil or bY == nil then
      		return nil
      	end
      	aM = aM or 1
      	aD = aD or 1
      	bM = bM or 1
      	bD = bD or 1
      
      	if aY < bY then
      		return true
      	end
      
      	if aY > bY then
      		return false
      	end
      
      	if aM < bM then
      		return true
      	end
      
      	if aM > bM then
      		return false
      	end
      
      	if aD < bD then
      		return true
      	end
      
      	return false
      end
      
      local function getHookName(param, index)
      	if hookNames[param] then
      		return hookNames[param][index]
      	elseif param:len() > 2 then
      		return hookNames[param:sub(1, 2).."\\d"][index]
      	else
      		return nil
      	end
      end
      
      local function alwaysTrue()
      	return true
      end
      
      -- The following function parses a format string.
      --
      -- The example below shows how a parsed string is structured in memory.
      -- Variables other than 'str' and 'child' are left out for clarity's sake.
      --
      -- Example:
      -- "A %p B [%s[%q1]] C [%r] D"
      --
      -- Structure:
      -- [
      --   {
      --     str = "A "
      --   },
      --   {
      --     str = "%p"
      --   },
      --   {
      --     str = " B ",
      --     child =
      --     [
      --       {
      --         str = "%s",
      --         child =
      --         [
      --           {
      --             str = "%q1"
      --           }
      --         ]
      --       }
      --     ]
      --   },
      --   {
      --     str = " C ",
      --     child =
      --     [
      --       {
      --         str = "%r"
      --       }
      --     ]
      --   },
      --   {
      --     str = " D"
      --   }
      -- ]
      --
      local function parseFormat(str)
      	local chr, esc, param, root, cur, prev, new
      	local params = {}
      
      	local function newObject(array)
      		local obj = {}  -- new object
      		obj.str = ""
      
      		array[#array + 1] = obj  -- array{object}
      		obj.parent = array
      
      		return obj
      	end
      
      	local function endParam()
      		if param > 0 then
      			if cur.str ~= "" then
      				cur.str = "%"..cur.str
      				cur.param = true
      				params[cur.str] = true
      				cur.parent.req[cur.str] = true
      				prev = cur
      				cur = newObject(cur.parent)
      			end
      			param = 0
      		end
      	end
      
      	root = {}  -- array
      	root.req = {}
      	cur = newObject(root)
      	prev = nil
      
      	esc = false
      	param = 0
      
      	for i = 1, #str do
      		chr = str:sub(i,i)
      
      		if not esc then
      			if chr == '\\' then
      				endParam()
      				esc = true
      			elseif chr == '%' then
      				endParam()
      				if cur.str ~= "" then
      					cur = newObject(cur.parent)
      				end
      				param = 2
      			elseif chr == '[' then
      				endParam()
      				if prev and cur.str == "" then
      					table.remove(cur.parent)
      					cur = prev
      				end
      				cur.child = {}  -- new array
      				cur.child.req = {}
      				cur.child.parent = cur
      				cur = newObject(cur.child)
      			elseif chr == ']' then
      				endParam()
      				if cur.parent.parent then
      					new = newObject(cur.parent.parent.parent)
      					if cur.str == "" then
      						table.remove(cur.parent)
      					end
      					cur = new
      				end
      			else
      				if param > 1 then
      					param = param - 1
      				elseif param == 1 then
      					if not chr:match('%d') then
      						endParam()
      					end
      				end
      
      				cur.str = cur.str .. replaceSpecialChar(chr)
      			end
      		else
      			cur.str = cur.str .. chr
      			esc = false
      		end
      
      		prev = nil
      	end
      
      	endParam()
      
      	-- make sure that at least one required parameter has been defined
      	if not next(root.req) then
      		throwError("missing-required-parameter")
      	end
      
      	-- make sure that the separator parameter "%s" is not amongst the required parameters
      	if root.req[parameters.separator] then
      		throwError("extra-required-parameter", parameters.separator)
      	end
      
      	return root, params
      end
      
      local function sortOnRank(claims)
      	local rankPos
      	local ranks = {{}, {}, {}, {}}  -- preferred, normal, deprecated, (default)
      	local sorted = {}
      
      	for _, v in ipairs(claims) do
      		rankPos = rankTable[v.rank] or 4
      		ranks[rankPos][#ranks[rankPos] + 1] = v
      	end
      
      	sorted = ranks[1]
      	sorted = mergeArrays(sorted, ranks[2])
      	sorted = mergeArrays(sorted, ranks[3])
      
      	return sorted
      end
      
      -- if id == nil then item connected to current page is used
      function Config:getLabel(id, raw, link, short)
      	local label = nil
      	local title = nil
      	local prefix= ""
      
      	if not id then
      		id = mw.wikibase.getEntityIdForCurrentPage()
      
      		if not id then
      			return ""
      		end
      	end
      
      	id = id:upper()  -- just to be sure
      
      	if raw then
      		-- check if given id actually exists
      		if mw.wikibase.isValidEntityId(id) and mw.wikibase.entityExists(id) then
      			label = id
      
      			if id:sub(1,1) == "P" then
      				prefix = "Property:"
      			end
      		end
      
      		prefix = "d:" .. prefix
      
      		title = label  -- may be nil
      	else
      		-- try short name first if requested
      		if short then
      			label = p._property{aliasesP.shortName, [p.args.eid] = id}  -- get short name
      
      			if label == "" then
      				label = nil
      			end
      		end
      
      		-- get label
      		if not label then
      			label = mw.wikibase.getLabelByLang(id, self.langCode)
      		end
      	end
      
      	if not label then
      		label = ""
      	elseif link then
      		-- build a link if requested
      		if not title then
      			if id:sub(1,1) == "Q" then
      				title = mw.wikibase.getSitelink(id)
      			elseif id:sub(1,1) == "P" then
      				-- properties have no sitelink, link to Wikidata instead
      				title = id
      				prefix = "d:Property:"
      			end
      		end
      
      		if title then
      			label = buildWikilink(prefix .. title, label)
      		end
      	end
      
      	return label
      end
      
      function Config:getEditIcon()
      	local value = ""
      	local prefix = ""
      	local front = "&nbsp;"
      	local back = ""
      
      	if self.entityID:sub(1,1) == "P" then
      		prefix = "Property:"
      	end
      
      	if self.editAtEnd then
      		front = '<span style="float:'
      
      		if self.langObj:isRTL() then
      			front = front .. 'left'
      		else
      			front = front .. 'right'
      		end
      
      		front = front .. '">'
      		back = '</span>'
      	end
      
      	value = "[[File:OOjs UI icon edit-ltr-progressive.svg|frameless|text-top|10px|alt=" .. i18n['info']['edit-on-wikidata'] .. "|link=https://www.wikidata.org/wiki/" .. prefix .. self.entityID .. "?uselang=" .. self.langCode
      
      	if self.propertyID then
      		value = value .. "#" .. self.propertyID
      	elseif self.inSitelinks then
      		value = value .. "#sitelinks-wikipedia"
      	end
      
      	value = value .. "|" .. i18n['info']['edit-on-wikidata'] .. "]]"
      
      	return front .. value .. back
      end
      
      -- used to create the final output string when it's all done, so that for references the
      -- function extensionTag("ref", ...) is only called when they really ended up in the final output
      function Config:concatValues(valuesArray)
      	local outString = ""
      	local j, skip
      
      	for i = 1, #valuesArray do
      		-- check if this is a reference
      		if valuesArray[i].refHash then
      			j = i - 1
      			skip = false
      
      			-- skip this reference if it is part of a continuous row of references that already contains the exact same reference
      			while valuesArray[j] and valuesArray[j].refHash do
      				if valuesArray[i].refHash == valuesArray[j].refHash then
      					skip = true
      					break
      				end
      				j = j - 1
      			end
      
      			if not skip then
      				-- add <ref> tag with the reference's hash as its name (to deduplicate references)
      				outString = outString .. mw.getCurrentFrame():extensionTag("ref", valuesArray[i][1], {name = valuesArray[i].refHash})
      			end
      		else
      			outString = outString .. valuesArray[i][1]
      		end
      	end
      
      	return outString
      end
      
      function Config:convertUnit(unit, raw, link, short, unitOnly)
      	local space = " "
      	local label = ""
      	local itemID
      
      	if unit == "" or unit == "1" then
      		return nil
      	end
      
      	if unitOnly then
      		space = ""
      	end
      
      	itemID = parseWikidataURL(unit)
      
      	if itemID then
      		if itemID == aliasesQ.percentage then
      			return "%"
      		else
      			label = self:getLabel(itemID, raw, link, short)
      
      			if label ~= "" then
      				return space .. label
      			end
      		end
      	end
      
      	return ""
      end
      
      function State:getValue(snak)
      	return self.conf:getValue(snak, self.rawValue, self.linked, self.shortName, self.anyLanguage, self.unitOnly, false, self.type:sub(1,2))
      end
      
      function Config:getValue(snak, raw, link, short, anyLang, unitOnly, noSpecial, type)
      	if snak.snaktype == 'value' then
      		local datatype = snak.datavalue.type
      		local subtype = snak.datatype
      		local datavalue = snak.datavalue.value
      
      		if datatype == 'string' then
      			if subtype == 'url' and link then
      				-- create link explicitly
      				if raw then
      					-- will render as a linked number like [1]
      					return "[" .. datavalue .. "]"
      				else
      					return "[" .. datavalue .. " " .. datavalue .. "]"
      				end
      			elseif subtype == 'commonsMedia' then
      				if link then
      					return buildWikilink("c:File:" .. datavalue, datavalue)
      				elseif not raw then
      					return "[[File:" .. datavalue .. "]]"
      				else
      					return datavalue
      				end
      			elseif subtype == 'geo-shape' and link then
      				return buildWikilink("c:" .. datavalue, datavalue)
      			elseif subtype == 'math' and not raw then
      				local attribute = nil
      
      				if (type == parameters.property or (type == parameters.qualifier and self.propertyID == aliasesP.hasPart)) and snak.property == aliasesP.definingFormula then
      					attribute = {qid = self.entityID}
      				end
      
      				return mw.getCurrentFrame():extensionTag("math", datavalue, attribute)
      			elseif subtype == 'external-id' and link then
      				local url = p._property{aliasesP.formatterURL, [p.args.eid] = snak.property}  -- get formatter URL
      
      				if url ~= "" then
      					url = mw.ustring.gsub(url, "$1", datavalue)
      					return "[" .. url .. " " .. datavalue .. "]"
      				else
      					return datavalue
      				end
      			else
      				return datavalue
      			end
      		elseif datatype == 'monolingualtext' then
      			if anyLang or datavalue['language'] == self.langCode then
      				return datavalue['text']
      			else
      				return nil
      			end
      		elseif datatype == 'quantity' then
      			local value = ""
      			local unit
      
      			if not unitOnly then
      				-- get value and strip + signs from front
      				value = mw.ustring.gsub(datavalue['amount'], "^\+(.+)$", "%1")
      
      				if raw then
      					return value
      				end
      
      				-- replace decimal mark based on locale
      				value = replaceDecimalMark(value)
      
      				-- add delimiters for readability
      				value = i18n.addDelimiters(value)
      			end
      
      			unit = self:convertUnit(datavalue['unit'], raw, link, short, unitOnly)
      
      			if unit then
      				value = value .. unit
      			end
      
      			return value
      		elseif datatype == 'time' then
      			local y, m, d, p, yDiv, yRound, yFull, value, calendarID, dateStr
      			local yFactor = 1
      			local sign = 1
      			local prefix = ""
      			local suffix = ""
      			local mayAddCalendar = false
      			local calendar = ""
      			local precision = datavalue['precision']
      
      			if precision == 11 then
      				p = "d"
      			elseif precision == 10 then
      				p = "m"
      			else
      				p = "y"
      				yFactor = 10^(9-precision)
      			end
      
      			y, m, d = parseDate(datavalue['time'], p)
      
      			if y < 0 then
      				sign = -1
      				y = y * sign
      			end
      
      			-- if precision is tens/hundreds/thousands/millions/billions of years
      			if precision <= 8 then
      				yDiv = y / yFactor
      
      				-- if precision is tens/hundreds/thousands of years
      				if precision >= 6 then
      					mayAddCalendar = true
      
      					if precision <= 7 then
      						-- round centuries/millenniums up (e.g. 20th century or 3rd millennium)
      						yRound = math.ceil(yDiv)
      
      						if not raw then
      							if precision == 6 then
      								suffix = i18n['datetime']['suffixes']['millennium']
      							else
      								suffix = i18n['datetime']['suffixes']['century']
      							end
      
      							suffix = i18n.getOrdinalSuffix(yRound) .. suffix
      						else
      							-- if not verbose, take the first year of the century/millennium
      							-- (e.g. 1901 for 20th century or 2001 for 3rd millennium)
      							yRound = (yRound - 1) * yFactor + 1
      						end
      					else
      						-- precision == 8
      						-- round decades down (e.g. 2010s)
      						yRound = math.floor(yDiv) * yFactor
      
      						if not raw then
      							prefix = i18n['datetime']['prefixes']['decade-period']
      							suffix = i18n['datetime']['suffixes']['decade-period']
      						end
      					end
      
      					if raw and sign < 0 then
      						-- if BCE then compensate for "counting backwards"
      						-- (e.g. -2019 for 2010s BCE, -2000 for 20th century BCE or -3000 for 3rd millennium BCE)
      						yRound = yRound + yFactor - 1
      					end
      				else
      					local yReFactor, yReDiv, yReRound
      
      					-- round to nearest for tens of thousands of years or more
      					yRound = math.floor(yDiv + 0.5)
      
      					if yRound == 0 then
      						if precision <= 2 and y ~= 0 then
      							yReFactor = 1e6
      							yReDiv = y / yReFactor
      							yReRound = math.floor(yReDiv + 0.5)
      
      							if yReDiv == yReRound then
      								-- change precision to millions of years only if we have a whole number of them
      								precision = 3
      								yFactor = yReFactor
      								yRound = yReRound
      							end
      						end
      
      						if yRound == 0 then
      							-- otherwise, take the unrounded (original) number of years
      							precision = 5
      							yFactor = 1
      							yRound = y
      							mayAddCalendar = true
      						end
      					end
      
      					if precision >= 1 and y ~= 0 then
      						yFull = yRound * yFactor
      
      						yReFactor = 1e9
      						yReDiv = yFull / yReFactor
      						yReRound = math.floor(yReDiv + 0.5)
      
      						if yReDiv == yReRound then
      							-- change precision to billions of years if we're in that range
      							precision = 0
      							yFactor = yReFactor
      							yRound = yReRound
      						else
      							yReFactor = 1e6
      							yReDiv = yFull / yReFactor
      							yReRound = math.floor(yReDiv + 0.5)
      
      							if yReDiv == yReRound then
      								-- change precision to millions of years if we're in that range
      								precision = 3
      								yFactor = yReFactor
      								yRound = yReRound
      							end
      						end
      					end
      
      					if not raw then
      						if precision == 3 then
      							suffix = i18n['datetime']['suffixes']['million-years']
      						elseif precision == 0 then
      							suffix = i18n['datetime']['suffixes']['billion-years']
      						else
      							yRound = yRound * yFactor
      							if yRound == 1 then
      								suffix = i18n['datetime']['suffixes']['year']
      							else
      								suffix = i18n['datetime']['suffixes']['years']
      							end
      						end
      					else
      						yRound = yRound * yFactor
      					end
      				end
      			else
      				yRound = y
      				mayAddCalendar = true
      			end
      
      			if mayAddCalendar then
      				calendarID = parseWikidataURL(datavalue['calendarmodel'])
      
      				if calendarID and calendarID == aliasesQ.prolepticJulianCalendar then
      					if not raw then
      						if link then
      							calendar = " ("..buildWikilink(i18n['datetime']['julian-calendar'], i18n['datetime']['julian'])..")"
      						else
      							calendar = " ("..i18n['datetime']['julian']..")"
      						end
      					else
      						calendar = "/"..i18n['datetime']['julian']
      					end
      				end
      			end
      
      			if not raw then
      				local ce = nil
      
      				if sign < 0 then
      					ce = i18n['datetime']['BCE']
      				elseif precision <= 5 then
      					ce = i18n['datetime']['CE']
      				end
      
      				if ce then
      					if link then
      						ce = buildWikilink(i18n['datetime']['common-era'], ce)
      					end
      					suffix = suffix .. " " .. ce
      				end
      
      				value = tostring(yRound)
      
      				if m then
      					dateStr = self.langObj:formatDate("F", "1-"..m.."-1")
      
      					if d then
      						if self.mdyDate then
      							dateStr = dateStr .. " " .. d .. ","
      						else
      							dateStr = d .. " " .. dateStr
      						end
      					end
      
      					value = dateStr .. " " .. value
      				end
      
      				value = prefix .. value .. suffix .. calendar
      			else
      				value = padZeros(yRound * sign, 4)
      
      				if m then
      					value = value .. "-" .. padZeros(m, 2)
      
      					if d then
      						value = value .. "-" .. padZeros(d, 2)
      					end
      				end
      
      				value = value .. calendar
      			end
      
      			return value
      		elseif datatype == 'globecoordinate' then
      			-- logic from https://github.com/DataValues/Geo (v4.0.1)
      
      			local precision, unitsPerDegree, numDigits, strFormat, value, globe
      			local latitude, latConv, latValue, latLink
      			local longitude, lonConv, lonValue, lonLink
      			local latDirection, latDirectionN, latDirectionS, latDirectionEN
      			local lonDirection, lonDirectionE, lonDirectionW, lonDirectionEN
      			local degSymbol, minSymbol, secSymbol, separator
      
      			local latDegrees = nil
      			local latMinutes = nil
      			local latSeconds = nil
      			local lonDegrees = nil
      			local lonMinutes = nil
      			local lonSeconds = nil
      
      			local latDegSym = ""
      			local latMinSym = ""
      			local latSecSym = ""
      			local lonDegSym = ""
      			local lonMinSym = ""
      			local lonSecSym = ""
      
      			local latDirectionEN_N = "N"
      			local latDirectionEN_S = "S"
      			local lonDirectionEN_E = "E"
      			local lonDirectionEN_W = "W"
      
      			if not raw then
      				latDirectionN = i18n['coord']['latitude-north']
      				latDirectionS = i18n['coord']['latitude-south']
      				lonDirectionE = i18n['coord']['longitude-east']
      				lonDirectionW = i18n['coord']['longitude-west']
      
      				degSymbol = i18n['coord']['degrees']
      				minSymbol = i18n['coord']['minutes']
      				secSymbol = i18n['coord']['seconds']
      				separator = i18n['coord']['separator']
      			else
      				latDirectionN = latDirectionEN_N
      				latDirectionS = latDirectionEN_S
      				lonDirectionE = lonDirectionEN_E
      				lonDirectionW = lonDirectionEN_W
      
      				degSymbol = "/"
      				minSymbol = "/"
      				secSymbol = "/"
      				separator = "/"
      			end
      
      			latitude = datavalue['latitude']
      			longitude = datavalue['longitude']
      
      			if latitude < 0 then
      				latDirection = latDirectionS
      				latDirectionEN = latDirectionEN_S
      				latitude = math.abs(latitude)
      			else
      				latDirection = latDirectionN
      				latDirectionEN = latDirectionEN_N
      			end
      
      			if longitude < 0 then
      				lonDirection = lonDirectionW
      				lonDirectionEN = lonDirectionEN_W
      				longitude = math.abs(longitude)
      			else
      				lonDirection = lonDirectionE
      				lonDirectionEN = lonDirectionEN_E
      			end
      
      			precision = datavalue['precision']
      
      			if not precision or precision <= 0 then
      				precision = 1 / 3600  -- precision not set (correctly), set to arcsecond
      			end
      
      			-- remove insignificant detail
      			latitude = math.floor(latitude / precision + 0.5) * precision
      			longitude = math.floor(longitude / precision + 0.5) * precision
      
      			if precision >= 1 - (1 / 60) and precision < 1 then
      				precision = 1
      			elseif precision >= (1 / 60) - (1 / 3600) and precision < (1 / 60) then
      				precision = 1 / 60
      			end
      
      			if precision >= 1 then
      				unitsPerDegree = 1
      			elseif precision >= (1 / 60)  then
      				unitsPerDegree = 60
      			else
      				unitsPerDegree = 3600
      			end
      
      			numDigits = math.ceil(-math.log10(unitsPerDegree * precision))
      
      			if numDigits <= 0 then
      				numDigits = tonumber("0")  -- for some reason, 'numDigits = 0' may actually store '-0', so parse from string instead
      			end
      
      			strFormat = "%." .. numDigits .. "f"
      
      			if precision >= 1 then
      				latDegrees = strFormat:format(latitude)
      				lonDegrees = strFormat:format(longitude)
      
      				if not raw then
      					latDegSym = replaceDecimalMark(latDegrees) .. degSymbol
      					lonDegSym = replaceDecimalMark(lonDegrees) .. degSymbol
      				else
      					latDegSym = latDegrees .. degSymbol
      					lonDegSym = lonDegrees .. degSymbol
      				end
      			else
      				latConv = math.floor(latitude * unitsPerDegree * 10^numDigits + 0.5) / 10^numDigits
      				lonConv = math.floor(longitude * unitsPerDegree * 10^numDigits + 0.5) / 10^numDigits
      
      				if precision >= (1 / 60) then
      					latMinutes = latConv
      					lonMinutes = lonConv
      				else
      					latSeconds = latConv
      					lonSeconds = lonConv
      
      					latMinutes = math.floor(latSeconds / 60)
      					lonMinutes = math.floor(lonSeconds / 60)
      
      					latSeconds = strFormat:format(latSeconds - (latMinutes * 60))
      					lonSeconds = strFormat:format(lonSeconds - (lonMinutes * 60))
      
      					if not raw then
      						latSecSym = replaceDecimalMark(latSeconds) .. secSymbol
      						lonSecSym = replaceDecimalMark(lonSeconds) .. secSymbol
      					else
      						latSecSym = latSeconds .. secSymbol
      						lonSecSym = lonSeconds .. secSymbol
      					end
      				end
      
      				latDegrees = math.floor(latMinutes / 60)
      				lonDegrees = math.floor(lonMinutes / 60)
      
      				latDegSym = latDegrees .. degSymbol
      				lonDegSym = lonDegrees .. degSymbol
      
      				latMinutes = latMinutes - (latDegrees * 60)
      				lonMinutes = lonMinutes - (lonDegrees * 60)
      
      				if precision >= (1 / 60) then
      					latMinutes = strFormat:format(latMinutes)
      					lonMinutes = strFormat:format(lonMinutes)
      
      					if not raw then
      						latMinSym = replaceDecimalMark(latMinutes) .. minSymbol
      						lonMinSym = replaceDecimalMark(lonMinutes) .. minSymbol
      					else
      						latMinSym = latMinutes .. minSymbol
      						lonMinSym = lonMinutes .. minSymbol
      					end
      				else
      					latMinSym = latMinutes .. minSymbol
      					lonMinSym = lonMinutes .. minSymbol
      				end
      			end
      
      			latValue = latDegSym .. latMinSym .. latSecSym .. latDirection
      			lonValue = lonDegSym .. lonMinSym .. lonSecSym .. lonDirection
      
      			value = latValue .. separator .. lonValue
      
      			if link then
      				globe = parseWikidataURL(datavalue['globe'])
      
      				if globe then
      					globe = mw.wikibase.getLabelByLang(globe, "en"):lower()
      				else
      					globe = "earth"
      				end
      
      				latLink = table.concat({latDegrees, latMinutes, latSeconds}, "_")
      				lonLink = table.concat({lonDegrees, lonMinutes, lonSeconds}, "_")
      
      				value = "[https://tools.wmflabs.org/geohack/geohack.php?language="..self.langCode.."&params="..latLink.."_"..latDirectionEN.."_"..lonLink.."_"..lonDirectionEN.."_globe:"..globe.." "..value.."]"
      			end
      
      			return value
      		elseif datatype == 'wikibase-entityid' then
      			local label
      			local itemID = datavalue['numeric-id']
      
      			if subtype == 'wikibase-item' then
      				itemID = "Q" .. itemID
      			elseif subtype == 'wikibase-property' then
      				itemID = "P" .. itemID
      			else
      				return '<strong class="error">' .. errorText('unknown-data-type', subtype) .. '</strong>'
      			end
      
      			label = self:getLabel(itemID, raw, link, short)
      
      			if label == "" then
      				label = nil
      			end
      
      			return label
      		else
      			return '<strong class="error">' .. errorText('unknown-data-type', datatype) .. '</strong>'
      		end
      	elseif snak.snaktype == 'somevalue' and not noSpecial then
      		if raw then
      			return " "  -- single space represents 'somevalue'
      		else
      			return i18n['values']['unknown']
      		end
      	elseif snak.snaktype == 'novalue' and not noSpecial then
      		if raw then
      			return ""  -- empty string represents 'novalue'
      		else
      			return i18n['values']['none']
      		end
      	else
      		return nil
      	end
      end
      
      function Config:getSingleRawQualifier(claim, qualifierID)
      	local qualifiers
      
      	if claim.qualifiers then qualifiers = claim.qualifiers[qualifierID] end
      
      	if qualifiers and qualifiers[1] then
      		return self:getValue(qualifiers[1], true)  -- raw = true
      	else
      		return nil
      	end
      end
      
      function Config:snakEqualsValue(snak, value)
      	local snakValue = self:getValue(snak, true)  -- raw = true
      
      	if snakValue and snak.snaktype == 'value' and snak.datavalue.type == 'wikibase-entityid' then value = value:upper() end
      
      	return snakValue == value
      end
      
      function Config:setRank(rank)
      	local rankPos
      
      	if rank == p.flags.best then
      		self.bestRank = true
      		self.flagBest = true  -- mark that 'best' flag was given
      		return
      	end
      
      	if rank:sub(1,9) == p.flags.preferred then
      		rankPos = 1
      	elseif rank:sub(1,6) == p.flags.normal then
      		rankPos = 2
      	elseif rank:sub(1,10) == p.flags.deprecated then
      		rankPos = 3
      	else
      		return
      	end
      
      	-- one of the rank flags was given, check if another one was given before
      	if not self.flagRank then
      		self.ranks = {false, false, false}  -- no other rank flag given before, so unset ranks
      		self.bestRank = self.flagBest       -- unsets bestRank only if 'best' flag was not given before
      		self.flagRank = true                -- mark that a rank flag was given
      	end
      
      	if rank:sub(-1) == "+" then
      		for i = rankPos, 1, -1 do
      			self.ranks[i] = true
      		end
      	elseif rank:sub(-1) == "-" then
      		for i = rankPos, #self.ranks do
      			self.ranks[i] = true
      		end
      	else
      		self.ranks[rankPos] = true
      	end
      end
      
      function Config:setPeriod(period)
      	local periodPos
      
      	if period == p.flags.future then
      		periodPos = 1
      	elseif period == p.flags.current then
      		periodPos = 2
      	elseif period == p.flags.former then
      		periodPos = 3
      	else
      		return
      	end
      
      	-- one of the period flags was given, check if another one was given before
      	if not self.flagPeriod then
      		self.periods = {false, false, false}  -- no other period flag given before, so unset periods
      		self.flagPeriod = true                -- mark that a period flag was given
      	end
      
      	self.periods[periodPos] = true
      end
      
      function Config:qualifierMatches(claim, id, value)
      	local qualifiers
      
      	if claim.qualifiers then qualifiers = claim.qualifiers[id] end
      	if qualifiers then
      		for _, v in pairs(qualifiers) do
      			if self:snakEqualsValue(v, value) then
      				return true
      			end
      		end
      	elseif value == "" then
      		-- if the qualifier is not present then treat it the same as the special value 'novalue'
      		return true
      	end
      
      	return false
      end
      
      function Config:rankMatches(rankPos)
      	if self.bestRank then
      		return (self.ranks[rankPos] and self.foundRank >= rankPos)
      	else
      		return self.ranks[rankPos]
      	end
      end
      
      function Config:timeMatches(claim)
      	local startTime = nil
      	local startTimeY = nil
      	local startTimeM = nil
      	local startTimeD = nil
      	local endTime = nil
      	local endTimeY = nil
      	local endTimeM = nil
      	local endTimeD = nil
      
      	if self.periods[1] and self.periods[2] and self.periods[3] then
      		-- any time
      		return true
      	end
      
      	startTime = self:getSingleRawQualifier(claim, aliasesP.startTime)
      	if startTime and startTime ~= "" and startTime ~= " " then
      		startTimeY, startTimeM, startTimeD = parseDate(startTime)
      	end
      
      	endTime = self:getSingleRawQualifier(claim, aliasesP.endTime)
      	if endTime and endTime ~= "" and endTime ~= " " then
      		endTimeY, endTimeM, endTimeD = parseDate(endTime)
      	end
      
      	if startTimeY ~= nil and endTimeY ~= nil and datePrecedesDate(endTimeY, endTimeM, endTimeD, startTimeY, startTimeM, startTimeD) then
      		-- invalidate end time if it precedes start time
      		endTimeY = nil
      		endTimeM = nil
      		endTimeD = nil
      	end
      
      	if self.periods[1] then
      		-- future
      		if startTimeY and datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], startTimeY, startTimeM, startTimeD) then
      			return true
      		end
      	end
      
      	if self.periods[2] then
      		-- current
      		if (startTimeY == nil or not datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], startTimeY, startTimeM, startTimeD)) and
      		   (endTimeY == nil or datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], endTimeY, endTimeM, endTimeD)) then
      			return true
      		end
      	end
      
      	if self.periods[3] then
      		-- former
      		if endTimeY and not datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], endTimeY, endTimeM, endTimeD) then
      			return true
      		end
      	end
      
      	return false
      end
      
      function Config:processFlag(flag)
      	if not flag then
      		return false
      	end
      
      	if flag == p.flags.linked then
      		self.curState.linked = true
      		return true
      	elseif flag == p.flags.raw then
      		self.curState.rawValue = true
      
      		if self.curState == self.states[parameters.reference] then
      			-- raw reference values end with periods and require a separator (other than none)
      			self.separators["sep%r"][1] = {" "}
      		end
      
      		return true
      	elseif flag == p.flags.short then
      		self.curState.shortName = true
      		return true
      	elseif flag == p.flags.multilanguage then
      		self.curState.anyLanguage = true
      		return true
      	elseif flag == p.flags.unit then
      		self.curState.unitOnly = true
      		return true
      	elseif flag == p.flags.mdy then
      		self.mdyDate = true
      		return true
      	elseif flag == p.flags.single then
      		self.singleClaim = true
      		return true
      	elseif flag == p.flags.sourced then
      		self.sourcedOnly = true
      		return true
      	elseif flag == p.flags.edit then
      		self.editable = true
      		return true
      	elseif flag == p.flags.editAtEnd then
      		self.editable = true
      		self.editAtEnd = true
      		return true
      	elseif flag == p.flags.best or flag:match('^'..p.flags.preferred..'[+-]?$') or flag:match('^'..p.flags.normal..'[+-]?$') or flag:match('^'..p.flags.deprecated..'[+-]?$') then
      		self:setRank(flag)
      		return true
      	elseif flag == p.flags.future or flag == p.flags.current or flag == p.flags.former then
      		self:setPeriod(flag)
      		return true
      	elseif flag == "" then
      		-- ignore empty flags and carry on
      		return true
      	else
      		return false
      	end
      end
      
      function Config:processFlagOrCommand(flag)
      	local param = ""
      
      	if not flag then
      		return false
      	end
      
      	if flag == p.claimCommands.property or flag == p.claimCommands.properties then
      		param = parameters.property
      	elseif flag == p.claimCommands.qualifier or flag == p.claimCommands.qualifiers then
      		self.states.qualifiersCount = self.states.qualifiersCount + 1
      		param = parameters.qualifier .. self.states.qualifiersCount
      		self.separators["sep"..param] = {copyTable(defaultSeparators["sep%q\\d"])}
      	elseif flag == p.claimCommands.reference or flag == p.claimCommands.references then
      		param = parameters.reference
      	else
      		return self:processFlag(flag)
      	end
      
      	if self.states[param] then
      		return false
      	end
      
      	-- create a new state for each command
      	self.states[param] = State:new(self, param)
      
      	-- use "%x" as the general parameter name
      	self.states[param].parsedFormat = parseFormat(parameters.general)  -- will be overwritten for param=="%p"
      
      	-- set the separator
      	self.states[param].separator = self.separators["sep"..param]  -- will be nil for param=="%p", which will be set separately
      
      	if flag == p.claimCommands.property or flag == p.claimCommands.qualifier or flag == p.claimCommands.reference then
      		self.states[param].singleValue = true
      	end
      
      	self.curState = self.states[param]
      
      	return true
      end
      
      function Config:processSeparators(args)
      	local sep
      
      	for i, v in pairs(self.separators) do
      		if args[i] then
      			sep = replaceSpecialChars(args[i])
      
      			if sep ~= "" then
      				self.separators[i][1] = {sep}
      			else
      				self.separators[i][1] = nil
      			end
      		end
      	end
      end
      
      function Config:setFormatAndSeparators(state, parsedFormat)
      	state.parsedFormat = parsedFormat
      	state.separator = self.separators["sep"]
      	state.movSeparator = self.separators["sep"..parameters.separator]
      	state.puncMark = self.separators["punc"]
      end
      
      -- determines if a claim has references by prefetching them from the claim using getReferences,
      -- which applies some filtering that determines if a reference is actually returned,
      -- and caches the references for later use
      function State:isSourced(claim)
      	self.conf.prefetchedRefs = self:getReferences(claim)
      	return (#self.conf.prefetchedRefs > 0)
      end
      
      function State:resetCaches()
      	-- any prefetched references of the previous claim must not be used
      	self.conf.prefetchedRefs = nil
      end
      
      function State:claimMatches(claim)
      	local matches, rankPos
      
      	-- first of all, reset any cached values used for the previous claim
      	self:resetCaches()
      
      	-- if a property value was given, check if it matches the claim's property value
      	if self.conf.propertyValue then
      		matches = self.conf:snakEqualsValue(claim.mainsnak, self.conf.propertyValue)
      	else
      		matches = true
      	end
      
      	-- if any qualifier values were given, check if each matches one of the claim's qualifier values
      	for i, v in pairs(self.conf.qualifierIDsAndValues) do
      		matches = (matches and self.conf:qualifierMatches(claim, i, v))
      	end
      
      	-- check if the claim's rank and time period match
      	rankPos = rankTable[claim.rank] or 4
      	matches = (matches and self.conf:rankMatches(rankPos) and self.conf:timeMatches(claim))
      
      	-- if only claims with references must be returned, check if this one has any
      	if self.conf.sourcedOnly then
      		matches = (matches and self:isSourced(claim))  -- prefetches and caches references
      	end
      
      	return matches, rankPos
      end
      
      function State:out()
      	local result  -- collection of arrays with value objects
      	local valuesArray  -- array with value objects
      	local sep = nil  -- value object
      	local out = {}  -- array with value objects
      
      	local function walk(formatTable, result)
      		local valuesArray = {}  -- array with value objects
      
      		for i, v in pairs(formatTable.req) do
      			if not result[i] or not result[i][1] then
      				-- we've got no result for a parameter that is required on this level,
      				-- so skip this level (and its children) by returning an empty result
      				return {}
      			end
      		end
      
      		for _, v in ipairs(formatTable) do
      			if v.param then
      				valuesArray = mergeArrays(valuesArray, result[v.str])
      			elseif v.str ~= "" then
      				valuesArray[#valuesArray + 1] = {v.str}
      			end
      
      			if v.child then
      				valuesArray = mergeArrays(valuesArray, walk(v.child, result))
      			end
      		end
      
      		return valuesArray
      	end
      
      	-- iterate through the results from back to front, so that we know when to add separators
      	for i = #self.results, 1, -1 do
      		result = self.results[i]
      
      		-- if there is already some output, then add the separators
      		if #out > 0 then
      			sep = self.separator[1]  -- fixed separator
      			result[parameters.separator] = {self.movSeparator[1]}  -- movable separator
      		else
      			sep = nil
      			result[parameters.separator] = {self.puncMark[1]}  -- optional punctuation mark
      		end
      
      		valuesArray = walk(self.parsedFormat, result)
      
      		if #valuesArray > 0 then
      			if sep then
      				valuesArray[#valuesArray + 1] = sep
      			end
      
      			out = mergeArrays(valuesArray, out)
      		end
      	end
      
      	-- reset state before next iteration
      	self.results = {}
      
      	return out
      end
      
      -- level 1 hook
      function State:getProperty(claim)
      	local value = {self:getValue(claim.mainsnak)}  -- create one value object
      
      	if #value > 0 then
      		return {value}  -- wrap the value object in an array and return it
      	else
      		return {}  -- return empty array if there was no value
      	end
      end
      
      -- level 1 hook
      function State:getQualifiers(claim, param)
      	local qualifiers
      
      	if claim.qualifiers then qualifiers = claim.qualifiers[self.conf.qualifierIDs[param]] end
      	if qualifiers then
      		-- iterate through claim's qualifier statements to collect their values;
      		-- return array with multiple value objects
      		return self.conf.states[param]:iterate(qualifiers, {[parameters.general] = hookNames[parameters.qualifier.."\\d"][2], count = 1})  -- pass qualifier state with level 2 hook
      	else
      		return {}  -- return empty array
      	end
      end
      
      -- level 2 hook
      function State:getQualifier(snak)
      	local value = {self:getValue(snak)}  -- create one value object
      
      	if #value > 0 then
      		return {value}  -- wrap the value object in an array and return it
      	else
      		return {}  -- return empty array if there was no value
      	end
      end
      
      -- level 1 hook
      function State:getAllQualifiers(claim, param, result, hooks)
      	local out = {}  -- array with value objects
      	local sep = self.conf.separators["sep"..parameters.qualifier][1]  -- value object
      
      	-- iterate through the output of the separate "qualifier(s)" commands
      	for i = 1, self.conf.states.qualifiersCount do
      
      		-- if a hook has not been called yet, call it now
      		if not result[parameters.qualifier..i] then
      			self:callHook(parameters.qualifier..i, hooks, claim, result)
      		end
      
      		-- if there is output for this particular "qualifier(s)" command, then add it
      		if result[parameters.qualifier..i] and result[parameters.qualifier..i][1] then
      
      			-- if there is already some output, then add the separator
      			if #out > 0 and sep then
      				out[#out + 1] = sep
      			end
      
      			out = mergeArrays(out, result[parameters.qualifier..i])
      		end
      	end
      
      	return out
      end
      
      -- level 1 hook
      function State:getReferences(claim)
      	if self.conf.prefetchedRefs then
      		-- return references that have been prefetched by isSourced
      		return self.conf.prefetchedRefs
      	end
      
      	if claim.references then
      		-- iterate through claim's reference statements to collect their values;
      		-- return array with multiple value objects
      		return self.conf.states[parameters.reference]:iterate(claim.references, {[parameters.general] = hookNames[parameters.reference][2], count = 1})  -- pass reference state with level 2 hook
      	else
      		return {}  -- return empty array
      	end
      end
      
      -- level 2 hook
      function State:getReference(statement)
      	local key, citeWeb, citeQ, label
      	local params = {}
      	local citeParams = {['web'] = {}, ['q'] = {}}
      	local citeMismatch = {}
      	local useCite = nil
      	local useParams = nil
      	local value = ""
      	local ref = {}
      
      	local version = 1  -- increment this each time the below logic is changed to avoid conflict errors
      
      	if statement.snaks then
      		-- don't include "imported from", which is added by a bot
      		if statement.snaks[aliasesP.importedFrom] then
      			statement.snaks[aliasesP.importedFrom] = nil
      		end
      
      		-- don't include "inferred from", which is added by a bot
      		if statement.snaks[aliasesP.inferredFrom] then
      			statement.snaks[aliasesP.inferredFrom] = nil
      		end
      
      		-- don't include "type of reference"
      		if statement.snaks[aliasesP.typeOfReference] then
      			statement.snaks[aliasesP.typeOfReference] = nil
      		end
      
      		-- don't include "image" to prevent littering
      		if statement.snaks[aliasesP.image] then
      			statement.snaks[aliasesP.image] = nil
      		end
      		p = statement.snaks
      		-- don't include "language" if it is equal to the local one
      		if self:getReferenceDetail(statement.snaks, aliasesP.language) == self.conf.langName then
      			statement.snaks[aliasesP.language] = nil
      		end
      
      		-- retrieve all the parameters
      		for i in pairs(statement.snaks) do
      			label = ""
      
      			-- multiple authors may be given
      			if i == aliasesP.author then
      				params[i] = self:getReferenceDetails(statement.snaks, i, false, self.linked, true)  -- link = true/false, anyLang = true
      			else
      				params[i] = {self:getReferenceDetail(statement.snaks, i, false, (self.linked or (i == aliasesP.statedIn)) and (statement.snaks[i][1].datatype ~= 'url'), true)}  -- link = true/false, anyLang = true
      			end
      
      			if #params[i] == 0 then
      				params[i] = nil
      			else
      				if statement.snaks[i][1].datatype == 'external-id' then
      					key = "external-id"
      					label = self.conf:getLabel(i)
      
      					if label ~= "" then
      						label = label .. " "
      					end
      				else
      					key = i
      				end
      
      				-- add the parameter to each matching type of citation
      				for j in pairs(citeParams) do
      					-- do so if there was no mismatch with a previous parameter
      					if not citeMismatch[j] then
      						-- check if this parameter is not mismatching itself
      						if i18n['cite'][j][key] then
      							-- continue if an option is available in the corresponding cite template
      							if i18n['cite'][j][key] ~= "" then
      								citeParams[j][i18n['cite'][j][key]] = label .. params[i][1]
      
      								-- if there are multiple parameter values (authors), add those too
      								for k=2, #params[i] do
      									citeParams[j][i18n['cite'][j][key]..k] = label .. params[i][k]
      								end
      							end
      						else
      							citeMismatch[j] = true
      						end
      					end
      				end
      			end
      		end
      
      		-- get title of general template for citing web references
      		citeWeb = split(mw.wikibase.getSitelink(aliasesQ.citeWeb) or "", ":")[2]  -- split off namespace from front
      
      		-- get title of template that expands stated-in references into citations
      		citeQ = split(mw.wikibase.getSitelink(aliasesQ.citeQ) or "", ":")[2]  -- split off namespace from front
      
      		-- (1) use the general template for citing web references if there is a match and if at least both "reference URL" and "title" are present
      		if citeWeb and not citeMismatch['web'] and citeParams['web'][i18n['cite']['web'][aliasesP.referenceURL]] and citeParams['web'][i18n['cite']['web'][aliasesP.title]] then
      			useCite = citeWeb
      			useParams = citeParams['web']
      
      		-- (2) use the template that expands stated-in references into citations if there is a match and if at least "stated in" is present
      		elseif citeQ and not citeMismatch['q'] and citeParams['q'][i18n['cite']['q'][aliasesP.statedIn]] then
      			-- we need the raw "stated in" Q-identifier for the this template
      			citeParams['q'][i18n['cite']['q'][aliasesP.statedIn]] = self:getReferenceDetail(statement.snaks, aliasesP.statedIn, true)  -- raw = true
      
      			useCite = citeQ
      			useParams = citeParams['q']
      		end
      
      		if useCite and useParams then
      			-- if this module is being substituted then build a regular template call, otherwise expand the template
      			if mw.isSubsting() then
      				for i, v in pairs(useParams) do
      					value = value .. "|" .. i .. "=" .. v
      				end
      
      				value = "{{" .. useCite .. value .. "}}"
      			else
      				value = mw.getCurrentFrame():expandTemplate{title=useCite, args=useParams}
      			end
      
      		-- (3) else, do some default rendering of name-value pairs, but only if at least "stated in", "reference URL" or "title" is present
      		elseif params[aliasesP.statedIn] or params[aliasesP.referenceURL] or params[aliasesP.title] then
      			citeParams['default'] = {}
      
      			-- start by adding authors up front
      			if params[aliasesP.author] and #params[aliasesP.author] > 0 then
      				citeParams['default'][#citeParams['default'] + 1] = table.concat(params[aliasesP.author], " & ")
      			end
      
      			-- combine "reference URL" and "title" into one link if both are present
      			if params[aliasesP.referenceURL] and params[aliasesP.title] then
      				citeParams['default'][#citeParams['default'] + 1] = '[' .. params[aliasesP.referenceURL][1] .. ' "' .. params[aliasesP.title][1] .. '"]'
      			elseif params[aliasesP.referenceURL] then
      				citeParams['default'][#citeParams['default'] + 1] = params[aliasesP.referenceURL][1]
      			elseif params[aliasesP.title] then
      				citeParams['default'][#citeParams['default'] + 1] = '"' .. params[aliasesP.title][1] .. '"'
      			end
      
      			-- then add "stated in"
      			if params[aliasesP.statedIn] then
      				citeParams['default'][#citeParams['default'] + 1] = "''" .. params[aliasesP.statedIn][1] .. "''"
      			end
      
      			-- remove previously added parameters so that they won't be added a second time
      			params[aliasesP.author] = nil
      			params[aliasesP.referenceURL] = nil
      			params[aliasesP.title] = nil
      			params[aliasesP.statedIn] = nil
      
      			-- add the rest of the parameters
      			for i, v in pairs(params) do
      				i = self.conf:getLabel(i)
      
      				if i ~= "" then
      					citeParams['default'][#citeParams['default'] + 1] = i .. ": " .. v[1]
      				end
      			end
      
      			value = table.concat(citeParams['default'], "; ")
      
      			if value ~= "" then
      				value = value .. "."
      			end
      		end
      
      		if value ~= "" then
      			value = {value}  -- create one value object
      
      			if not self.rawValue then
      				-- this should become a <ref> tag, so save the reference's hash for later
      				value.refHash = "wikidata-" .. statement.hash .. "-v" .. (tonumber(i18n['cite']['version']) + version)
      			end
      
      			ref = {value}  -- wrap the value object in an array
      		end
      	end
      
      	return ref
      end
      
      -- gets a detail of one particular type for a reference
      function State:getReferenceDetail(snaks, dType, raw, link, anyLang)
      	local switchLang = anyLang
      	local value = nil
      
      	if not snaks[dType] then
      		return nil
      	end
      
      	-- if anyLang, first try the local language and otherwise any language
      	repeat
      		for _, v in ipairs(snaks[dType]) do
      			value = self.conf:getValue(v, raw, link, false, anyLang and not switchLang, false, true)  -- noSpecial = true
      
      			if value then
      				break
      			end
      		end
      
      		if value or not anyLang then
      			break
      		end
      
      		switchLang = not switchLang
      	until anyLang and switchLang
      
      	return value
      end
      
      -- gets the details of one particular type for a reference
      function State:getReferenceDetails(snaks, dType, raw, link, anyLang)
      	local values = {}
      
      	if not snaks[dType] then
      		return {}
      	end
      
      	for _, v in ipairs(snaks[dType]) do
      		-- if nil is returned then it will not be added to the table
      		values[#values + 1] = self.conf:getValue(v, raw, link, false, anyLang, false, true)  -- noSpecial = true
      	end
      
      	return values
      end
      
      -- level 1 hook
      function State:getAlias(object)
      	local value = object.value
      	local title = nil
      
      	if value and self.linked then
      		if self.conf.entityID:sub(1,1) == "Q" then
      			title = mw.wikibase.getSitelink(self.conf.entityID)
      		elseif self.conf.entityID:sub(1,1) == "P" then
      			title = "d:Property:" .. self.conf.entityID
      		end
      
      		if title then
      			value = buildWikilink(title, value)
      		end
      	end
      
      	value = {value}  -- create one value object
      
      	if #value > 0 then
      		return {value}  -- wrap the value object in an array and return it
      	else
      		return {}  -- return empty array if there was no value
      	end
      end
      
      -- level 1 hook
      function State:getBadge(value)
      	value = self.conf:getLabel(value, self.rawValue, self.linked, self.shortName)
      
      	if value == "" then
      		value = nil
      	end
      
      	value = {value}  -- create one value object
      
      	if #value > 0 then
      		return {value}  -- wrap the value object in an array and return it
      	else
      		return {}  -- return empty array if there was no value
      	end
      end
      
      function State:callHook(param, hooks, statement, result)
      	local valuesArray, refHash
      
      	-- call a parameter's hook if it has been defined and if it has not been called before
      	if not result[param] and hooks[param] then
      		valuesArray = self[hooks[param]](self, statement, param, result, hooks)  -- array with value objects
      
      		-- add to the result
      		if #valuesArray > 0 then
      			result[param] = valuesArray
      			result.count = result.count + 1
      		else
      			result[param] = {}  -- an empty array to indicate that we've tried this hook already
      			return true  -- miss == true
      		end
      	end
      
      	return false
      end
      
      -- iterate through claims, claim's qualifiers or claim's references to collect values
      function State:iterate(statements, hooks, matchHook)
      	matchHook = matchHook or alwaysTrue
      
      	local matches = false
      	local rankPos = nil
      	local result, gotRequired
      
      	for _, v in ipairs(statements) do
      		-- rankPos will be nil for non-claim statements (e.g. qualifiers, references, etc.)
      		matches, rankPos = matchHook(self, v)
      
      		if matches then
      			result = {count = 0}  -- collection of arrays with value objects
      
      			local function walk(formatTable)
      				local miss
      
      				for i2, v2 in pairs(formatTable.req) do
      					-- call a hook, adding its return value to the result
      					miss = self:callHook(i2, hooks, v, result)
      
      					if miss then
      						-- we miss a required value for this level, so return false
      						return false
      					end
      
      					if result.count == hooks.count then
      						-- we're done if all hooks have been called;
      						-- returning at this point breaks the loop
      						return true
      					end
      				end
      
      				for _, v2 in ipairs(formatTable) do
      					if result.count == hooks.count then
      						-- we're done if all hooks have been called;
      						-- returning at this point prevents further childs from being processed
      						return true
      					end
      
      					if v2.child then
      						walk(v2.child)
      					end
      				end
      
      				return true
      			end
      			gotRequired = walk(self.parsedFormat)
      
      			-- only append the result if we got values for all required parameters on the root level
      			if gotRequired then
      				-- if we have a rankPos (only with matchHook() for complete claims), then update the foundRank
      				if rankPos and self.conf.foundRank > rankPos then
      					self.conf.foundRank = rankPos
      				end
      
      				-- append the result
      				self.results[#self.results + 1] = result
      
      				-- break if we only need a single value
      				if self.singleValue then
      					break
      				end
      			end
      		end
      	end
      
      	return self:out()
      end
      
      local function getEntityId(arg, eid, page, allowOmitPropPrefix)
      	local id = nil
      	local prop = nil
      
      	if arg then
      		if arg:sub(1,1) == ":" then
      			page = arg
      			eid = nil
      		elseif arg:sub(1,1):upper() == "Q" or arg:sub(1,9):lower() == "property:" or allowOmitPropPrefix then
      			eid = arg
      			page = nil
      		else
      			prop = arg
      		end
      	end
      
      	if eid then
      		if eid:sub(1,9):lower() == "property:" then
      			id = replaceAlias(mw.text.trim(eid:sub(10)))
      
      			if id:sub(1,1):upper() ~= "P" then
      				id = ""
      			end
      		else
      			id = replaceAlias(eid)
      		end
      	elseif page then
      		if page:sub(1,1) == ":" then
      			page = mw.text.trim(page:sub(2))
      		end
      
      		id = mw.wikibase.getEntityIdForTitle(page) or ""
      	end
      
      	if not id then
      		id = mw.wikibase.getEntityIdForCurrentPage() or ""
      	end
      
      	id = id:upper()
      
      	if not mw.wikibase.isValidEntityId(id) then
      		id = ""
      	end
      
      	return id, prop
      end
      
      local function nextArg(args)
      	local arg = args[args.pointer]
      
      	if arg then
      		args.pointer = args.pointer + 1
      		return mw.text.trim(arg)
      	else
      		return nil
      	end
      end
      
      local function claimCommand(args, funcName)
      	local cfg = Config:new()
      	cfg:processFlagOrCommand(funcName)  -- process first command (== function name)
      
      	local lastArg, parsedFormat, formatParams, claims, value
      	local hooks = {count = 0}
      
      	-- set the date if given;
      	-- must come BEFORE processing the flags
      	if args[p.args.date] then
      		cfg.atDate = {parseDate(args[p.args.date])}
      		cfg.periods = {false, true, false}  -- change default time constraint to 'current'
      	end
      
      	-- process flags and commands
      	repeat
      		lastArg = nextArg(args)
      	until not cfg:processFlagOrCommand(lastArg)
      
      	-- get the entity ID from either the positional argument, the eid argument or the page argument
      	cfg.entityID, cfg.propertyID = getEntityId(lastArg, args[p.args.eid], args[p.args.page])
      
      	if cfg.entityID == "" then
      		return ""  -- we cannot continue without a valid entity ID
      	end
      
      	cfg.entity = mw.wikibase.getEntity(cfg.entityID)
      
      	if not cfg.propertyID then
      		cfg.propertyID = nextArg(args)
      	end
      
      	cfg.propertyID = replaceAlias(cfg.propertyID)
      
      	if not cfg.entity or not cfg.propertyID then
      		return ""  -- we cannot continue without an entity or a property ID
      	end
      
      	cfg.propertyID = cfg.propertyID:upper()
      
      	if not cfg.entity.claims or not cfg.entity.claims[cfg.propertyID] then
      		return ""  -- there is no use to continue without any claims
      	end
      
      	claims = cfg.entity.claims[cfg.propertyID]
      
      	if cfg.states.qualifiersCount > 0 then
      		-- do further processing if "qualifier(s)" command was given
      
      		if #args - args.pointer + 1 > cfg.states.qualifiersCount then
      			-- claim ID or literal value has been given
      
      			cfg.propertyValue = nextArg(args)
      		end
      
      		for i = 1, cfg.states.qualifiersCount do
      			-- check if given qualifier ID is an alias and add it
      			cfg.qualifierIDs[parameters.qualifier..i] = replaceAlias(nextArg(args) or ""):upper()
      		end
      	elseif cfg.states[parameters.reference] then
      		-- do further processing if "reference(s)" command was given
      
      		cfg.propertyValue = nextArg(args)
      	end
      
      	-- check for special property value 'somevalue' or 'novalue'
      	if cfg.propertyValue then
      		cfg.propertyValue = replaceSpecialChars(cfg.propertyValue)
      
      		if cfg.propertyValue ~= "" and mw.text.trim(cfg.propertyValue) == "" then
      			cfg.propertyValue = " "  -- single space represents 'somevalue', whereas empty string represents 'novalue'
      		else
      			cfg.propertyValue = mw.text.trim(cfg.propertyValue)
      		end
      	end
      
      	-- parse the desired format, or choose an appropriate format
      	if args["format"] then
      		parsedFormat, formatParams = parseFormat(args["format"])
      	elseif cfg.states.qualifiersCount > 0 then  -- "qualifier(s)" command given
      		if cfg.states[parameters.property] then  -- "propert(y|ies)" command given
      			parsedFormat, formatParams = parseFormat(formats.propertyWithQualifier)
      		else
      			parsedFormat, formatParams = parseFormat(formats.qualifier)
      		end
      	elseif cfg.states[parameters.property] then  -- "propert(y|ies)" command given
      		parsedFormat, formatParams = parseFormat(formats.property)
      	else  -- "reference(s)" command given
      		parsedFormat, formatParams = parseFormat(formats.reference)
      	end
      
      	-- if a "qualifier(s)" command and no "propert(y|ies)" command has been given, make the movable separator a semicolon
      	if cfg.states.qualifiersCount > 0 and not cfg.states[parameters.property] then
      		cfg.separators["sep"..parameters.separator][1] = {";"}
      	end
      
      	-- if only "reference(s)" has been given, set the default separator to none (except when raw)
      	if cfg.states[parameters.reference] and not cfg.states[parameters.property] and cfg.states.qualifiersCount == 0
      	   and not cfg.states[parameters.reference].rawValue then
      		cfg.separators["sep"][1] = nil
      	end
      
      	-- if exactly one "qualifier(s)" command has been given, make "sep%q" point to "sep%q1" to make them equivalent
      	if cfg.states.qualifiersCount == 1 then
      		cfg.separators["sep"..parameters.qualifier] = cfg.separators["sep"..parameters.qualifier.."1"]
      	end
      
      	-- process overridden separator values;
      	-- must come AFTER tweaking the default separators
      	cfg:processSeparators(args)
      
      	-- define the hooks that should be called (getProperty, getQualifiers, getReferences);
      	-- only define a hook if both its command ("propert(y|ies)", "reference(s)", "qualifier(s)") and its parameter ("%p", "%r", "%q1", "%q2", "%q3") have been given
      	for i, v in pairs(cfg.states) do
      		-- e.g. 'formatParams["%q1"] or formatParams["%q"]' to define hook even if "%q1" was not defined to be able to build a complete value for "%q"
      		if formatParams[i] or formatParams[i:sub(1, 2)] then
      			hooks[i] = getHookName(i, 1)
      			hooks.count = hooks.count + 1
      		end
      	end
      
      	-- the "%q" parameter is not attached to a state, but is a collection of the results of multiple states (attached to "%q1", "%q2", "%q3", ...);
      	-- so if this parameter is given then this hook must be defined separately, but only if at least one "qualifier(s)" command has been given
      	if formatParams[parameters.qualifier] and cfg.states.qualifiersCount > 0 then
      		hooks[parameters.qualifier] = getHookName(parameters.qualifier, 1)
      		hooks.count = hooks.count + 1
      	end
      
      	-- create a state for "properties" if it doesn't exist yet, which will be used as a base configuration for each claim iteration;
      	-- must come AFTER defining the hooks
      	if not cfg.states[parameters.property] then
      		cfg.states[parameters.property] = State:new(cfg, parameters.property)
      
      		-- if the "single" flag has been given then this state should be equivalent to "property" (singular)
      		if cfg.singleClaim then
      			cfg.states[parameters.property].singleValue = true
      		end
      	end
      
      	-- if the "sourced" flag has been given then create a state for "reference" if it doesn't exist yet, using default values,
      	-- which must exist in order to be able to determine if a claim has any references;
      	-- must come AFTER defining the hooks
      	if cfg.sourcedOnly and not cfg.states[parameters.reference] then
      		cfg:processFlagOrCommand(p.claimCommands.reference)  -- use singular "reference" to minimize overhead
      	end
      
      	-- set the parsed format and the separators (and optional punctuation mark);
      	-- must come AFTER creating the additonal states
      	cfg:setFormatAndSeparators(cfg.states[parameters.property], parsedFormat)
      
      	-- process qualifier matching values, analogous to cfg.propertyValue
      	for i, v in pairs(args) do
      		i = tostring(i)
      
      		if i:match('^[Pp]%d+$') or aliasesP[i] then
      			v = replaceSpecialChars(v)
      
      			-- check for special qualifier value 'somevalue'
      			if v ~= "" and mw.text.trim(v) == "" then
      				v = " "  -- single space represents 'somevalue'
      			end
      
      			cfg.qualifierIDsAndValues[replaceAlias(i):upper()] = v
      		end
      	end
      
      	-- first sort the claims on rank to pre-define the order of output (preferred first, then normal, then deprecated)
      	claims = sortOnRank(claims)
      
      	-- then iterate through the claims to collect values
      	value = cfg:concatValues(cfg.states[parameters.property]:iterate(claims, hooks, State.claimMatches))  -- pass property state with level 1 hooks and matchHook
      
      	-- if desired, add a clickable icon that may be used to edit the returned values on Wikidata
      	if cfg.editable and value ~= "" then
      		value = value .. cfg:getEditIcon()
      	end
      
      	return value
      end
      
      local function generalCommand(args, funcName)
      	local cfg = Config:new()
      	cfg.curState = State:new(cfg)
      
      	local lastArg
      	local value = nil
      
      	repeat
      		lastArg = nextArg(args)
      	until not cfg:processFlag(lastArg)
      
      	-- get the entity ID from either the positional argument, the eid argument or the page argument
      	cfg.entityID = getEntityId(lastArg, args[p.args.eid], args[p.args.page], true)
      
      	if cfg.entityID == "" or not mw.wikibase.entityExists(cfg.entityID) then
      		return ""  -- we cannot continue without an entity
      	end
      
      	-- serve according to the given command
      	if funcName == p.generalCommands.label then
      		value = cfg:getLabel(cfg.entityID, cfg.curState.rawValue, cfg.curState.linked, cfg.curState.shortName)
      	elseif funcName == p.generalCommands.title then
      		cfg.inSitelinks = true
      
      		if cfg.entityID:sub(1,1) == "Q" then
      			value = mw.wikibase.getSitelink(cfg.entityID)
      		end
      
      		if cfg.curState.linked and value then
      			value = buildWikilink(value)
      		end
      	elseif funcName == p.generalCommands.description then
      		value = mw.wikibase.getDescription(cfg.entityID)
      	else
      		local parsedFormat, formatParams
      		local hooks = {count = 0}
      
      		cfg.entity = mw.wikibase.getEntity(cfg.entityID)
      
      		if funcName == p.generalCommands.alias or funcName == p.generalCommands.badge then
      			cfg.curState.singleValue = true
      		end
      
      		if funcName == p.generalCommands.alias or funcName == p.generalCommands.aliases then
      			if not cfg.entity.aliases or not cfg.entity.aliases[cfg.langCode] then
      				return ""  -- there is no use to continue without any aliasses
      			end
      
      			local aliases = cfg.entity.aliases[cfg.langCode]
      
      			-- parse the desired format, or parse the default aliases format
      			if args["format"] then
      				parsedFormat, formatParams = parseFormat(args["format"])
      			else
      				parsedFormat, formatParams = parseFormat(formats.alias)
      			end
      
      			-- process overridden separator values;
      			-- must come AFTER tweaking the default separators
      			cfg:processSeparators(args)
      
      			-- define the hook that should be called (getAlias);
      			-- only define the hook if the parameter ("%a") has been given
      			if formatParams[parameters.alias] then
      				hooks[parameters.alias] = getHookName(parameters.alias, 1)
      				hooks.count = hooks.count + 1
      			end
      
      			-- set the parsed format and the separators (and optional punctuation mark)
      			cfg:setFormatAndSeparators(cfg.curState, parsedFormat)
      
      			-- iterate to collect values
      			value = cfg:concatValues(cfg.curState:iterate(aliases, hooks))
      		elseif funcName == p.generalCommands.badge or funcName == p.generalCommands.badges then
      			if not cfg.entity.sitelinks or not cfg.entity.sitelinks[cfg.siteID] or not cfg.entity.sitelinks[cfg.siteID].badges then
      				return ""  -- there is no use to continue without any badges
      			end
      
      			local badges = cfg.entity.sitelinks[cfg.siteID].badges
      
      			cfg.inSitelinks = true
      
      			-- parse the desired format, or parse the default aliases format
      			if args["format"] then
      				parsedFormat, formatParams = parseFormat(args["format"])
      			else
      				parsedFormat, formatParams = parseFormat(formats.badge)
      			end
      
      			-- process overridden separator values;
      			-- must come AFTER tweaking the default separators
      			cfg:processSeparators(args)
      
      			-- define the hook that should be called (getBadge);
      			-- only define the hook if the parameter ("%b") has been given
      			if formatParams[parameters.badge] then
      				hooks[parameters.badge] = getHookName(parameters.badge, 1)
      				hooks.count = hooks.count + 1
      			end
      
      			-- set the parsed format and the separators (and optional punctuation mark)
      			cfg:setFormatAndSeparators(cfg.curState, parsedFormat)
      
      			-- iterate to collect values
      			value = cfg:concatValues(cfg.curState:iterate(badges, hooks))
      		end
      	end
      
      	value = value or ""
      
      	if cfg.editable and value ~= "" then
      		-- if desired, add a clickable icon that may be used to edit the returned value on Wikidata
      		value = value .. cfg:getEditIcon()
      	end
      
      	return value
      end
      
      -- modules that include this module should call the functions with an underscore prepended, e.g.: p._property(args)
      local function establishCommands(commandList, commandFunc)
      	for _, commandName in pairs(commandList) do
      		local function wikitextWrapper(frame)
      			local args = copyTable(frame.args)
      			args.pointer = 1
      			loadI18n(aliasesP, frame)
      			return commandFunc(args, commandName)
      		end
      		p[commandName] = wikitextWrapper
      
      		local function luaWrapper(args)
      			args = copyTable(args)
      			args.pointer = 1
      			loadI18n(aliasesP)
      			return commandFunc(args, commandName)
      		end
      		p["_" .. commandName] = luaWrapper
      	end
      end
      
      establishCommands(p.claimCommands, claimCommand)
      establishCommands(p.generalCommands, generalCommand)
      
      -- main function that is supposed to be used by wrapper templates
      function p.main(frame)
      	local f, args
      
      	loadI18n(aliasesP, frame)
      
      	-- get the parent frame to take the arguments that were passed to the wrapper template
      	frame = frame:getParent() or frame
      
      	if not frame.args[1] then
      		throwError("no-function-specified")
      	end
      
      	f = mw.text.trim(frame.args[1])
      
      	if f == "main" then
      		throwError("main-called-twice")
      	end
      
      	assert(p["_"..f], errorText('no-such-function', f))
      
      	-- copy arguments from immutable to mutable table
      	args = copyTable(frame.args)
      
      	-- remove the function name from the list
      	table.remove(args, 1)
      
      	return p["_"..f](args)
      end
      
      return p
      
      Cookies helpen ons onze services aan te bieden. Door onze services te gebruiken stemt u in met het gebruik van onze cookies.