Aller au contenu

Module:European and national party data

Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 28 mars 2025 à 16:54 et modifiée en dernier par Julius Schwarz (discuter | contributions) (Change reference config file). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

 Documentation[voir] [modifier] [historique] [purger]

Usage

{{#invoke:European and national party data|main|<type_de_parti>|<type_de_données>|<parti>|<institution>|paramètres supplémentaires}}

Paramètres

Paramètre Description
1 Le type de parti considéré ; peut être soit :

Ce paramètre est obligatoire.

2 Le type de données demandées et extraites de Wikidata, à partir de la liste suivante :
  • sieges : le nombre de sièges d'une ou plusieurs entités dans une ou plusieurs institutions (P1410) ;
  • part des sieges : la part des sièges d'une ou plusieurs entités dans une ou plusieurs institutions (sur la base de P1410) ;
  • barre de composition des sieges : une barre de composition montrant les sièges d'une ou plusieurs entités dans une ou plusieurs institutions (sur la base de P1410) ;
  • acronyme : le nom court de l'entité (P1813) ;
  • couleur : la couleur officielle de l'entité sous forme de code hexadécimal (P465) ;
  • pays : le pays dans lequel l'entité est enregistrée (P17) ;
  • date de fondation : la date à laquelle l'entité a été fondée (P571) ;
  • membres individuels : le nombre de membres individuels de l'entité (P2124) ;
  • date membres individuels : la date de référence pour le nombre de membres individuels de l'entité (sur la base de P2124) ;
  • étiquette : le nom de l'entité ;
  • nom officiel : le nom officiel détaillé de l'entité (P1448) ;
  • groupe parlementaire : le groupe parlementaire auquel appartient l'entité (P4100) ;
  • financement public : le montant du financement public reçu par l'entité (P12919) ; ou
  • site web : le site web officiel de l'entité (P856), sans les préfixes « https », « http » et « www ».

Ce paramètre est obligatoire.

3 Le nom de l'entité, à partir de la liste suivante :
  • dans tous les cas, le nom peut être omis lorsque le module est appelé à partir de la page Wikipédia de l'entité (alternativement, ceparti peut être utilisé pour se référer à l'entité en question) ;
  • pour les entités européennes : l'acronyme de l'entité (voir la liste ci-dessous) ou son qID Wikidata ; et
  • pour les partis nationaux : le qID Wikidata du parti.

Ce paramètre est facultatif lorsqu'il est appelé à partir de la page de l'entité en question.

Les acronymes suivants sont utilisés pour les partis européens :

En outre, les alliances politiques européennes suivantes sont couvertes :

En outre, quatre paramètres spéciaux peuvent être utilisés à la place des partis européens (donc pas avec |party_type=national_party) :

  • all : pour les sièges de tous les partis européens combinés ;
  • none : pour les sièges non occupés par des membres de partis européens (pas pour les chambres basse et haute) ; et
  • ind : pour les politiciens indépendants siégeant au Conseil européen (uniquement).

Notes :

  • la majuscule des paramètres n'a pas d'importance ;
  • étant donné le coût de l'appel à Wikidata lors de l'utilisation d'un qID spécifique (c'est-à-dire sans appeler Wikidata à partir d'une page Wikipédia liée), le paramètre spécial « ceparti » devrait être utilisé chaque fois que ce module est appelé à partir de la page d'un parti européen ; et
  • étant donné que les alliances politiques européennes énumérées ne sont pas des partis politiques européens, elles ne comptent pas dans la somme des sièges occupés par les partis politiques européens, ni dans les sièges non occupés par les partis politiques européens.
4 Le nom de l'institution, à partir de la liste suivante :

Notes :

  • Pour les chambres basses et hautes des partis nationaux, le module déterminera automatiquement l'organe concerné, en utilisant ce tableau ;
  • Pour les chambres basses et hautes des partis européens, le module additionnera le nombre de sièges de leurs partis membres dans tous les États membres ; et
  • Pour le Parlement européen pour les partis nationaux, le module utilisera automatiquement le nombre de sièges de l'État membre au Parlement.

Ce paramètre est obligatoire lorsque le type de données est sieges, part des sieges ou barre de composition des sieges.

paramètres supplémentaires Les paramètres supplémentaires suivants peuvent également être utilisés, en fonction du type_de_données demandé :
  • tous les types de données :
    • reference affiche la référence lorsque |reference=yes (ce paramètre est ignoré pour les sièges des chambres basses ou hautes des entités européennes, car de nombreux chiffres nationaux sont additionnés) ;
  • part des sieges :
    • circonscription remplace le nombre de sièges de l'institution (par exemple, lorsque le parti fait partie d'une circonscription spéciale) ;
  • barre de composition des sieges :
    • circonscription remplace le nombre de sièges de l'institution (par exemple, lorsque le parti fait partie d'une circonscription spéciale) ; barre de composition des sièges : la largeur spécifiera la largeur de la barre ;
    • largeur spécifie la largeur de la barre et peut avoir les formats suivants : « 80 » (l'unité par défaut est le pixel), “80px”, “80em”, ou “80%” (sans espace) ;
    • pourcent affiche le pourcentage lorsque |pourcent=oui ;
    • couleur-de-barre, bordure et couleur-de-fond remplacent les couleurs par défaut lorsqu'une valeur hexadécimale (par exemple « #123ABC », y compris le dièse) ou une couleur reconnue (par exemple « rouge ») est fournie.
  • tous les autres types de données :
    • verbose : affiche un message d'erreur si aucune valeur n'existe sur Wikidata, ainsi qu'un lien pertinent, lorsque |verbose=oui (sinon le champ est vide).

Ces paramètres sont facultatifs.

Notes : dans la version française, les paramètres largeur, couleur-de-barre, bordure et couleur-de-fond existent dans le code mais ne fonctionnent pas pour la barre de composition car ils n'existent pas dans le modèle Wikidata. De la même maniere, reference ne fonctionne pas pour la barre de composition car il ne peut pas être fourni de manière indépendante d'une valeur.

Modèles liés

Le module est directement implémenté par deux modèles :

Tests

Le module comporte deux pages de tests :

Mise à jour du module

Le module tire ses données de deux sources :

Pour mettre à jour les données renvoyées par le module, rendez-vous sur la page Wikidata de l'entité en question (le lien est souvent fourni sous forme de commentaire dans l'infobox de l'article de Wikipédia), et modifiez la propriété concernée, de préférence en ajoutant une nouvelle valeur et en la marquant comme rang préféré (au lieu de supprimer les informations obsolètes).

Voici une liste de propriétés pertinentes pour le module :

  • nombre de sièges dans une assemblée : P1410, avec les qualificatifs suivants :
    • assemblée délibérante : P194
    • exécutif (pour la Commission européenne et le Conseil européen) : P208
    • législature (pour le Parlement européen et la Commission européenne) : P2937
  • nom court/acronyme : P1813
  • couleur (triplet hexadécimal sRGB) : P465
  • pays : P17
  • date de fondation ou de création : P571
  • nombre de membres/membres individuels : P2124
  • nom officiel : P1448
  • groupe parlementaire : P4100
  • financement public : P12919
  • site officiel : P856

À chaque fois que c'est possible, essayez d'ajouter :

  • un qualificateur de date de début (P580), et de date de fin (P582) équivalente dans l'entrée obsolète, ou un qualificateur de date (P585) ; et
  • une référence, y compris des qualificateurs de URL de la référence (P854), titre (P1476), date de consultation (P813), and publié par (P123).

La mise à jour de Wikidata garantit que les informations mises à jour et sourcées sont disponibles non seulement pour ce Wiki, mais aussi pour toutes les versions de Wikipédia, ainsi que pour les autres services qui tirent des informations de Wikidata.

Exemples

Type de données sieges

Code Résultat
{{#invoke:European and national party data|main|entite_europeenne|sieges|PPE|PE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges du Parti populaire européen au Parlement européen
{{#invoke:European and national party data|main|entite_europeenne|sieges|PSE|CE|reference=oui}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges du Parti socialiste européen à la Commission européenne, avec référence
{{#invoke:European and national party data|main|entite_europeenne|sieges|ind|EUCO}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges de politiciens indépendants au Conseil européen
{{#invoke:European and national party data|main|entite_europeenne|sieges|ALDE|chambre-basse}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges de l'Alliance des démocrates et des libéraux pour l'Europe dans les chambres basses des États membres
{{#invoke:European and national party data|main|entite_europeenne|sieges|PVE|chambre-haute|reference=oui}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges du Parti vert européen dans les chambres hautes des Etats membres, sans référence (voir tableau ci-dessus)
{{#invoke:European and national party data|main|entite_europeenne|sieges|Q208242|CE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges du Parti populaire européen (appelé par son qID Wikidata) à la Commission européenne
{{#invoke:European and national party data|main|entite_europeenne|sieges|Q208242|chambre-haute}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges du Parti populaire européen (appelé par son qID Wikidata) dans les chambres hautes des États membres
{{#invoke:European and national party data|main|parti_national|sieges|Q13564543|chambre-basse|reference=oui}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) nombre de sièges du parti autrichien NEOS (appelé par son qID Wikidata) au Conseil national, avec référence
{{#invoke:European and national party data|main|parti_national|sieges|Q138198|chambre-haute}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) nombre de sièges du Parti socialiste ouvrier espagnol (appelé par son qID Wikidata) au Sénat
{{#invoke:European and national party data|main|parti_national|sieges|Q49768|PE}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) nombre de sièges du Parti social-démocrate allemand (appelé par son qID Wikidata) au Parlement européen
{{#invoke:European and national party data|main|entite_europeenne|sieges|tous|PE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges de tous les partis européens réunis au Parlement européen
{{#invoke:European and national party data|main|entite_europeenne|sieges|aucun|PE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nombre de sièges non occupés par des partis européens au Parlement européen

Type de données part de sieges

Code Résultat
{{#invoke:European and national party data|main|entite_europeenne|part des sieges|PPE|PE|reference=oui}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) part des sièges du Parti populaire européen au Parlement européen, avec référence
{{#invoke:European and national party data|main|entite_europeenne|part des sieges|ind|EUCO}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) part des sièges occupés par des personnalités politiques indépendantes au Conseil européen
{{#invoke:European and national party data|main|entite_europeenne|part des sieges|ALDE|chambre-basse}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) part des sièges de l'Alliance des démocrates et des libéraux pour l'Europe dans les chambres basses des États membres
{{#invoke:European and national party data|main|entite_europeenne|part des sieges|Q208242|CE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) part des sièges du Parti populaire européen (appelé par son qID Wikidata) à la Commission européenne
{{#invoke:European and national party data|main|parti_national|part des sieges|Q13564543|chambre-basse}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) part des sièges du parti autrichien NEOS (appelé par son qID Wikidata) au Conseil national
{{#invoke:European and national party data|main|parti_national|part des sieges|Q655611|chambre-basse|circonscription=61}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) part des sièges du parti belge Écolo (appelé par son qID Wikidata) dans les sièges francophones de la Chambre des représentants
{{#invoke:European and national party data|main|parti_national|part des sieges|Q49768|PE|reference=oui}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) part des sièges du Parti social-démocrate allemand (appelé par son qID Wikidata) au Parlement européen, avec référence
{{#invoke:European and national party data|main|entite_europeenne|part des sieges|tous|PE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) part des sièges de tous les partis européens réunis au Parlement européen

Type de données barre de composition des sieges

Code Résultat
{{#invoke:European and national party data|main|entite_europeenne|barre de composition des sieges|PPE|PE|reference=oui}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) barre de composition des sièges du Parti populaire européen au Parlement européen, avec référence
{{#invoke:European and national party data|main|entite_europeenne|barre de composition des sieges|ind|EUCO|pourcent=oui}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) barre de composition des sièges des personnalités politiques indépendantes au sein du Conseil européen, avec référence
{{#invoke:European and national party data|main|entite_europeenne|barre de composition des sieges|ALDE|chambre-basse}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) barre de composition des sièges de l'Alliance des démocrates et des libéraux pour l'Europe dans les chambres basses des états membres
{{#invoke:European and national party data|main|entite_europeenne|barre de composition des sieges|Q208242|CE|pourcent=oui|reference=oui}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) barre de composition des sièges du Parti populaire européen (appelé par son qID Wikidata) à la Commission européenne, avec référence
{{#invoke:European and national party data|main|parti_national|barre de composition des sieges|Q655611|chambre-basse|circonscription=61}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) barre de composition des sièges du parti belge Écolo (appelé par son qID Wikidata) dans les sièges francophones de la Chambre des représentants
{{#invoke:European and national party data|main|parti_national|barre de composition des sieges|Q49768|PE|largeur=80%|couleur-de-fond=blue|bordure=green|couleur-de-barre=red}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) barre de composition des sièges du Parti social-démocrate allemand (appelé par son qID Wikidata) au Parlement européen, avec des paramètres spéciaux
{{#invoke:European and national party data|main|entite_europeenne|barre de composition des sieges|tous|PE|largeur=80%|couleur-de-fond=#FFFF00|bordure=#008080|couleur-de-barre=#A020F0}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) barre de composition des sièges de tous les partis européens réunis au Parlement européen, avec des paramètres spéciaux

Autres type de données

Code Result
{{#invoke:European and national party data|main|entite_europeenne|acronyme|PPE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) acronyme du Parti populaire européen
{{#invoke:European and national party data|main|entite_europeenne|couleur|PSE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) couleur du Parti socialiste européen
{{#invoke:European and national party data|main|entite_europeenne|couleur|PSE}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) pays du parti Levice (appelé par son qID Wikidata)
{{#invoke:European and national party data|main|entite_europeenne|date de fondation|PSE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) date de fondation du Parti socialiste européen
{{#invoke:European and national party data|main|entite_europeenne|membres individuels|PPE|reference=oui}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) des membres individuels du Parti populaire européen, avec référence
{{#invoke:European and national party data|main|entite_europeenne|label|ALDE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) label de l'Alliance des démocrates et des libéraux pour l'Europe
{{#invoke:European and national party data|main|entite_europeenne|nom officiel|PVE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) nom officiel du Parti vert européen
{{#invoke:European and national party data|main|entite_europeenne|groupe parlementaire|ALE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) groupe parlementaire de l'Alliance libre européenne
{{#invoke:European and national party data|main|entite_europeenne|financement public|PVE}} Error: {{Sièges PPEU}}: unknown institution: ENTITE_EUROPEENNE (help) financement public du parti vert européen, avec référence
{{#invoke:European and national party data|main|parti_national|site web|Q667680}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) Site web du parti néerlandais GroenLinks
{{#invoke:European and national party data|main|parti_national|nom officiel|Q22748|verbose=oui}} Error: {{Sièges PPEU}}: unknown institution: PARTI_NATIONAL (help) nom officiel du parti allemand Die PARTEI, affichant un message d'erreur


require ('strict');
local get_args = require ('Module:Arguments').getArgs;							-- function to fetch frame and parent frame arguments
local cfg = mw.loadData ('Module:Sièges PPEU/config');							-- defines, configuration data, and i18n support
local namespace = mw.title.getCurrentTitle().namespace;							-- used for categorization


--[[--------------------------< S U B S T I T U T E >----------------------------------------------------------

Substitutes $1, $2, etc in <message> with data from <data_t>. Returns plain-text substituted string when
<data_t> not nil; returns <message> else.

]]

local function substitute (message, data_t)
	return data_t and mw.message.newRawMessage (message, data_t):plain() or message;
end


--[[--------------------------< M A K E _ E R R O R _ M S G >--------------------------------------------------

Assembles an error message from template name, message text, help link, and error category.

]]

local function make_error_msg (msg, template_name, nocat)
	local category;

	local category_link = ((0 == namespace) and not nocat) and substitute ('[[Category:$1]]', {cfg.settings_t.err_category}) or '';
	return substitute ('<span style="color:#d33">Error: {{$1}}: $2 ([[:Template:$1|$3]])</span>$4',
		{
		template_name or cfg.settings_t.template_name,							-- the template name without namespace
		msg,																	-- the error message
		cfg.settings_t.help,													-- help wikilink display text
		category_link															-- link to error category (main namespace only)
		})
end
	

--[[--------------------------< R O U N D >--------------------------------------------------------------------

return the rounded value of the arguments with two digits

]]

local function round (n)
  return math.floor(100 * n + 0.5) / 100
end


--[[--------------------------< S U M >------------------------------------------------------------------------

return the sum of seats for all parties of <institution> listed in <cfg.parties_t>.  <body_prop> is the wikidata
property:
	P194: legislative body
	P208: executive body

<frame> required to expand {{wikidata}} template 

Note: P1410 is the property "number of seats in assembly", used to record an entity's seats in legislative or executive bodies

]]

local function sum (frame, institution, body_prop)
	local sum = 0;																-- init

	local args_t = {[1]='property', [3]='P1410'};								-- init some of the {{wikidata}} parameters
	args_t[body_prop] = cfg.institutions_t[institution];

	for _, qid in pairs (cfg.parties_t) do										-- loop through all parties in <cfg.parties_t>
		args_t[2] = qid;														-- set the last {{wikidata}} parameter
		sum = sum + frame:expandTemplate ({title='wikidata', args = args_t});	-- expand and tally
	end

	return sum;
end


--[[--------------------------< G E T _ C O L O U R >----------------------------------------------------------

return the hex colour of a European party with '#' prefix

<frame> required to expand {{wikidata}} template

]]

local function get_colour (frame, party)
	local args_t = {'property'};												-- build an arguments table for expandTemplate()
	if party ~= "THISPARTY" then												-- when not on a party page
		table.insert (args_t, cfg.parties_t[party]);							-- must name the party
	end
	table.insert (args_t, 'P465');												-- last argument is P465; sRGB color hex triplet property
	
	local color = frame:expandTemplate ({title='wikidata', args = args_t});		-- get the color
	if '' == color then															-- if no color
		color = 'BBB';															-- use a default color; some sort of gray
	end
	return '#' .. color;														-- add the '#' prefix
end


--[[--------------------------< G E T _  R E F >---------------------------------------------------------------

return the reference for a seat claim

<frame> required to expand {{wikidata}} template

]]

local function get_ref (frame, institution, party)
	if institution == 'EP' or institution == 'COR' then
		if party == "THISPARTY" then
			return frame:expandTemplate ({title='wikidata', args = {'references', 'P1410', P194 = cfg.institutions_t[institution]}});
		elseif cfg.parties_t[party] then
			return frame:expandTemplate ({title='wikidata', args = {'references', cfg.parties_t[party], 'P1410', P194 = cfg.institutions_t[institution]}});
		end
	elseif institution == 'EP' or institution == 'COR' then
		if party == "THISPARTY" then
			return frame:expandTemplate ({title='wikidata', args = {'references', 'P1410', P208 = cfg.institutions_t[institution]}});
		elseif parties_t[party] then
			return frame:expandTemplate ({title='wikidata', args = {'references', cfg.parties_t[party], 'P1410', P208 = cfg.institutions_t[institution]}});
		end
	end
end
	

--[[--------------------------< S I N G L E >------------------------------------------------------------------

return the number of seats occupied by one party in one institution.  <body_prop> is the wikidata property:
	P194: legislative body
	P208: executive body

<frame> required to expand {{wikidata}} template 

Note: P1410 is the property "number of seats in assembly", used to record an entity's seats in legislative or executive bodies

]]

local function single (frame, institution, party, body_prop)
	local args_t = {};	
	if party == "THISPARTY" then												-- flag used when module is called from the page of a European party; less expensive
		args_t = {'property', 'P1410'};											-- init some of the {{wikidata}} parameters with THISPARTY (only when called from the page of a European party)
	else
		args_t = {'property', cfg.parties_t[party], 'P1410'};					-- init some of the {{wikidata}} parameters
	end
	args_t[body_prop] = cfg.institutions_t[institution];

	local retval = frame:expandTemplate ({title='wikidata', args = args_t})
	if '' == retval then														-- {{wikidata}} returns empty string when <party> not known to <institution>
		if party == "THISPARTY" then											-- specific error message if the module was called with THISPARTY from the wrong page
			return make_error_msg (cfg.error_messages_t.thisparty);
		elseif not party then
			return	make_error_msg (substitute (cfg.error_messages_t.party_req_share));
		else
			return  make_error_msg (substitute (cfg.error_messages_t.inst_unknown_party, {institution, party}));
		end
	end
	return retval;
end


--[[--------------------------< S H A R E _ F C >--------------------------------------------------------------

return the share of a party's seats relative to the total size of a given institution

<frame> required to expand {{wikidata}} template 

Note: P1342 is the property "number of seats", used to record an institution's number of seats

]]

local function share_fc (frame, party_seats, institution)
	return tonumber (party_seats) and round (100 * party_seats / frame:expandTemplate ({title='wikidata', args = {'property', cfg.institutions_t[institution], 'P1342'}})) or party_seats;
end


--[[--------------------------< S E A T S >--------------------------------------------------------------------

return a number of seats either for an institution or occupied by one or more parties, or by none of them, in one institution.

<frame> required to expand {{wikidata}} template 

Note: 
* P1410 is the property "number of seats in assembly", used to record an entity's seats in legislative or executive bodies
* P1342 is the property "number of seats", used to record an institution's number of seats
* P208 is the property "executive body"
* P194 is the property "legislative body"

]]

local function seats (frame, institution, party)
	if not party then															-- party not specified, returns seats of the institution
		return frame:expandTemplate ({title='wikidata', args = {'property', cfg.institutions_t[institution], 'P1342'}});

	elseif party == "IND" and institution == "EUCO" then						-- special case of independent politicians on European Council
		return frame:expandTemplate ({title='wikidata', args = {'property', cfg.misc_parties_t['IND'], 'P1410', P208 = cfg.institutions_t[institution]}});

	elseif party == "NONE" then													-- returns seats not occupied by European parties
		if institution == "EUCO" then											-- if EUCO, use P208 and separate case to account for independent politicians
			local retval = frame:expandTemplate ({title='wikidata', args = {'property', cfg.institutions_t[institution], 'P1342'}});
			local ind = frame:expandTemplate ({title='wikidata', args = {'property', cfg.misc_parties_t['IND'], 'P1410', P208 = cfg.institutions_t[institution]}})
			return retval - (sum (frame, institution, 'P208') + ind);

		elseif institution == "EC" then											-- if EC, use P208
			local retval = frame:expandTemplate ({title='wikidata', args = {'property', cfg.institutions_t[institution], 'P1342'}});
			return retval - sum (frame, institution, 'P208');

		elseif institution == "EP" or institution == "COR" then					-- if EP or COR, use P194
			local retval = frame:expandTemplate ({title='wikidata', args = {'property', cfg.institutions_t[institution], 'P1342'}});
			return retval - sum (frame, institution, 'P194');
		end

	elseif party == "ALL" then													-- returns seats occupied by all European parties combined
		if institution == "EC" or institution == "EUCO" then					-- if EC or EUCO, use P208 (independent politicians not counted)
			return sum (frame, institution, 'P208');

		elseif institution == "EP" or institution == "COR" then					-- if EP or COR, use P194
			return sum (frame, institution, 'P194');
		end

	else																		-- returns the number of seats occupied by one party in one institution
		if institution == "EC" or institution == "EUCO" then					-- if EC or EUCO, use P208
			return single (frame, institution, party, 'P208');

		elseif institution == "EP" or institution == "COR" then					-- if EP or COR, use P194
			return single (frame, institution, party, 'P194');
		end
	end
end


--[[--------------------------< S E A T S _ S H A R E >--------------------------------------------------------

return a share of seats occupied by one or more parties, or by none of them, in one institution.

<frame> required to expand {{wikidata}} template 

Note: 
* P1410 is the property "number of seats in assembly", used to record an entity's seats in legislative or executive bodies
* P1342 is the property "number of seats", used to record an institution's number of seats
* P208 is the property "executive body"
* P194 is the property "legislative body"

]]

local function seats_share (frame, institution, party)
	if party == "IND" and institution == "EUCO" then							-- special case of independent politicians on European Council
		return share_fc (frame, frame:expandTemplate ({title='wikidata', args = {'property', cfg.misc_parties_t['IND'], 'P1410', P208 = cfg.institutions_t[institution]}}), institution);

	elseif party == "NONE" then													-- returns seats not occupied by European parties
		if institution == "EUCO" then											-- if EUCO, use P208 and separate case to account for independent politicians
			local retval = frame:expandTemplate ({title='wikidata', args = {'property', cfg.institutions_t[institution], 'P1342'}});
			local ind = frame:expandTemplate ({title='wikidata', args = {'property', cfg.misc_parties_t['IND'], 'P1410', P208 = cfg.institutions_t[institution]}})
			return share_fc (frame, retval - (sum (frame, institution, 'P208') + ind), institution);

		elseif institution == "EC" then											-- if EC, use P208
			local retval = frame:expandTemplate ({title='wikidata', args = {'property', cfg.institutions_t[institution], 'P1342'}});
			return share_fc (frame, retval - sum (frame, institution, 'P208'), institution);

		elseif institution == "EP" or institution == "COR" then					-- if EP or COR, use P194
			local retval = frame:expandTemplate ({title='wikidata', args = {'property', cfg.institutions_t[institution], 'P1342'}});
			return share_fc (frame, retval - sum (frame, institution, 'P194'), institution);
		end

	elseif party == "ALL" then													-- returns seats occupied by all European parties combined
		if institution == "EC" or institution == "EUCO" then					-- if EC or EUCO, use P208 (independent politicians not counted)
			return share_fc (frame, sum (frame, institution, 'P208'), institution);

		elseif institution == "EP" or institution == "COR" then					-- if EP or COR, use P194
			return share_fc (frame, sum (frame, institution, 'P194'), institution);
		end

	else																		-- returns the number of seats occupied by one party in one institution
		if institution == "EC" or institution == "EUCO" then					-- if EC or EUCO, use P208
			return share_fc (frame, single (frame, institution, party, 'P208'), institution);

		elseif institution == "EP" or institution == "COR" then					-- if EP or COR, use P194
			return share_fc (frame, single (frame, institution, party, 'P194'), institution);
		end
	end
end


--[[--------------------------< V A L I D A T E _ W I D T H >--------------------------------------------------

validates data format for width parameter (for composition bar()); returns boolean true when valid; nil else

]]

local function validate_width (width)
	local patterns_t = {'^%d+$', '^%d+px$', '^%d+%%$', '^%d+em$'};				-- valid <width> patterns
	for i, pattern in ipairs (patterns_t) do									-- loop through the patterns in <patterns_t>
		if width:match (pattern) then											-- is there a match?
			return true;														-- yes, done
		end
	end
end


--[[--------------------------< V A L I D A T E _ I N S T I T U T I O N _ P A R T Y >--------------------------

validates data format for institution and party parameters (for main() and compositionbar())

returns boolean true when valid; error message else

]]

local function validate_institution_party (institution, party, template_name)
	if not institution then														-- institution is required
		return make_error_msg (cfg.error_messages_t.missing_inst, template_name);
	elseif not cfg.institutions_t[institution] then
		return make_error_msg (substitute (cfg.error_messages_t.unknown_inst, {institution}), template_name);	-- if institution is present, it must be known
	end
	
	if party == "%" or party == "SHARE" then									-- if party is missing and %/share is entered instead
		return make_error_msg (cfg.error_messages_t.party_req_share, template_name);
	end
	
	if party and not cfg.parties_t[party] and not cfg.misc_parties_t[party] and not cfg.keywords_t[party] then	-- party is optional; but if party is present, it must be known
		return  make_error_msg (substitute (cfg.error_messages_t.unknown_party, {party}), template_name);
	end

	if 'THISPARTY' == party then												-- 'THISPARTY' parameter only to be used by templates on European party articles
		local frame = mw.getCurrentFrame();										-- we need a copy of the frame for this test
		if '' == frame:expandTemplate ({title='wikidata', args = {'property', 'P1410', cfg.institutions_t[institution]}}) then	-- empty string when this article not an EU party article
			return make_error_msg (cfg.error_messages_t.thisparty , template_name);
		end
	end

	return true;
end


--[[--------------------------< M A I N >----------------------------------------------------------------------

implements {{SeatsEUPPs}}

carries out input error detection, reporting, and function dispatching

]]

local function main (frame)
	local args_t = get_args (frame);											-- get arguments; empty string or whitespace positional parameters set to nil

	local institution = args_t[1] and args_t[1]:upper();						-- force to upper case
	local party = args_t[2] and args_t[2]:upper();
	local share = args_t[3] and args_t[3]:upper();
	
--[=[ data validation for institution and party ]=]	
	
	local is_valid = validate_institution_party (institution, party);
	if true ~= is_valid then													-- boolean true when valid; error message else
		return is_valid;														-- yep, abandon with error message
	end

--[=[ function dispatching ]=]	
	
	if not share then			
		return seats (frame, institution, party);								-- return number of seats by calling seats()

	elseif share == "%" or share == "SHARE" then
		return seats_share (frame, institution, party);							-- return share of seats by calling seats_share()
	else 
		return make_error_msg (substitute (cfg.error_messages_t.unknown_param, {share}));
	end
end


--[[--------------------------< C O M P O S I T I O N _ B A R >------------------------------------------------

this function does whatever it is that {{composition bar}} does

implements {{EUPP composition bar}}

	{{EUPP composition bar|<institution>|<party>|width=<width>|percent=yes|reference=yes|bar-color=<color>|background-color=<color>|border=<color>}}
	
]]

local function composition_bar (frame)
	local args_t = get_args (frame);											-- get arguments; empty string or whitespace positional parameters set to nil

	local institution = args_t[1] and args_t[1]:upper();						-- force to upper case
	local party = args_t[2] and args_t[2]:upper();
	local width = args_t.width;													-- must be a number, or number with unit suffix: 'px', '%', 'em'; whitespace not allowed
	local percentage = args_t.percent and args_t.percent:lower();											-- 
	percentage = 'yes' == percentage;											-- make a boolean
	local reference = args_t.reference and args_t.reference:lower();			
	reference = 'yes' == reference;												-- make a boolean
	
	local background_color = args_t['background-color'];
	local border = args_t.border;
	
	
--[=[ data validation for institution, party and width ]=]	
		
	local is_valid = validate_institution_party (institution, party, 'CompositionBarEUPPs');
	if true ~= is_valid then													-- boolean true when valid; error message else
		return is_valid;														-- yep, abandon with error message
	end
	
	if width and not validate_width (width) then
		return make_error_msg (substitute (cfg.error_messages_t.parameter_invalid, {width}), 'CompositionBarEUPPs');	-- yep, abandon with error message
	end

--[=[ prepare arguments for composition bar ]=]	

	local inst_seats = seats (frame, institution);								-- get total seats in <institution>
	local party_seats = seats (frame, institution, party);						-- get total seats in <institution> occupied by <party>
	local color = args_t['bar-color'] or get_colour (frame, party);				-- get color associated with <party>; |bar-color= overrides wikidata

	local comp_bar_args_t = {
		party_seats,
		inst_seats, 
		color,
		width=width,
		per=percentage,
		['background-color'] = background_color,
		border = border,
	}

	return frame:expandTemplate ({title='Composition bar', args = comp_bar_args_t}) .. ((reference and get_ref (frame, institution, party)) or '');
end


--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]

return {
	main = main,
	composition_bar = composition_bar,
	}