diff --git a/design_system_dependences/metasplus/CHANGELOG.md b/design_system_dependences/metasplus/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..335371fba696b1f937c26d7d947865f7c074da62
--- /dev/null
+++ b/design_system_dependences/metasplus/CHANGELOG.md
@@ -0,0 +1,11 @@
+# Changelog
+
+## 2.4.5 - 2023-06-15
+
+### Added
+
+- Un changelog
+
+### Fixed
+
+- #24 Notice php en moins, à piori levée sur la page d'accueil
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/TODO.md b/design_system_dependences/metasplus/TODO.md
new file mode 100644
index 0000000000000000000000000000000000000000..71f3b5e1afa3729db7f22017a79acaf30ed0c2ff
--- /dev/null
+++ b/design_system_dependences/metasplus/TODO.md
@@ -0,0 +1,19 @@
+# Plugin Métas+ : choses à faire
+
+## Open graph
+
+### Propriétés
+
+article:section : rubriques
+
+## Twitter
+
+### propriétés
+
+twitter:site : en fonction des plugins installés, il y a peut-être moyen de renseigner le compte twitter
+
+
+## Dublin Core
+
+Lire la doc !
+Prendre le plugin dublin core comme référence aussi.
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/formulaires/configurer_metasplus.php b/design_system_dependences/metasplus/formulaires/configurer_metasplus.php
new file mode 100644
index 0000000000000000000000000000000000000000..48a2148a721386ba0d1ecbf78ebd48688d31c85a
--- /dev/null
+++ b/design_system_dependences/metasplus/formulaires/configurer_metasplus.php
@@ -0,0 +1,49 @@
+<?php
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+function formulaires_configurer_metasplus_charger_dist() {
+	// Chargement automatique
+	$valeurs = cvtconf_formulaires_configurer_recense('configurer_metasplus', array());
+
+	// Compat bigup
+	$valeurs['_bigup_rechercher_fichiers'] = true;
+
+	return $valeurs;
+}
+
+function formulaires_configurer_metasplus_traiter_dist() {
+
+	include_spip('inc/cvt_configurer');
+	//refuser_traiter_formulaire_ajax();
+
+	$retours = array();
+
+	// Enregistrement de l'image
+	if ($documents = $_FILES) {
+		$mode = 'auto';
+		include_spip('action/editer_liens');
+		$ajouter_document = charger_fonction('ajouter_documents', 'action');
+		if (
+			$document = $ajouter_document(0, $documents, null, 0, $mode)
+			and $id_document = intval($document[0])
+		) {
+			sql_updateq('spip_documents',array('statut' => 'publie'), 'id_document='.intval($id_document));
+			set_request('id_doc_logo',$id_document);
+		}
+	}
+
+	// Enregistrement de la configuration
+	$trace = cvtconf_formulaires_configurer_enregistre('configurer_metasplus', array());
+	$retours['message_ok'] = _T('config_info_enregistree') . $trace;
+
+	// Si on traite le logo, on force une redirection
+	if (isset($id_document)) {
+		$retours['redirect'] = parametre_url(self(), 'id_document', $id_document, '&');
+	}
+
+	$retours['editable'] = true;
+
+	return $retours;
+}
diff --git a/design_system_dependences/metasplus/inclure/metasplus/auteur.html b/design_system_dependences/metasplus/inclure/metasplus/auteur.html
new file mode 100644
index 0000000000000000000000000000000000000000..1c729e2dccb0ec9dd604beaae30bb8a4ee123274
--- /dev/null
+++ b/design_system_dependences/metasplus/inclure/metasplus/auteur.html
@@ -0,0 +1,9 @@
+[(#REM)
+
+	Métas+ : variante pour les auteurs
+
+]
+<INCLURE{fond=inclure/metasplus/dist,
+	og-type=profile,
+	desc=#INFO_BIO{auteur,#ENV{id_auteur}},
+	env} />
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/inclure/metasplus/dist.html b/design_system_dependences/metasplus/inclure/metasplus/dist.html
new file mode 100644
index 0000000000000000000000000000000000000000..4ba9e60a49bb2c1874c29bc6f199300b68632f1b
--- /dev/null
+++ b/design_system_dependences/metasplus/inclure/metasplus/dist.html
@@ -0,0 +1,207 @@
+[(#ENV{var_mode}|=={debug}|oui)#HTTP_HEADER{Content-Type:text/html}][(#ENV{debug}|oui)#HTTP_HEADER{Content-Type:text/plain}]
+[(#REM)
+
+	Métas+ : ce squelette génère les métas pour Dublin Core, Open Graph et Twitter.
+
+	Pour déboguer sur spip.php?page=inclure/metasplus/dist :
+	- var_mode=debug pour le débug normal (sql, etc.)
+	- debug=oui pour avoir un simple retour texte
+
+	Il s'agit du squelette par défaut inclus automatiquement dans le <head>, il tente de générer au mieux les informations des pages.
+
+	Ce squelette récupére les valeurs *brutes* sans appliquer aucun filtre comme |textebrut, |attribut_html ou autre.
+	Ces filtres sont appliqués en aval dans le squelette inclus : inc-dist.tml
+
+	On peut lui transmettre certaines valeurs à prendre en priorité par rapport à la récupération automatique.
+
+	Il est possible de créer des variantes pour des pages précises : inclure/metasplus/{page}.html
+	Plusieurs possibilités pour le contenu des variantes :
+	- vide = pas de métas (voir aussi la constante _METASPLUS_PAGES_EXCLUES)
+	- inclure ce squelette en ne transmettant *que* les paramètres à modifier
+	- inclure inc-dist.html en transmettant *tous* les paramètres
+	- tout faire à la main
+
+	Précisions :
+		- Sur une page d'objet, on met og-type = article par défaut
+		- Sur une page lambda, on omet volontairement le titre et la description puisqu'on ne les connait pas, twitter et facebook se rabattent sur les metas <title> et <description>.
+
+	Format des logos : https://goo.gl/L4StmD
+		- Twitter  : taille min 440 x 220
+		             taille recommandée 506 x 253
+		             taille max 1024 x 512
+		             poids max 5 Mo
+		             ratio 2:1
+		- Facebook : pas de taille min
+		             taille recommandée > 600 x 315 ou 1200 x 630 (hidpi)
+		             poids max 8 Mo
+		             ratio 1.91:1
+
+	Contexte : 
+		- type-page
+		- objet
+		- id_objet
+		- id_patate
+
+	Paramètres :
+		- debug :      'Oui' quand on débogue le squelette
+		               spip.php?page=inclure/metasplus/dist&objet=truc&id_objet=N&debug=oui
+		- titre :      Titre de la ressource
+		- desc :       Description
+		- langue :     Langue au format iso. ex. fr
+		- territoire : Complète la langue pour former le duet langue_territoire, ex. UK
+			             Si rien n'est renseigné, on tente un lang_LANG
+		- date :       Date de publication au format Y-m-d
+		- maj :        Date de mise à jour au format Y-m-d
+		- url :        URL de la ressource
+		- auteurs :    Soit un tableau linéaires
+		               Soit des auteurs séparés par des virgules
+		- logos :      Soit un tableau de tableaux associatifs avec URL et alt
+		               #LISTE{#ARRAY{url,...,alt...},#ARRAY{url,...,alt...}}
+		               Soit des URLs séparées par des virgules
+		- mots :       Soit un tableau linéaire
+		               Soit des mots-clés séparés par des virgules
+		- og-type :    (open graph) Type de la ressource : article, profile, book, etc.
+		- dc-type :    (dublin core) Type de la ressource : Text, Event, PhysicalObject, etc.
+
+	Paramètres dépréciés :
+		- auteur => auteurs
+		- logo => logos
+		- lang => langue
+]
+
+[(#REM)
+
+	=======================================
+	1. Récupération automatique des valeurs
+	=======================================
+
+]
+
+[(#REM)
+
+	Cas 1 : Page d'un objet éditorial
+
+]
+<BOUCLE_objet(CONDITION) {si #ENV{objet}|et{#ENV{id_objet}}}>
+#SET{og-type_auto,    article}
+#SET{dc-type_auto,    Text}
+#SET{titre_auto,      #INFO_TITRE{#ENV{objet},#ENV{id_objet}}|concat{" – ",#NOM_SITE_SPIP}}
+#SET{desc_auto,       #INFO_INTRODUCTION{#ENV{objet},#ENV{id_objet}}
+	|sinon{#INFO_DESCRIPTIF{#ENV{objet},#ENV{id_objet}}}
+	|sinon{#INFO_CHAPO{#ENV{objet},#ENV{id_objet}}}
+	|sinon{#INFO_TEXTE{#ENV{objet},#ENV{id_objet}}}}
+#SET{url_auto,        #INFO_URL{#ENV{objet},#ENV{id_objet}}}
+#SET{date_auto,       #INFO_DATE{#ENV{objet},#ENV{id_objet}}}
+#SET{maj_auto,        #INFO_MAJ{#ENV{objet},#ENV{id_objet}}}
+#SET{langue_auto,     #INFO_LANG{#ENV{objet},#ENV{id_objet}}|sinon{#LANG}}
+#SET{territoire_auto, ''}
+
+[(#REM) Les auteurs ]
+#SET{auteurs_auto,#ARRAY}
+<BOUCLE_auteurs_objet(AUTEURS)
+	{objet}
+	{id_objet}
+	{par nom}
+	{si #ENV{auteurs}|non}
+	{si #CONFIG{metasplus/masquer_auteurs}|non}
+>
+#SET{auteurs_auto, #GET{auteurs_auto}|push{#NOM}}
+</BOUCLE_auteurs_objet>
+#SET{auteurs_auto, #NOM_SITE_SPIP}
+<//B_auteurs_objet>
+
+[(#REM) Les mots-clés ]
+#SET{mots_auto,#ARRAY}
+<BOUCLE_mots_objet(MOTS)
+	{objet}
+	{id_objet}
+	{par titre}
+	{si #ENV{mots}|non}
+>
+#SET{mots_auto, #GET{mots_auto}|push{#TITRE}}
+</BOUCLE_mots_objet>
+
+[(#REM) Les images : logo de l'objet puis images liées ]
+<BOUCLE_logo_objet(CONDITION){si #ENV{logos}|non}>
+#SET{id_rubrique,#INFO_ID_RUBRIQUE{#ENV{objet},#ENV{id_objet}}}
+#SET{logo_objet, #ENV{objet}|id_table_objet|quete_logo{on,#ENV{id_objet},#GET{id_rubrique,0},0}}
+#SET{logos_auto, #GET{logo_objet}|?{#LISTE{#ARRAY{url,#GET{logo_objet/src}}},#ARRAY}}
+#SET{fichier_logo,#GET{logo_objet/src}|replace{#VAL{_NOM_PERMANENTS_ACCESSIBLES}|constant}|replace{'\.\./'}|supprimer_timestamp}
+#SET{par,#SPIP_VERSION|floatval|>{3.1}|?{rang_lien,largeur}}
+#SET{defaut_tri,#ARRAY{
+	rang_lien, 1,
+	largeur, -1,
+}}
+<BOUCLE_images_objet(DOCUMENTS)
+	{objet}
+	{id_objet}
+	{media = image}
+	{extension != svg}
+	{fichier != #GET{fichier_logo}}
+	{tri #GET{par}, #GET{defaut_tri}}
+	{0,#GET{logos_auto}|?{2,3}}
+	{!par largeur}
+	{tout}
+>
+#SET{logos_auto, #GET{logos_auto}|push{#ARRAY{
+	url, #FICHIER,
+	alt, #TITRE|sinon{#DESCRIPTIF}|couper{80},
+}}}
+</BOUCLE_images_objet>
+</BOUCLE_logo_objet>
+</BOUCLE_objet>
+
+
+[(#REM)
+
+	Cas 2 : Page lambda
+
+]
+#SET{og-type_auto,    website}
+#SET{dc-type_auto,    Text}
+#SET{titre_auto,      #ENV{type-page,sommaire}|=={sommaire}|?{#NOM_SITE_SPIP|concat{" - ",#SLOGAN_SITE_SPIP}}}
+#SET{desc_auto,       #ENV{type-page,sommaire}|=={sommaire}|?{#DESCRIPTIF_SITE_SPIP}}
+#SET{url_auto,        #ENV{type-page,sommaire}|=={sommaire}|?{#URL_SITE_SPIP,#URL_PAGE{#ENV{type-page}}}}
+#SET{date_auto,       #DATE}
+#SET{maj_auto,        ''}
+#SET{langue_auto,     #LANG}
+#SET{territoire_auto, ''}
+#SET{auteurs_auto,    #NOM_SITE_SPIP}
+#SET{mots_auto,       ''}
+<//B_objet>
+
+[(#REM)
+
+	Cas 1 et 2 : compléments
+	Pas de logo ? On prend celui configuré par défaut, sinon celui du site
+
+]
+[(#ENV{logos}|non|et{#GET{logos_auto}|non}|oui)
+#SET{logos_auto,#INFO_FICHIER{document,#CONFIG{metasplus/id_doc_logo}}|sinon{#LOGO_SITE_SPIP|extraire_attribut{src}}}
+]
+
+[(#REM)
+
+	====================
+	2. Code des metas
+	====================
+
+]
+<INCLURE{
+	fond=inclure/metasplus/inc-dist,
+	titre=#ENV{titre,#GET{titre_auto}},
+	desc=#ENV{desc,#GET{desc_auto}},
+	url=#ENV{url,#GET{url_auto}},
+	date=#ENV{date,#GET{date_auto}},
+	maj=#ENV{maj,#GET{maj_auto}},
+	langue=#ENV{langue,#GET{langue_auto}},
+	territoire=#ENV{territoire,#GET{territoire_auto}},
+	og-type=#ENV{og-type,#GET{og-type_auto}},
+	dc-type=#ENV{dc-type,#GET{dc-type_auto}},
+	logos=#ENV{logos,#GET{logos_auto}},
+	auteurs=#ENV{auteurs,#GET{auteurs_auto}},
+	mots=#ENV{mots,#GET{mots_auto}},
+	env,
+}/>
+
+#FILTRE{trim}
diff --git a/design_system_dependences/metasplus/inclure/metasplus/evenement.html b/design_system_dependences/metasplus/inclure/metasplus/evenement.html
new file mode 100644
index 0000000000000000000000000000000000000000..5033f6d315013a13990bdb69826038451e9f1849
--- /dev/null
+++ b/design_system_dependences/metasplus/inclure/metasplus/evenement.html
@@ -0,0 +1,8 @@
+[(#REM)
+
+	Métas+ : variante pour les évènements
+
+]
+<INCLURE{fond=inclure/metasplus/dist,
+	dc-type=Event,
+	env} />
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/inclure/metasplus/inc-dist.html b/design_system_dependences/metasplus/inclure/metasplus/inc-dist.html
new file mode 100644
index 0000000000000000000000000000000000000000..8dd8be9e9fd075ca6d6c301bdedfed37366ea4eb
--- /dev/null
+++ b/design_system_dependences/metasplus/inclure/metasplus/inc-dist.html
@@ -0,0 +1,186 @@
+[(#REM)
+
+	Métas+ : ce squelette contient le code des métas pour Dublin Core, Open Graph et Twitter.
+	Ici aucune requête SQL, on doit recevoir toutes les données.
+	Il est inclus dans inclure/metasplus/dist.html, voir ce dernier pour les explications et les paramètres.
+
+]
+[(#REM)
+
+
+	============================================
+	1) Normalisation et vérification des valeurs
+	============================================
+
+
+]
+#SET{titre,      #ENV{titre}|trim|html_entity_decode|supprimer_tags|textebrut}
+#SET{desc,       #ENV{desc}|trim|html_entity_decode|supprimer_tags|textebrut}
+#SET{url,        #ENV{url}|trim}
+#SET{date,       #ENV{date}|trim}
+#SET{maj,        #ENV{maj}|trim}
+#SET{lang,       #ENV{langue}|trim}
+#SET{og-type,    #ENV{og-type}|trim}
+#SET{dc-type,    #ENV{dc-type}|trim}
+#SET{territoire, #ENV{territoire}|=={en}|?{uk,#ENV{territoire,#ENV{langue}}}|strtoupper|trim}
+#SET{locale,     #ENV{langue}|concat{_,#GET{territoire}}|trim}
+#SET{couper,     200}
+#SET{dimensions, #ARRAY{
+	opengraph, 1200:630,
+	twitter,   506:253,
+}}
+[(#REM)
+	auteurs
+]
+#SET{auteurs,#ARRAY}
+<BOUCLE_normaliser_auteurs(DATA){source table, #ENV{auteurs}|is_array|?{#ENV{auteurs},#ENV{auteurs}|explode{','}}|array_filter}>
+#SET{auteurs,#GET{auteurs}|push{#VALEUR|trim|html_entity_decode|supprimer_tags|textebrut}}
+</BOUCLE_normaliser_auteurs>
+[(#REM)
+	mots-clés
+]
+#SET{mots,#ARRAY}
+<BOUCLE_normaliser_mots(DATA){source table, #ENV{mots}|is_array|?{#ENV{mots},#ENV{mots}|explode{','}}|array_filter}>
+#SET{mots,#GET{mots}|push{#VALEUR|trim|html_entity_decode|supprimer_tags|textebrut}}
+</BOUCLE_normaliser_mots>
+[(#REM)
+	Logos
+]
+#SET{logos,#ARRAY}
+<BOUCLE_normaliser_logos(DATA){source table, #ENV{logos}|is_array|?{#ENV{logos},#ENV{logos}|explode{','}}|array_filter}>
+#SET{valeur,#VALEUR|is_array|?{
+	#ARRAY{
+		url, #VAL{#VALEUR{url}|supprimer_timestamp},
+		alt, #VAL{#VALEUR{alt}|trim|supprimer_tags|textebrut},
+	},
+	#ARRAY{url,#VALEUR|supprimer_timestamp}
+}|array_filter}
+[(#CHEMIN{#GET{valeur/url}}|oui)
+#SET{logos,#GET{logos}|push{#GET{valeur}}}
+]
+</BOUCLE_normaliser_logos>
+[(#REM)
+
+
+	============================
+	2) Affichage des métadonnées
+	============================
+
+
+]
+[(#REM)
+
+	===========
+	Dublin Core
+	===========
+
+	http://dublincore.org
+
+]
+<BOUCLE_dublincore(CONDITION) {si #CONFIG{metasplus/dublincore}}>
+<!-- Dublin Core -->
+<link rel="schema.DC" href="https://purl.org/dc/elements/1.1/" />
+<link rel="schema.DCTERMS" href="https://purl.org/dc/terms/" />
+<meta name="DC.Format" content="text/html" />
+[<meta name="DC.Type" content="(#GET{dc-type})" />]
+[<meta name="DC.Language" content="(#GET{lang})" />]
+[<meta name="DC.Title" lang="#GET{lang}" content="(#GET{titre}|attribut_html)" />]
+[<meta name="DC.Description.Abstract" lang="#GET{lang}" content="(#GET{desc}|couper{#GET{couper},'…'}|attribut_html)" />]
+[<meta name="DC.Date" content="(#GET{date}|affdate{Y-m-d})" />]
+[<meta name="DC.Date.Modified" content="(#GET{maj}|affdate{Y-m-d})" />]
+[<meta name="DC.Identifier" content="(#GET{url}|url_absolue)" />]
+[<meta name="DC.Publisher" content="(#NOM_SITE_SPIP|attribut_html)" />]
+[<meta name="DC.Source" content="(#URL_SITE_SPIP)" />]
+<BOUCLE_auteurs_dublincore(DATA){source table, #GET{auteurs}}>
+[<meta name="DC.Creator" content="(#VALEUR|attribut_html)" />]
+</BOUCLE_auteurs_dublincore>
+<BOUCLE_mots_dublincore(DATA) {source table, #GET{mots}}>
+[<meta name="DC.Subject" content="(#VALEUR|attribut_html)" />]
+</BOUCLE_mots_dublincore>
+</BOUCLE_dublincore>
+[(#REM)
+
+	==========
+	Open Graph
+	==========
+
+	http://ogp.me
+	https://developers.facebook.com/docs/sharing/opengraph/object-properties
+	https://developers.facebook.com/docs/sharing/webmasters/images
+	https://developers.facebook.com/tools/debug/
+
+]
+<BOUCLE_opengraph(CONDITION) {si #CONFIG{metasplus/opengraph}}>
+<!-- Open Graph -->
+[(#GET{logos}|count|oui)
+<meta property="og:rich_attachment" content="true" />
+]
+[<meta property="og:site_name" content="(#NOM_SITE_SPIP|attribut_html)" />]
+[<meta property="og:type" content="(#GET{og-type}|attribut_html)" />]
+[<meta property="og:title" content="(#GET{titre}|attribut_html)" />]
+[<meta property="og:locale" content="(#GET{locale})" />]
+[<meta property="og:url" content="(#GET{url}|url_absolue)" />]
+[<meta property="og:description" content="(#GET{desc}|couper{#GET{couper},'…'}|attribut_html)" />]
+#SET{largeur,#GET{dimensions/opengraph}|explode{:}|table_valeur{0}}
+#SET{hauteur,#GET{dimensions/opengraph}|explode{:}|table_valeur{1}}
+<BOUCLE_logos_opengraph(DATA) {source table, #GET{logos}}>
+#SET{src, #VALEUR{url}|image_recadre{#GET{dimensions/opengraph},-,focus}
+	|image_reduire{#GET{largeur},#GET{hauteur}}
+	|extraire_attribut{src}
+	|sinon{#VALEUR{url}}
+	|supprimer_timestamp}
+[(#VAL{finfo_file}|function_exists|oui)
+#SET{finfo,#EVAL{FILEINFO_MIME_TYPE}|finfo_open}
+#SET{mimetype,#GET{finfo}|finfo_file{#GET{src}}}
+]
+[<meta property="og:image" content="(#GET{src}|url_absolue)" />]
+[<meta property="og:image:width" content="(#GET{src}|largeur)" />]
+[<meta property="og:image:height" content="(#GET{src}|hauteur)" />]
+[<meta property="og:image:type" content="(#GET{mimetype})" />]
+[<meta property="og:image:alt" content="(#VALEUR{alt}|couper{80}|attribut_html)" />]
+</BOUCLE_logos_opengraph>
+<BOUCLE_article_opengraph(CONDITION) {si #GET{og-type}|=={article}}>
+[<meta property="article:published_time" content="(#GET{date}|affdate{Y-m-d})" />]
+[<meta property="article:modified_time" content="(#GET{maj}|affdate{Y-m-d})" />]
+<BOUCLE_auteurs_opengraph(DATA){source table, #GET{auteurs}}>
+[<meta property="article:author" content="(#VALEUR|attribut_html)" />]
+</BOUCLE_auteurs_opengraph>
+<BOUCLE_mots_opengraph(DATA) {source table, #GET{mots}}>
+[<meta property="article:tag" content="(#VALEUR|attribut_html)" />]
+</BOUCLE_mots_opengraph>
+</BOUCLE_article_opengraph>
+[(#REM) Si plugin facebook, on envoie la méta fb:app_id ]
+[<meta property="fb:app_id" content="(#CONFIG{facebook/cle})" />]
+</BOUCLE_opengraph>
+[(#REM)
+
+	============
+	Twitter Card
+	============
+
+	https://dev.twitter.com/cards/types/summary
+	https://dev.twitter.com/cards/types/summary-large-image
+	https://cards-dev.twitter.com/validator
+
+]
+<BOUCLE_twitter(CONDITION) {si #CONFIG{metasplus/twitter}}>
+<!-- Twitter Card -->
+<meta name="twitter:card" content="[(#GET{logos}|count|?{summary_large_image,summary})]" />
+[<meta name="twitter:title" content="(#GET{titre}|attribut_html)" />]
+[<meta name="twitter:description" content="(#GET{desc}|couper{#GET{couper},'…'}|attribut_html)" />]
+<meta name="twitter:dnt" content="on" />
+[<meta name="twitter:url" content="(#GET{url}|url_absolue)" />]
+#SET{largeur,#GET{dimensions/twitter}|explode{:}|table_valeur{0}}
+#SET{hauteur,#GET{dimensions/twitter}|explode{:}|table_valeur{1}}
+<BOUCLE_images_twitter(DATA) {source table, #GET{logos}} {0,1}>
+#SET{src, #VALEUR{url}|image_recadre{#GET{dimensions/twitter},-,focus}
+	|image_reduire{#GET{largeur},#GET{hauteur}}
+	|extraire_attribut{src}
+	|sinon{#VALEUR{url}}
+	|timestamp}
+[<meta name="twitter:image" content="(#GET{src}|url_absolue)" />]
+[<meta property="twitter:image:alt" content="(#VALEUR{alt}|couper{80}|attribut_html)" />]
+</BOUCLE_images_twitter>
+</BOUCLE_twitter>
+
+#FILTRE{trim}
diff --git a/design_system_dependences/metasplus/lang/metasplus.xml b/design_system_dependences/metasplus/lang/metasplus.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8c288b66197733e234e1749225483ffa8d668177
--- /dev/null
+++ b/design_system_dependences/metasplus/lang/metasplus.xml
@@ -0,0 +1,12 @@
+<traduction
+	module="metasplus"
+	id="metasplus--metasplus-23d39"
+	gestionnaire="salvatore"
+	url="https://trad.spip.net"
+	source="https://git.spip.net/spip-contrib-extensions/metasplus.git"
+	reference="fr">
+	<langue code="en" url="https://trad.spip.net/tradlang_module/metasplus?lang_cible=en" total="15" traduits="15" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="raphael" lien="https://trad.spip.net/auteur/raphael-7042" />
+	</langue>
+	<langue code="fr" url="https://trad.spip.net/tradlang_module/metasplus?lang_cible=fr" total="15" traduits="15" relire="0" modifs="0" nouveaux="0" pourcent="100.00" />
+</traduction>
diff --git a/design_system_dependences/metasplus/lang/metasplus_en.php b/design_system_dependences/metasplus/lang/metasplus_en.php
new file mode 100644
index 0000000000000000000000000000000000000000..34b808af6e26619a70c3b2e5b7c85b3e917453ea
--- /dev/null
+++ b/design_system_dependences/metasplus/lang/metasplus_en.php
@@ -0,0 +1,34 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/metasplus?lang_cible=en
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// E
+	'explication_id_doc_logo' => 'Allows you to use an image of your choice instead of the SPIP site logo (properties "og:image" and "twitter:image", recommended format: 1,91:1)',
+	'explication_masquer_auteurs' => 'Check this option if you do not want to publish the names of the content writers: the site name will be used instead.',
+
+	// I
+	'icone_previsu' => 'Meta+ Overview',
+	'icone_previsu_title' => 'Overview of Dublin Core, Open Graph and Twitter metadata.',
+
+	// L
+	'label_case_masquer_auteurs' => 'Use the name of the site as the author of the content',
+	'label_dublincore' => 'Dublin Core',
+	'label_masquer_auteurs' => 'Authors',
+	'label_opengraph' => 'Open Graph',
+	'label_previsu_fond' => 'Background used',
+	'label_previsu_objet' => 'Editorial object',
+	'label_reseaux' => 'Check the meta to be included',
+	'label_twitter' => 'Twitter',
+	'logo_bis' => 'Site image',
+
+	// T
+	'titre_config_metasplus' => 'Configure Meta +',
+	'titre_previsu' => 'Overview of Dublin Core, Open Graph and Twitter metadata.'
+);
diff --git a/design_system_dependences/metasplus/lang/metasplus_fr.php b/design_system_dependences/metasplus/lang/metasplus_fr.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e7e54192ff5a1448f091c5d74622355f4778c95
--- /dev/null
+++ b/design_system_dependences/metasplus/lang/metasplus_fr.php
@@ -0,0 +1,32 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// Fichier source, a modifier dans https://git.spip.net/spip-contrib-extensions/metasplus.git
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// E
+	'explication_id_doc_logo' => 'Permet d’utiliser une image de votre choix à la place du logo du site SPIP (propriétés "og:image" et "twitter:image", format conseillé : 1,91:1)',
+	'explication_masquer_auteurs' => 'Cochez cette option si vous ne souhaitez pas diffuser le nom des rédacteurs des contenus : le nom du site sera utilisé à la place.',
+
+	// I
+	'icone_previsu' => 'Aperçu des métas+',
+	'icone_previsu_title' => 'Aperçu des métadonnées Dublin Core, Open Graph et Twitter.',
+
+	// L
+	'label_case_masquer_auteurs' => 'Utiliser le nom du site comme auteur des contenus',
+	'label_dublincore' => 'Dublin Core',
+	'label_masquer_auteurs' => 'Auteurs',
+	'label_opengraph' => 'Open Graph',
+	'label_previsu_fond' => 'Fond utilisé',
+	'label_previsu_objet' => 'Objet éditorial',
+	'label_reseaux' => 'Cochez les métas à inclure',
+	'label_twitter' => 'Twitter',
+	'logo_bis' => 'Image du site',
+
+	// T
+	'titre_config_metasplus' => 'Configurer Métas +',
+	'titre_previsu' => 'Aperçu des métadonnées Dublin Core, Open Graph et Twitter.'
+);
diff --git a/design_system_dependences/metasplus/lang/paquet-metasplus.xml b/design_system_dependences/metasplus/lang/paquet-metasplus.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2387ee3433743884ce133bdf59c6edd2ea4201d5
--- /dev/null
+++ b/design_system_dependences/metasplus/lang/paquet-metasplus.xml
@@ -0,0 +1,12 @@
+<traduction
+	module="paquet-metasplus"
+	id="paquet-metasplus--metasplus-23d39"
+	gestionnaire="salvatore"
+	url="https://trad.spip.net"
+	source="https://git.spip.net/spip-contrib-extensions/metasplus.git"
+	reference="fr">
+	<langue code="en" url="https://trad.spip.net/tradlang_module/paquet-metasplus?lang_cible=en" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="raphael" lien="https://trad.spip.net/auteur/raphael-7042" />
+	</langue>
+	<langue code="fr" url="https://trad.spip.net/tradlang_module/paquet-metasplus?lang_cible=fr" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00" />
+</traduction>
diff --git a/design_system_dependences/metasplus/lang/paquet-metasplus_en.php b/design_system_dependences/metasplus/lang/paquet-metasplus_en.php
new file mode 100644
index 0000000000000000000000000000000000000000..8463b8ca4064e04abc80c27d587504b9bf16c8c1
--- /dev/null
+++ b/design_system_dependences/metasplus/lang/paquet-metasplus_en.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-metasplus?lang_cible=en
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// M
+	'metasplus_description' => 'Improve the indexing of your articles in search engines and their display on social networks with Dublin Core, Open Graph and Twitter Card metadata.',
+	'metasplus_slogan' => 'Metadata for Open Graph, Duclin Core and Twitter'
+);
diff --git a/design_system_dependences/metasplus/lang/paquet-metasplus_fr.php b/design_system_dependences/metasplus/lang/paquet-metasplus_fr.php
new file mode 100644
index 0000000000000000000000000000000000000000..66cf875782156ae6102aab3fe6efa3d10d463ecd
--- /dev/null
+++ b/design_system_dependences/metasplus/lang/paquet-metasplus_fr.php
@@ -0,0 +1,13 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// Fichier source, a modifier dans https://git.spip.net/spip-contrib-extensions/metasplus.git
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// M
+	'metasplus_description' => 'Améliorez l’indexation de vos articles dans les moteurs et leur affichage sur les réseaux sociaux grâce aux métadonnées Dublin Core, Open Graph et Twitter Card.',
+	'metasplus_slogan' => 'Métadonnées pour Open Graph, Duclin Core et Twitter'
+);
diff --git a/design_system_dependences/metasplus/metasplus_administrations.php b/design_system_dependences/metasplus/metasplus_administrations.php
new file mode 100644
index 0000000000000000000000000000000000000000..50ced8db670ad3fdcbff51b3cf55a161fb5878a3
--- /dev/null
+++ b/design_system_dependences/metasplus/metasplus_administrations.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Fichier gérant l'installation et désinstallation du plugin Métas+
+ *
+ * @plugin     Métas+
+ * @copyright  2018
+ * @author     Tetue, Erational, Tcharlss
+ * @licence    GNU/GPL
+ * @package    SPIP\Metas+\Installation
+ */
+
+// Sécurité
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+
+/**
+ * Fonction d'installation et de mise à jour du plugin Métas+.
+ *
+ * @param string $nom_meta_base_version
+ *     Nom de la meta informant de la version du schéma de données du plugin installé dans SPIP
+ * @param string $version_cible
+ *     Version du schéma de données dans ce plugin (déclaré dans paquet.xml)
+ * @return void
+**/
+function metasplus_upgrade($nom_meta_base_version, $version_cible) {
+	$maj = array();
+
+	// 1ère installation : passe la config en opt-in
+	$maj['create'] = array(
+		array('metasplus_maj_create'),
+	);
+	
+	include_spip('base/upgrade');
+	maj_plugin($nom_meta_base_version, $version_cible, $maj);
+}
+
+
+/**
+ * Fonction de désinstallation du plugin Métas+.
+ *
+ * @param string $nom_meta_base_version
+ *     Nom de la meta informant de la version du schéma de données du plugin installé dans SPIP
+ * @return void
+**/
+function metasplus_vider_tables($nom_meta_base_version) {
+	effacer_meta($nom_meta_base_version);
+}
+
+
+/**
+ * Fonction privée pour la mise à jour create (1ère installation)
+ * On passe la config des protocoles en opt-in
+ *
+ * @return Void
+ */
+function metasplus_maj_create(){
+	include_spip('inc/config');
+	$config = lire_config('metasplus');
+	$protocoles = array('dublincore', 'opengraph', 'twitter');
+	foreach($protocoles as $protocole) {
+		if (empty($config[$protocole])) {
+			$config[$protocole] = 'on';
+		} else {
+			unset($config[$protocole]);
+		}
+	}
+	ecrire_config('metasplus', $config);
+}
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/metasplus_autorisations.php b/design_system_dependences/metasplus/metasplus_autorisations.php
new file mode 100644
index 0000000000000000000000000000000000000000..4cc69cc0a1723ad5e60e7cbcffc4e566380c7ea9
--- /dev/null
+++ b/design_system_dependences/metasplus/metasplus_autorisations.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Définit les autorisations du plugin Métas+
+ *
+ * @plugin     Métas+
+ * @copyright  2016-2018
+ * @author     Tetue, Erational, Tcharlss
+ * @licence    GNU/GPL
+ * @package    SPIP\Metas+\Autorisations
+ */
+
+// Sécurité
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+
+/**
+ * Fonction d'appel pour le pipeline
+ * @pipeline autoriser */
+function metasplus_autoriser() {
+}
+
+
+/**
+ * Autorisation de prévisualiser les métas+ d'un objet
+ *
+ * Il faut être admin et avoir le droit de modifier l'objet
+ *
+ * @param  string $faire Action demandée
+ * @param  string $type  Type d'objet sur lequel appliquer l'action
+ * @param  int    $id    Identifiant de l'objet
+ * @param  array  $qui   Description de l'auteur demandant l'autorisation
+ * @param  array  $opt   Options de cette autorisation
+ * @return bool          true s'il a le droit, false sinon
+**/
+function autoriser_previsualiser_metasplus_dist($faire, $type, $id, $qui, $opt){
+
+	$is_admin = ($qui['statut'] == '0minirezo');
+	$autoriser_modifier = autoriser('modifier', $type, $id, $qui, $opt);
+	$autoriser = ($is_admin and $autoriser_modifier);
+
+	return $autoriser;
+}
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/metasplus_fonctions.php b/design_system_dependences/metasplus/metasplus_fonctions.php
new file mode 100644
index 0000000000000000000000000000000000000000..d73bd732489f5ebfca4943968a930779c7117323
--- /dev/null
+++ b/design_system_dependences/metasplus/metasplus_fonctions.php
@@ -0,0 +1,161 @@
+<?php
+/**
+ * Fonctions utiles au plugin Métas+
+ *
+ * @plugin     Métas+
+ * @copyright  2016-2018
+ * @author     Tetue, Erational, Tcharlss
+ * @licence    GNU/GPL
+ * @package    SPIP\Metas+\Fonctions
+ */
+
+/**
+ * Retrouver le contexte d'après l'URL : type de page, objet éventuel
+ *
+ * @Note
+ * Il n'est pas recommandé d'utiliser $GLOBALS['contexte],
+ * donc on utilise la fonction qui décode l'URL
+ * et retourne un tableau linéaire avec les bonnes infos :
+ * [0]            => page (le fond)
+ * [1][id_patate] => identifiant si page d'un objet
+ * [1][erreur]    => erreur éventuelle (404)
+ *
+ * @param string $url
+ * @return array
+ *   Tableau associatif :
+ *   array{
+ *     type-page: string  (type de page),
+ *     erreur:    bool    (true si page ou décodage en erreur),
+ *     objet:     string  (type d'objet éventuel),
+ *     id_objet:  int     (numéro d'objet éventuel),
+ *     id_patate: int     (numéro d'objet éventuel)
+ *   }
+ */
+function metasplus_identifier_contexte($url) {
+
+	// Decoder_url nous donne quelques infos sur la page actuelle
+	// type-page n'est rempli que pour les objets éditoriaux
+	$decoder_url = charger_fonction('decoder_url', 'urls');
+	$decodage    = $decoder_url($url);
+	$type_page   = (!empty($decodage[0]) ? $decodage[0] : '');
+	$erreur      = (isset($decodage[1]['erreur']) ? true : false);
+
+	// On retourne au minimum le type de page et l'erreur
+	$contexte = array(
+		'type-page' => $type_page,
+		'erreur'    => $erreur,
+	);
+
+	// On complète les infos pour repérer la page d'accueil, les pages autonomes,
+	// et donner des choses complémentaires sur l'éventuel objet.
+	if (!$erreur) {
+
+		// S'agit-il d'une page autonome ? (?page=truc)
+		$query_page    = (defined('_SPIP_PAGE') ? _SPIP_PAGE : 'page');
+		$page_autonome = _request($query_page);
+
+		// Soit c'est la page d'un objet
+		if ($type_page) {
+			include_spip('base/objets');
+			$cle_objet = id_table_objet($type_page);
+			$id_objet = (isset($decodage[1][$cle_objet]) ? intval($decodage[1][$cle_objet]) : 0);
+			if ($id_objet) {
+				$contexte['objet']    = $type_page;
+				$contexte['id_objet'] = $id_objet;
+				$contexte[$cle_objet] = $id_objet; // ça peut servir
+			}
+
+		// Soit c'est une page autonome ?page=truc
+		} elseif ($page_autonome) {
+			$contexte['type-page'] = $page_autonome;
+
+		// Soit c'est la page d'accueil
+		} else {
+			$contexte['type-page'] = 'sommaire';
+
+			// Exception pour le plugin multidomaines : on est dans une rubrique
+			// TODO : faire un pipeline
+			if (test_plugin_actif('multidomaines')) {
+				$multidomaines = lire_config('multidomaines');
+				foreach ($multidomaines as $id_rubrique => $domaine) {
+					if ($domaine['url'] && rtrim($url, '/') == $domaine['url']) {
+						$contexte['type-page']  = 'rubrique';
+						$contexte['erreur']     = false;
+						$contexte['objet']      = 'rubrique';
+						$contexte['id_objet']   = $id_rubrique;
+						$contexte['id_article'] = $id_rubrique;
+						$contexte['url']        = $url;
+					}
+				}
+			}
+		}
+	}
+
+	return $contexte;
+}
+
+
+/**
+ * Sélectionner le squelette des métadonnées pour un type de page
+ *
+ * On cherche dans l'ordre :
+ *
+ * - 1) inclure/metaplus/<type-page>-<composition>.html
+ * - 2) inclure/metaplus/<type-page>.html
+ * - 3) inclure/metaplus/dist.html
+ *
+ * @param array $contexte
+ *     Contexte de la page, avec le type de page, le type d'objet etc.
+ * @return string
+ *     Le fond
+ */
+function metasplus_selectionner_fond($contexte) {
+
+	include_spip('inc/utils');
+
+	$fond             = '';
+	$type_page        = (!empty($contexte['type-page']) ? $contexte['type-page'] : '');
+	$objet            = (!empty($contexte['objet']) ? $contexte['objet'] : '');
+	$id_objet         = (!empty($contexte['id_objet']) ? intval($contexte['id_objet']) : '');
+	$composition      = '';
+	$racine           = 'inclure/metasplus/';
+	$fond_defaut      = $racine . 'dist';
+	$fond_page        = $racine . $type_page;
+	$fond_composition = '';
+
+	if (
+		test_plugin_actif('compositions')
+		and $objet
+		and $id_objet
+		and include_spip('compositions_fonctions')
+		and $composition = compositions_determiner($objet, $id_objet)
+	) {
+		$fond_composition = $fond_page . '-' . $composition;
+	}
+
+	// En priorité, le fond de la composition du type de page
+	if ($composition and find_in_path($fond_composition.'.html')) {
+		$fond = $fond_composition;
+	// Sinon le fond du type de page
+	} elseif (find_in_path($fond_page.'.html')) {
+		$fond = $fond_page;
+	// Sinon le fond générique
+	} elseif (find_in_path($fond_defaut.'.html')) {
+		$fond = $fond_defaut;
+	}
+
+	return $fond;
+}
+
+/**
+ * @param array $args
+ * @param \Spip\Bigup\Formulaire $formulaire
+ * @return \Spip\Bigup\Formulaire
+ */
+function inc_bigup_medias_formulaire_configurer_metasplus_dist($args, $formulaire) {
+	$formulaire->preparer_input_class(
+		'bigup', // 'file' pour rendre automatique.
+		['previsualiser' => true]
+	);
+	return $formulaire;
+}
diff --git a/design_system_dependences/metasplus/metasplus_identifier_contexte.html b/design_system_dependences/metasplus/metasplus_identifier_contexte.html
new file mode 100644
index 0000000000000000000000000000000000000000..40f1cf837a865277bf66ffabec6f33cd804fe075
--- /dev/null
+++ b/design_system_dependences/metasplus/metasplus_identifier_contexte.html
@@ -0,0 +1,16 @@
+[(#REM)
+
+	Squelette technique pour retrouver le contexte correspondant à une URL.
+	Cf. pipeline affichage_final
+
+	Renvoie le contexte sous forme de tableau associatif sérialisé :
+	- type-page : le type de la page
+	- objet : le type d'objet le cas échéant
+	- id_objet : son identifiant
+	- id_patate : idem, mais avec le nom de sa clé primaire
+	- erreur : 'true' si la page est en erreur
+
+	Paramètres :
+	- url : url à décoder, par défaut l'url courante.
+
+][(#ENV{url,#SELF}|url_absolue|metasplus_identifier_contexte|serialize)]
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/metasplus_pipelines.php b/design_system_dependences/metasplus/metasplus_pipelines.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2b5db78d632cd7ce0663d12481fbfd29935bb3d
--- /dev/null
+++ b/design_system_dependences/metasplus/metasplus_pipelines.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Utilisations de pipelines par le plugin Métas+
+ *
+ * @plugin     Métas+
+ * @copyright  2016-2018
+ * @author     Tetue, Erational, Tcharlss
+ * @licence    GNU/GPL
+ * @package    SPIP\Metas+\Pipelines
+ */
+
+// Sécurité
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+
+/**
+ * Effectuer des traitements juste avant l'envoi des pages publiques.
+ *
+ * => Ajout des métadonnéess Open Graph, Dublin Core et Twitter
+ * dans le <head> public de certaines pages.
+ *
+ * @Note : on retrouve les informations du contexte de la page
+ * au moyen d'un squelette pour bénéficier de la mise en cache
+ * et éviter des requêtes SQL à chaque hit via decoder_url().
+ *
+ * @uses metasplus_identifier_contexte()
+ * @uses metasplus_selectionner_fond()
+ * 
+ * @param $flux
+ * @return mixed
+ */
+function metasplus_affichage_final($flux) {
+
+	include_spip('inc/config');
+	include_spip('inc/utils'); // pour self()
+
+	// Tests préliminaires avant d'inclure éventuellement les métas
+	if (
+		// C'est du HTML et on est pas dans le privé
+		$GLOBALS['html']
+		and !test_espace_prive()
+		// Il y a un <head>
+		and $pos_head = strpos($flux, '</head>')
+		// Au moins un protocole est activé
+		and $config = lire_config('metasplus')
+		and !empty($config)
+		// Le contexte est retrouvé
+		and $url = self()
+		and $contexte = recuperer_fond('metasplus_identifier_contexte', array('url' => $url))
+		// On est pas en var_mode=inclure (plantage de unserialize)
+		and !strpos( $contexte, 'inclure_blocs')
+		and is_array($contexte = unserialize($contexte))
+		// On a une page sans erreur
+		and !empty($contexte['type-page'])
+		and $contexte['erreur'] === false
+		// La page n'est pas exclue
+		and is_array($pages_exclues = (
+			(defined('_METASPLUS_PAGES_EXCLUES') and _METASPLUS_PAGES_EXCLUES) ?
+				explode(',', _METASPLUS_PAGES_EXCLUES) :
+				array()
+		))
+		and (!in_array($contexte['type-page'], $pages_exclues))
+		// Ce n'est pas une page d'un pseudo fichier (ex. robots.txt.html)
+		and !strpos($contexte['type-page'], '.')
+	) {
+
+		// Trouver le squelette à utiliser
+		include_spip('metasplus_fonctions');
+		$fond = metasplus_selectionner_fond($contexte);
+
+		// Si le squelette n'est pas vide, on ajoute son contenu à la fin du head
+		// On complète avec le contexte par défaut qui peut contenir des query strings et cie
+		$contexte_defaut = ((isset($GLOBALS['contexte']) and is_array($GLOBALS['contexte'])) ? $GLOBALS['contexte'] : array());
+		$full_contexte = array_merge($contexte_defaut, $contexte);
+		if (
+			$fond
+			and $metas = recuperer_fond($fond, $full_contexte)
+		) {
+			$metas = "<!-- Plugin Métas + -->\n$metas\n";
+			$flux = substr_replace($flux, $metas, $pos_head, 0);
+		}
+	}
+
+	return $flux;
+}
+
+
+/**
+ * pipeline post_edition pour supprimer la meta metasplus/id_doc_logo
+ * quand on supprime l'image dans le formulaire de configuration
+ *
+ * @param $flux
+ * @return $flux
+ * @author tofulm
+ */
+function metasplus_post_edition($flux) {
+	if (
+		isset($flux['args']['table'])
+		and $flux['args']['table'] === 'spip_documents'
+		and isset($flux['args']['operation'])
+		and $flux['args']['operation'] === 'supprimer_document'
+		and isset($flux['args']['action'])
+		and $flux['args']['action'] === 'supprimer_document'
+		and include_spip('inc/config')
+		and $flux['args']['id_objet'] == lire_config('metasplus/id_doc_logo')
+	) {
+		effacer_config('metasplus/id_doc_logo');
+	}
+	return $flux;
+}
+
+
+/**
+ * Gérer les informations affichées dans l’espace privé
+ * dans le cadre d’information des objets SPIP
+ *
+ * => Ajout du bouton de prévisualisation des métas+
+ *
+ * @param $flux
+ * @return $flux
+ * @author tofulm
+ */
+function metasplus_boite_infos($flux) {
+
+	if (
+		$objet = $flux['args']['type']
+		and $id_objet = $flux['args']['id']
+		and autoriser('previsualiser_metasplus', $objet, $id_objet)
+		and objet_info($objet,'page')
+	) {
+		include_spip('base/objets');
+		include_spip('inc/filtres');
+		$type_page = objet_info($objet, 'page');
+		$id_table_objet = id_table_objet($objet);
+		$contexte = array(
+			'type-page'      => $type_page,
+			'objet'          => $objet,
+			'id_objet'       => $id_objet,
+			$id_table_objet  => $id_objet,
+		);
+		$fond_previsu = recuperer_fond('prive/squelettes/inclure/metasplus_bouton_previsu', $contexte);
+		$flux['data'] .= $fond_previsu;
+	}
+
+	return $flux;
+}
diff --git a/design_system_dependences/metasplus/opengraph-150.png b/design_system_dependences/metasplus/opengraph-150.png
new file mode 100644
index 0000000000000000000000000000000000000000..2bb1c2e0cb5e6ed187a2e9d513da943bd955c307
Binary files /dev/null and b/design_system_dependences/metasplus/opengraph-150.png differ
diff --git a/design_system_dependences/metasplus/opengraph-xx.svg b/design_system_dependences/metasplus/opengraph-xx.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c788af7c9889a9d01c4423a14a2e2005778cba7f
--- /dev/null
+++ b/design_system_dependences/metasplus/opengraph-xx.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
+  <path d="M57.2 41.1c-.9 0-1.7.2-2.4.5-.3-.2-.5-.4-1-.6V19.4L31.9 6.7 13.6 17.5l-.9-.6c0-3.2-2.6-5.8-5.8-5.8C3.6 11.2 1 13.8 1 17s2.6 5.8 5.8 5.8c.9 0 1.7-.2 2.4-.5.3.2.7.4.9.5v21.8L32 57.3l18.5-10.8c.3.2.5.3.8.5 0 3.2 2.6 5.8 5.8 5.8 3.2 0 5.8-2.6 5.8-5.8.1-3.3-2.5-5.9-5.7-5.9" fill="#b8c6c9"/>
+  <path d="M32 53.7l18.7-10.9V21.3L32 10.4l-18.7 11v21.4L32 53.7m27.8-6.8c0 1.5-1.2 2.7-2.6 2.7-1.5 0-2.6-1.2-2.6-2.7 0-1.5 1.2-2.7 2.6-2.7 1.4.1 2.6 1.3 2.6 2.7M4.2 17c0-1.5 1.2-2.7 2.6-2.7 1.5 0 2.6 1.2 2.6 2.7s-1.2 2.7-2.6 2.7-2.6-1.2-2.6-2.7" fill="#759bc5"/>
+  <path d="M57.2 48.5c-.9 0-1.6-.7-1.6-1.6 0-.9.7-1.6 1.6-1.6.9 0 1.6.7 1.6 1.6 0 .9-.7 1.6-1.6 1.6zm-21.6 1.8c1.7-2.5 3.8-6.1 5-10.4 2.7.6 5.2 1.4 7.9 2.8l-12.9 7.6zM22.5 25.6c-.4 1.7-.7 3.6-.8 5.6h-7.5v-8.6c2.8 1.4 5.6 2.4 8.3 3zm-15.7-7c-.9 0-1.6-.7-1.6-1.6 0-.9.7-1.6 1.6-1.6.9 0 1.6.7 1.6 1.6 0 .9-.7 1.6-1.6 1.6zM28 14c-1.7 2.4-3.7 5.8-5 10-2.5-.5-4.9-1.4-7.4-2.7L28 14zm4.7 23.5v-2c1.4-.3 2.5-1.3 2.8-2.7h4.9c-.1 1.8-.3 3.6-.7 5.2-2.2-.3-4.5-.5-7-.5zm0 1.7c2.4 0 4.5.2 6.5.5-1.7 5.5-4.7 9.9-6.5 12V39.2zm-9.7 1c1.2 4.1 3.2 7.5 5 9.9l-12.7-7.3c1.5-.8 4.2-1.8 7.7-2.6zm5.5-7.4c.3 1.3 1.4 2.4 2.7 2.7v2c-2.4 0-4.8.3-7.2.7-.4-1.7-.7-3.5-.7-5.4h5.2zm2.7-6.3v2c-1.3.3-2.4 1.3-2.7 2.7h-5.2c.1-1.9.3-3.6.7-5.3 2.2.3 4.6.5 7.2.6zm0-13.1v11.3c-2.5 0-4.7-.2-6.7-.5 1.7-5.6 4.9-9.9 6.7-11.9v1.1zm9.4 10.5c-1.3-4.2-3.3-7.7-5-10.1l13 7.6c-1.6.6-4.3 1.7-8 2.5zm-7.9-10.5v-1.1c1.7 2.1 4.8 6.3 6.5 11.9-2.1.4-4.3.6-6.5.6V13.4zM32 33.9c-1.1 0-1.9-.9-1.9-1.9 0-1.1.9-1.9 1.9-1.9 1.1 0 1.9.9 1.9 1.9 0 1-.9 1.9-1.9 1.9zm-.8 17.9c-1.8-2-5-6.2-6.7-11.9 2.2-.4 4.4-.6 6.7-.7v12.6zm4.3-20.7c-.3-1.3-1.4-2.4-2.8-2.7v-2c2.3 0 4.6-.2 6.9-.6.4 1.7.7 3.5.7 5.3h-4.8zm13.9 0h-7.7c-.1-2-.4-3.8-.8-5.6 4-.8 7.1-2 8.5-2.8v8.4zm-35.1 1.7h7.5c.1 2 .3 3.9.7 5.7-3.8.8-6.5 2-8.2 2.8v-8.5zM41 38.3c.4-1.7.6-3.6.7-5.5h7.8v8.6c-2.7-1.5-5.6-2.5-8.5-3.1zm16.2 4.9c-1 0-1.9.4-2.6 1-1-.6-2-1.2-3-1.7V20.7L31.9 9.2l-18.5 11c-1-.6-2-1.2-3.1-1.8.1-.4.2-.8.2-1.2 0-2-1.7-3.7-3.7-3.7s-3.7 1.7-3.7 3.7 1.7 3.7 3.7 3.7c1 0 1.8-.4 2.5-1 1 .6 2.1 1.2 2.8 1.7v22L31.9 55l18.8-11 3 1.8c-.1.4-.2.8-.2 1.2 0 2 1.7 3.7 3.7 3.7s3.7-1.7 3.7-3.7-1.7-3.8-3.7-3.8z" fill="#343532"/>
+</svg>
diff --git a/design_system_dependences/metasplus/paquet.xml b/design_system_dependences/metasplus/paquet.xml
new file mode 100644
index 0000000000000000000000000000000000000000..50cdd2cbb9d50bfa30b6ac668e94f16e09815d38
--- /dev/null
+++ b/design_system_dependences/metasplus/paquet.xml
@@ -0,0 +1,25 @@
+<paquet
+	prefix="metasplus"
+	categorie="divers"
+	version="2.4.5"
+	schema="1.0.0"
+	etat="stable"
+	compatibilite="[3.1.0;4.2.*]"
+	logo="opengraph-150.png"
+	documentation="https://contrib.spip.net/4969"
+>
+
+	<nom>Métas +</nom>
+	<!-- Métadonnées pour booster vos articles -->
+
+	<auteur lien="http://spip.tetue.net">tetue</auteur>
+	<auteur lien="https://www.erational.org">erational</auteur>
+	<auteur lien="https://www.bravecassine.com">tcharlss</auteur>
+
+	<pipeline nom="affichage_final" inclure="metasplus_pipelines.php" />
+	<pipeline nom="post_edition" inclure="metasplus_pipelines.php" />
+	<pipeline nom="boite_infos" inclure="metasplus_pipelines.php" />
+	<pipeline nom="autoriser" inclure="metasplus_autorisations.php" />
+
+	<utilise nom="composition" compatibilite="[3.7.0;[" />
+</paquet>
diff --git a/design_system_dependences/metasplus/prive/squelettes/contenu/configurer_metasplus.html b/design_system_dependences/metasplus/prive/squelettes/contenu/configurer_metasplus.html
new file mode 100644
index 0000000000000000000000000000000000000000..f47fb93801372094943aeda8aaef59dccfbce19b
--- /dev/null
+++ b/design_system_dependences/metasplus/prive/squelettes/contenu/configurer_metasplus.html
@@ -0,0 +1,4 @@
+[(#AUTORISER{configurer,metasplus}|sinon_interdire_acces)]
+<div class="ajax">
+#FORMULAIRE_CONFIGURER_METASPLUS
+</div>
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/prive/squelettes/contenu/metasplus_previsu.html b/design_system_dependences/metasplus/prive/squelettes/contenu/metasplus_previsu.html
new file mode 100644
index 0000000000000000000000000000000000000000..20dfe2cd3fc3caef4084ff7842ee0666e93cc207
--- /dev/null
+++ b/design_system_dependences/metasplus/prive/squelettes/contenu/metasplus_previsu.html
@@ -0,0 +1,57 @@
+[(#REM)
+
+	Page de prévisualisation des métadonnées d'un objet éditorial
+
+	Paramètres :
+		**obligatoire
+
+		- **page : type de page
+		- **objet : type d'objet
+		- **id_objet : id de l'objet
+		- **id_patate : id de l'objet
+
+]
+#SET{cle_objet,   #ENV{objet}|id_table_objet}
+#SET{contexte,    #ARRAY{type-page,#ENV{page},objet,#ENV{objet},id_objet,#ENV{id_objet}}}
+#SET{fond,        #GET{contexte}|metasplus_selectionner_fond}
+#SET{texte_objet, #ENV{objet}|objet_info{texte_objet}|_T}
+#SET{redirect,    #ENV{id_objet}|generer_url_entite{#ENV{objet}}}
+
+<h1 class="grostitre"><:metasplus:titre_previsu:></h1>
+
+<p class="notice">Dans cette prévisualisation, les URLs pointent vers le privé, mais rassurez-vous, elles sont correctes dans les pages publiques.</p>
+
+#BOITE_OUVRIR{'',info}
+[(#GET{redirect}|icone_verticale{[(#ENV{objet}|objet_info{texte_retour}|_T)],#ENV{objet}|objet_info{icone_objet},'',right retour metasplus})]
+<dl>
+	<dt><:metasplus:label_previsu_objet:> :</dt>
+	<dd>
+		<:titre_cadre_numero_objet{objet=#GET{texte_objet}}|spip_strtolower|ucfirst|replace{':',''}:>[(#ENV{id_objet})][ : «&nbsp;(#INFO_TITRE{#ENV{objet},#ENV{id_objet}})&nbsp;»]
+	</dd>
+	<dt><:metasplus:label_previsu_fond:> :</dt>
+	<dd><code>#GET{fond}.html</code></dd>
+</dl>
+#BOITE_FERMER
+
+#BOITE_OUVRIR{'',simple metasplus}
+[(#PLUGIN{coloration_code}|non)<pre><code>]
+[(#GET{fond}|recuperer_fond{
+	#ARRAY{
+		type-page,#ENV{page},
+		objet,#ENV{objet},
+		id_objet,#ENV{id_objet},
+		#GET{cle_objet},#ENV{id_objet},
+	}}
+	|appliquer_filtre{
+		#PLUGIN{coloration_code}|?{coloration_code_color,htmlentities},
+		#PLUGIN{coloration_code}|?{spip,#EVAL{null}}
+	}
+	|replace{'^\s+',''}
+)]
+[(#PLUGIN{coloration_code}|non)</code></pre>]
+#BOITE_FERMER
+
+<style>
+	code.html {display:block;overflow-x:auto}
+	.box.simple.metasplus{overflow-x:auto}
+</style>
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/prive/squelettes/inclure/metasplus_bouton_previsu.html b/design_system_dependences/metasplus/prive/squelettes/inclure/metasplus_bouton_previsu.html
new file mode 100644
index 0000000000000000000000000000000000000000..1d830d6960ffd2b73a5039b61dbd675eefdd5e93
--- /dev/null
+++ b/design_system_dependences/metasplus/prive/squelettes/inclure/metasplus_bouton_previsu.html
@@ -0,0 +1,18 @@
+[(#REM)
+
+	Lien de prévisualisation des métas+
+
+	Nb : hack pas joli pour ajouter la classe mediabox sur le lien.
+]
+
+[(#URL_ECRIRE{metasplus_previsu}
+	|parametre_url{page,#ENV{type-page}}
+	|parametre_url{objet,#ENV{objet}}
+	|parametre_url{id_objet,#ENV{id_objet}}
+	|parametre_url{var_zajax,contenu}
+	|icone_horizontale{
+		<:metasplus:icone_previsu:>,
+		'metasplus_previsu-24',
+	}
+	|inserer_attribut{title,<:metasplus:icone_previsu_title:>}
+	|replace{'<a','<a class="mediabox"'})]
\ No newline at end of file
diff --git a/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-16.png b/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-16.png
new file mode 100644
index 0000000000000000000000000000000000000000..58dfec6e3fbb3a189d56bc3570e99d20d8da1012
Binary files /dev/null and b/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-16.png differ
diff --git a/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-24.png b/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-24.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b89999d3051ade0e7a6ba4543a86167e1f671c4
Binary files /dev/null and b/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-24.png differ
diff --git a/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-32.png b/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-32.png
new file mode 100644
index 0000000000000000000000000000000000000000..d33340feba4612d8fd013ae1e61094c636b90d1c
Binary files /dev/null and b/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-32.png differ
diff --git a/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-xx.svg b/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-xx.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2faeff8021f2cde2d4b7a928f17906f0f246aaf5
--- /dev/null
+++ b/design_system_dependences/metasplus/prive/themes/spip/images/metasplus_previsu-xx.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
+  <path fill="#fff" d="M49.7 18.5H4.9v27h44.8l9-13.5z"/>
+  <path fill="#666" d="M2.9 49.4H51.8l10.9-16.3c.4-.7.4-1.5 0-2.1L51.8 14.6H2.9c-1.1 0-1.9.9-1.9 1.9v31c0 1 .9 1.9 1.9 1.9zm2-30.9h44.8l9 13.5-9 13.5H4.9v-27z"/>
+  <path fill="#666" d="M47.4 35.7c2.1 0 3.7-1.7 3.7-3.7s-1.7-3.7-3.7-3.7c-2.1 0-3.7 1.7-3.7 3.7s1.7 3.7 3.7 3.7z"/>
+  <path fill="#1d83d4" d="M29.4 29.6l-1.5 4.8H32l-.9 4.2h-4.6l-1.6 5h-4.6l1.6-5h-4l-1.6 5h-4.6l1.6-5H9l.9-4.2h4.6l1.5-4.8h-4.1l.9-4.2h4.6l1.6-5h4.7l-1.6 5h4l1.6-5h4.6l-1.6 5H35l-.9 4.2h-4.7zm-4.6 0h-4l-1.5 4.8h4l1.5-4.8z" />
+</svg>
diff --git a/design_system_dependences/squelettes_par_rubrique/.gitignore b/design_system_dependences/squelettes_par_rubrique/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f6fb500729dc65db88ad2947b749373e00cb63f8
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/.gitignore
@@ -0,0 +1,7 @@
+/vendor/
+/composer.phar
+/composer.lock
+/phpcs.xml
+/phpstan.neon
+/.php_cs.cache
+/.php_cs.txt
diff --git a/design_system_dependences/squelettes_par_rubrique/composer.json b/design_system_dependences/squelettes_par_rubrique/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..2163e8dbb022941683e27e042d29e31b17f3b3e1
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/composer.json
@@ -0,0 +1,18 @@
+{
+    "require": {
+        "php": "^7.4 || ^8.0"
+    },
+    "require-dev": {
+        "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1",
+        "phpstan/phpstan": "^1.4",
+        "spip/coding-standards": "^1.2"
+    },
+    "config": {
+        "allow-plugins": {
+            "dealerdirect/phpcodesniffer-composer-installer": true
+        },
+        "platform": {
+            "php": "7.4.27"
+        }
+    }
+}
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique.xml b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique.xml
new file mode 100644
index 0000000000000000000000000000000000000000..583b8f8fc815f1c7c5b612a745a426250143e040
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique.xml
@@ -0,0 +1,61 @@
+<traduction
+	module="paquet-squelettes_par_rubrique"
+	id="paquet-squelettes_par_rubrique--squelettes_par_rubrique-5b74d"
+	gestionnaire="salvatore"
+	url="https://trad.spip.net"
+	source="https://git.spip.net/spip/squelettes_par_rubrique.git"
+	reference="fr">
+	<langue code="ar" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=ar" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="George" lien="https://trad.spip.net/auteur/جورج-قندلفت" />
+	</langue>
+	<langue code="de" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=de" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="klaus++" lien="https://trad.spip.net/auteur/klaus" />
+	</langue>
+	<langue code="en" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=en" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="kent1" lien="https://trad.spip.net/auteur/kent1" />
+	</langue>
+	<langue code="eo" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=eo" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="gpl" lien="https://trad.spip.net/auteur/gpl" />
+	</langue>
+	<langue code="es" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=es" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="dani" lien="https://trad.spip.net/auteur/dani" />
+	</langue>
+	<langue code="fa" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=fa" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="Davood Hossein" lien="https://trad.spip.net/auteur/davood-hossein" />
+	</langue>
+	<langue code="fr" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=fr" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00" />
+	<langue code="fr_fem" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=fr_fem" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="denisb" lien="https://trad.spip.net/auteur/denisb" />
+	</langue>
+	<langue code="fr_tu" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=fr_tu" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="Cerf" lien="https://trad.spip.net/auteur/cerf" />
+	</langue>
+	<langue code="it" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=it" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="phante" lien="https://trad.spip.net/auteur/phante" />
+	</langue>
+	<langue code="lb" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=lb" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="Jim Wanderscheid" lien="https://trad.spip.net/auteur/jwander" />
+	</langue>
+	<langue code="nl" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=nl" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="Suske" lien="https://trad.spip.net/auteur/suske" />
+	</langue>
+	<langue code="oc_ni_mis" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=oc_ni_mis" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="sylvain" lien="https://trad.spip.net/auteur/sylvain" />
+	</langue>
+	<langue code="pt" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=pt" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="Cláudia Anjos Lopes" lien="https://trad.spip.net/auteur/claudia_a_lopes" />
+	</langue>
+	<langue code="pt_br" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=pt_br" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="Ricardo Porto" lien="https://trad.spip.net/auteur/ricardo-porto" />
+	</langue>
+	<langue code="ru" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=ru" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="olly" lien="https://trad.spip.net/auteur/olly" />
+		<traducteur nom="Serge Markitanenko" lien="https://trad.spip.net/auteur/serge-markitanenko" />
+	</langue>
+	<langue code="sk" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=sk" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="jaro" lien="https://trad.spip.net/auteur/jaro" />
+	</langue>
+	<langue code="uk" url="https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=uk" total="2" traduits="2" relire="0" modifs="0" nouveaux="0" pourcent="100.00">
+		<traducteur nom="olly" lien="https://trad.spip.net/auteur/olly" />
+	</langue>
+</traduction>
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_de.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_de.php
new file mode 100644
index 0000000000000000000000000000000000000000..35f8d3b22441b6e00805741373c5f2e35fc21d2a
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_de.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=de
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Unterstützung der Skelette mit Rubriknummer und/oder Sprachcode als Namenszusatz: (-23.html, =23.html, et .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Unterstützung von Skeletten mit Namenszusatz in SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_en.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_en.php
new file mode 100644
index 0000000000000000000000000000000000000000..57fc9f01254524e9436d38a95010d3513b2741e8
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_en.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=en
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Support of suffixed templates by section number and/or by language code : (-23.html, =23.html, and .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Support of suffixed templates in SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_eo.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_eo.php
new file mode 100644
index 0000000000000000000000000000000000000000..a8556836dbbdf6866f2cb61162d6462248327992
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_eo.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=eo
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Subteno por la skeletoj sufiksitaj per rubrikonumero kaj lingvokodo (ekz., -23.html, =23.html, kaj .eo.html)',
+	'squelettes_par_rubrique_slogan' => 'Subteno por la sufiksitaj skeletoj en SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_es.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_es.php
new file mode 100644
index 0000000000000000000000000000000000000000..b284f04e6a62fe663b7c0844f114a3ceb2b962bb
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_es.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=es
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Implementación de esqueletos con sufijo por numero de sección y/o por código de idioma: (-23.html, =23.html, y .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Implementación de esqueletos con sufijos de SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fa.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fa.php
new file mode 100644
index 0000000000000000000000000000000000000000..17fff10837f1fc449e22e92680d0c385f86b38b4
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fa.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=fa
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'پشتيبان اسكلت‌هاي پسوندي توسط تعدادي بخش و/يا توسط كدر زبان :  (-23.html, =23.html, et .en.html)  ',
+	'squelettes_par_rubrique_slogan' => 'پشتيباني از اسكليت‌هاي  پسوندي در اسپيپ '
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr.php
new file mode 100644
index 0000000000000000000000000000000000000000..50895edbf1dc0dfc4e8e725a8c162aee05c99419
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr.php
@@ -0,0 +1,13 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// Fichier source, a modifier dans https://git.spip.net/spip/squelettes_par_rubrique.git
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Support des squelettes suffixés par numéro de rubrique et/ou par code de langue : (-23.html, =23.html, et .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Support des squelettes suffixés dans SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr_fem.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr_fem.php
new file mode 100644
index 0000000000000000000000000000000000000000..88200c251e98132c34a7552891d79f5aa97a12cf
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr_fem.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=fr_fem
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Support des squelettes suffixés par numéro de rubrique et/ou par code de langue : (-23.html, =23.html, et .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Support des squelettes suffixés dans SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr_tu.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr_tu.php
new file mode 100644
index 0000000000000000000000000000000000000000..1aba5b053a8fea6107009c6d60f87b4d444f7f36
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_fr_tu.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=fr_tu
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Support des squelettes suffixés par numéro de rubrique et/ou par code de langue : (-23.html, =23.html, et .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Support des squelettes suffixés dans SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_it.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_it.php
new file mode 100644
index 0000000000000000000000000000000000000000..e63e03277bd0cb30f6304ca18cd1b2a7e74ef9bb
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_it.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=it
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Supporto dei modelli con suffisso numero di sezione e/o il codice della lingua: (-23.html, =23.html, et .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Supporto di modelli con suffisso in SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_lb.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_lb.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f74a23add0535875bd1ab817b6379b37e0a077e
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_lb.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=lb
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Ënnerstëtzung vun de Skeletter mat engem Suffix fir d’Rubrik an/oder d’Sprooch: (-23.html, =23.html, an .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Ënnerstëtzung fir Skeletter mat Suffix am SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_nl.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_nl.php
new file mode 100644
index 0000000000000000000000000000000000000000..5f8330942395ab840573ced66e787028ab3f0c67
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_nl.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=nl
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Ondersteuning van de suffix ingewijden skeletten (met rubrieknummers en / of taal-code: -23.html, =23.html   en .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Ondersteuning van suffix ingewijden skeletten in SPIP '
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_oc_ni_mis.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_oc_ni_mis.php
new file mode 100644
index 0000000000000000000000000000000000000000..119b61ed2f975b1603458b9cbaf74946ed0b0862
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_oc_ni_mis.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=oc_ni_mis
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Supouòrt dei esquèletrou sufissat per un nùmero de rùbrica e/o per un code de lenga : (-23.html, =23.html, e .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Supouòrt dei esquèletrou sufissat en SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_pt.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_pt.php
new file mode 100644
index 0000000000000000000000000000000000000000..84c90437b86a7caefd2abb2d78c9063f59c9db0e
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_pt.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=pt
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Apoio dos modelos com sufixo por número de rubrica e/ou por código de idioma : (-23.html, =23.html, et .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Apoio de modelos com sufixo em SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_pt_br.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_pt_br.php
new file mode 100644
index 0000000000000000000000000000000000000000..1318e64bc40d952a682f1936037d315106e515dd
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_pt_br.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=pt_br
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Suporte aos gabaritos com sufixo do númeor da seção e/ou por código de idioma: (-23.html, =23.html, et .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Suporte aos gabaritos com sufixo do SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_ru.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_ru.php
new file mode 100644
index 0000000000000000000000000000000000000000..e6ce756a0c2b9f572054f99e0844d9fb26b7677c
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_ru.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=ru
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Позволяет задавать отдельные шаблоны по номеру раздела, статьи, а также языковой версии: (-23.html, =23.html, и .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Номерные шаблоны для SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_sk.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_sk.php
new file mode 100644
index 0000000000000000000000000000000000000000..262b2f9306f90248988664c98dd10bef9ed65bf0
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_sk.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=sk
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Podpora šablón pripojených vo forme prípony podľa čísla rubriky a/lebo kódu jazyka: (-23.html, =23.html a .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Podpora pripojených šablón v SPIPe'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_uk.php b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_uk.php
new file mode 100644
index 0000000000000000000000000000000000000000..1ef95443728a5e3d297dce69b323321407a1669c
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/lang/paquet-squelettes_par_rubrique_uk.php
@@ -0,0 +1,15 @@
+<?php
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// extrait automatiquement de https://trad.spip.net/tradlang_module/paquet-squelettes_par_rubrique?lang_cible=uk
+// ** ne pas modifier le fichier **
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+
+	// S
+	'squelettes_par_rubrique_description' => 'Дозволяє задавати окремі шаблони за номером рубріки, статті, а також мовної версії: (-23.html, =23.html, и .en.html)',
+	'squelettes_par_rubrique_slogan' => 'Шаблони за номерами для SPIP'
+);
diff --git a/design_system_dependences/squelettes_par_rubrique/paquet.xml b/design_system_dependences/squelettes_par_rubrique/paquet.xml
new file mode 100644
index 0000000000000000000000000000000000000000..feda398628d0af905110d19851db3c7acd3a461e
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/paquet.xml
@@ -0,0 +1,15 @@
+<paquet
+	prefix="squelettes_par_rubrique"
+	categorie="outil"
+	version="2.0.1"
+	etat="stable"
+	compatibilite="[4.1.0;4.2.*]"
+	logo="squelettes_par_rubrique-32.png"
+	documentation="https://www.spip.net/3445"
+>
+
+	<nom>Squelettes par Rubrique</nom>
+	<!-- Support des squelettes suffixés dans SPIP -->
+
+	<auteur>Collectif SPIP</auteur>
+</paquet>
diff --git a/design_system_dependences/squelettes_par_rubrique/phpcs.xml.dist b/design_system_dependences/squelettes_par_rubrique/phpcs.xml.dist
new file mode 100644
index 0000000000000000000000000000000000000000..d75d301a1679dec7517b60c515092b744edfaf16
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/phpcs.xml.dist
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<ruleset>
+    <file>.</file>
+    <exclude-pattern>vendor/*</exclude-pattern>
+    <exclude-pattern>lang/*</exclude-pattern>
+    <exclude-pattern>lib/*</exclude-pattern>
+
+    <rule ref="SPIP41"/>
+
+    <config name="ignore_warnings_on_exit" value="1"/>
+    <arg name="cache" value=".php_cs.cache"/>
+    <arg name="report-full" value=".php_cs.txt"/>
+    <arg name="report-summary"/>
+    <arg value="s"/>
+</ruleset>
diff --git a/design_system_dependences/squelettes_par_rubrique/phpstan-baseline.neon b/design_system_dependences/squelettes_par_rubrique/phpstan-baseline.neon
new file mode 100644
index 0000000000000000000000000000000000000000..36f4dac5d0eb0c7aa60172088da393c10b7900dd
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/phpstan-baseline.neon
@@ -0,0 +1,12 @@
+parameters:
+	ignoreErrors:
+		-
+			message: "#^Function lang_select not found\\.$#"
+			count: 2
+			path: squelettes_par_rubrique_options.php
+
+		-
+			message: "#^Function quete_parent not found\\.$#"
+			count: 1
+			path: squelettes_par_rubrique_options.php
+
diff --git a/design_system_dependences/squelettes_par_rubrique/phpstan.neon.dist b/design_system_dependences/squelettes_par_rubrique/phpstan.neon.dist
new file mode 100644
index 0000000000000000000000000000000000000000..9cd9a27ef7e21fab9c0fd609409bd26d8f265566
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/phpstan.neon.dist
@@ -0,0 +1,12 @@
+includes:
+	- phpstan-baseline.neon
+
+parameters:
+    paths:
+        - .
+    excludePaths:
+        analyseAndScan:
+            - vendor
+            - lang
+            - lib
+    level: 0
diff --git a/design_system_dependences/squelettes_par_rubrique/squelettes_par_rubrique-xx.svg b/design_system_dependences/squelettes_par_rubrique/squelettes_par_rubrique-xx.svg
new file mode 100644
index 0000000000000000000000000000000000000000..f26c9488b04e2d2424b10c119de316a0b1dfda68
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/squelettes_par_rubrique-xx.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
+  <path fill="#fff" d="M30.8 18.6v-5.3H10.7V56h48V18.6z"/>
+  <path d="M26.8 50.6h-16V13.3h14.9l5.3 5.3h22.5v10.7h5.3V16c0-1.5-1.2-2.7-2.7-2.7h-23L27.8 8H8c-1.5 0-2.7 1.2-2.7 2.7v42.6C5.3 54.8 6.5 56 8 56h18.8v-5.4z" fill="#666"/>
+  <path d="M55.2 44.6l-1.9 6.1h5.2l-1.1 5.4h-5.9l-2 6.3h-5.9l2-6.3h-5.1l-2 6.3h-5.9l2-6.3h-5.3l1.1-5.4h5.9l1.9-6.1H33l1.1-5.4H40l2-6.3h6l-2 6.3h5.1l2-6.3H59l-2 6.3h5.3l-1.1 5.4h-6zm-5.9 0h-5.1l-1.9 6.1h5.1l1.9-6.1z" fill="#1d83d4"/>
+</svg>
\ No newline at end of file
diff --git a/design_system_dependences/squelettes_par_rubrique/squelettes_par_rubrique_options.php b/design_system_dependences/squelettes_par_rubrique/squelettes_par_rubrique_options.php
new file mode 100644
index 0000000000000000000000000000000000000000..01ec0f9bf83ed1727652b23698b7b3a7085b5964
--- /dev/null
+++ b/design_system_dependences/squelettes_par_rubrique/squelettes_par_rubrique_options.php
@@ -0,0 +1,107 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Système de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright © avec tendresse depuis 2001                                 *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.     *
+ *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+/**
+ * Déclarations de pipelines
+ *
+ * @package SPIP\SquelettesParRubrique\Pipelines
+ **/
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+if (!isset($GLOBALS['spip_pipeline']['styliser'])) {
+	$GLOBALS['spip_pipeline']['styliser'] = '';
+}
+
+// Ajoute à la fin du pipeline styliser la recherche de squelettes par rubriques et par langue
+$GLOBALS['spip_pipeline']['styliser'] .= '||squelettes_par_rubrique_styliser_par_rubrique|squelettes_par_rubrique_styliser_par_langue';
+
+/**
+ * Cherche un squelette par rubrique squelette-XX.html ou squelette=XX.html
+ *
+ * Options de recherche de squelette par le styliseur, appelé par le pipeline 'styliser'
+ *
+ * @pipeline styliser
+ *
+ * @param array $flux Données du pipeline
+ * @return array       Données du pipeline
+ */
+function squelettes_par_rubrique_styliser_par_rubrique($flux) {
+
+	// uniquement si un squelette a ete trouve
+	if ($squelette = $flux['data']) {
+		$ext = $flux['args']['ext'];
+
+		// On selectionne, dans l'ordre :
+		// fond=10
+		if ($id_rubrique = $flux['args']['id_rubrique']) {
+			$f = "$squelette=$id_rubrique";
+			if (@file_exists("$f.$ext")) {
+				$squelette = $f;
+			} else {
+				$maxiter = 10000; // on ne remonte pas au dela en profondeur
+				// fond-10 fond-<rubriques parentes>
+				do {
+					$f = "$squelette-$id_rubrique";
+					if (@file_exists("$f.$ext")) {
+						$squelette = $f;
+						break;
+					}
+				} while (
+					$maxiter--
+					and $id_rubrique = quete_parent($id_rubrique)
+					// se proteger des references circulaires
+					and $id_rubrique != $flux['args']['id_rubrique']
+				);
+			}
+			// sauver le squelette
+			$flux['data'] = $squelette;
+		}
+	}
+
+	return $flux;
+}
+
+
+/**
+ * Cherche l'existence un squelette par langue squelette.en.html
+ *
+ * Options de recherche de squelette par le styliseur, appelé par le pipeline 'styliser'
+ *
+ * @pipeline styliser
+ *
+ * @param array $flux Données du pipeline
+ * @return array       Données du pipeline
+ */
+function squelettes_par_rubrique_styliser_par_langue($flux) {
+
+	// uniquement si un squelette a ete trouve
+	if ($squelette = $flux['data']) {
+		$ext = $flux['args']['ext'];
+
+		// Affiner par lang
+		if ($lang = $flux['args']['lang']) {
+			$l = lang_select($lang);
+			$f = "$squelette." . $GLOBALS['spip_lang'];
+			if ($l) {
+				lang_select();
+			}
+			if (@file_exists("$f.$ext")) {
+				// sauver le squelette
+				$flux['data'] = $f;
+			}
+		}
+	}
+
+	return $flux;
+}