diff --git a/.gitattributes b/.gitattributes
index a7c186b798ddf4b287fc16ddcddd981f907e4b88..bb512fdd9dbb6666fd11e9c451efbc5491bc25ac 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -84,6 +84,7 @@ ecrire/charsets/translit.php -text
 ecrire/charsets/translitcomplexe.php -text
 ecrire/exec_accueil.php -text
 ecrire/exec_admin_effacer.php -text
+ecrire/exec_admin_plugin.php -text
 ecrire/exec_admin_repair.php -text
 ecrire/exec_admin_tech.php -text
 ecrire/exec_admin_vider.php -text
@@ -190,6 +191,7 @@ ecrire/img_pack/degrade.jpg -text
 ecrire/img_pack/deplierbas.gif -text
 ecrire/img_pack/deplierhaut.gif -text
 ecrire/img_pack/deplierhaut_rtl.gif -text
+ecrire/img_pack/descendre-16.png -text
 ecrire/img_pack/doc-24.gif -text
 ecrire/img_pack/documents-48.png -text
 ecrire/img_pack/documents-48_rtl.png -text
@@ -238,12 +240,14 @@ ecrire/img_pack/m_envoi_rtl.gif -text
 ecrire/img_pack/message.gif -text
 ecrire/img_pack/messagerie-24.gif -text
 ecrire/img_pack/messagerie-48.png -text
+ecrire/img_pack/monter-16.png -text
 ecrire/img_pack/mot-cle-24.gif -text
 ecrire/img_pack/naviguer-site.png -text
 ecrire/img_pack/ortho-24.gif -text
 ecrire/img_pack/pense-bete.gif -text
 ecrire/img_pack/petite-cle.gif -text
 ecrire/img_pack/petition-24.gif -text
+ecrire/img_pack/plugin-24.png -text
 ecrire/img_pack/plus.gif -text
 ecrire/img_pack/poubelle.gif -text
 ecrire/img_pack/puce-blanche-anim.gif -text
@@ -335,6 +339,7 @@ ecrire/inc_lang_liste.php -text
 ecrire/inc_magicquotes.php -text
 ecrire/inc_mini_nav.php -text
 ecrire/inc_minipres.php -text
+ecrire/inc_plugin.php -text
 ecrire/inc_popularites.php -text
 ecrire/inc_sites_voir.php -text
 ecrire/inc_suivi_versions.php -text
@@ -343,6 +348,7 @@ ecrire/inc_utils.php -text
 ecrire/lang/ecrire_br.php3 -text
 ecrire/lang/ecrire_cs.php3 -text
 ecrire/lang/ecrire_ru.php3 -text
+ecrire/lang/plugin_fr.php3 -text
 ecrire/lang/public_br.php3 -text
 ecrire/lang/public_cs.php3 -text
 ecrire/lang/public_ru.php3 -text
diff --git a/ecrire/exec_admin_plugin.php b/ecrire/exec_admin_plugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..275a7fe43cd6690c6f71b2ec3760c259d2d43df5
--- /dev/null
+++ b/ecrire/exec_admin_plugin.php
@@ -0,0 +1,175 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2005                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+include_ecrire ("inc_config");
+include_ecrire ("inc_plugin");
+include_ecrire ("inc_presentation");
+include_ecrire ("inc_layer");
+
+function ligne_plug($plug_file,&$plug_actifs,$last_actif = false,$surligne = false){
+		static $id_input=0;
+		global $couleur_claire;
+		$vals = array();
+		$info = plugin_get_infos($plug_file);
+		$plugok='N';
+		if (@in_array($plug_file,$plug_actifs))
+			$plugok='O';
+
+		$s = "";
+		$s .= "<div id='$plug_file'";
+		if ($surligne)
+			$s .= " style='background:$couleur_claire'";
+		$s .= ">";
+		$s .= bouton_block_invisible("$plug_file");
+		$s .= ($plugok=='O'?"<strong>":"").$info['nom'].($plugok=='O'?"</strong>":"");
+		$s .= "</div>";
+		$s .= debut_block_invisible("$plug_file");
+		$s .= _T("plugin:version_plugin") . " : " . $info['version'] . "<br/>";
+		$s .= _T("plugin:repertoire_plugin") . " : " . $plug_file . "<br/>";
+
+		if (isset($info['description']))
+			$s .= "<hr/>" . propre($info['description']) . "<br/>";
+
+		if (isset($info['auteur']))
+			$s .= "<hr/>" . _T("plugin:auteur_plugin") . " : " . propre($info['auteur']) . "<br/>";
+		if (isset($info['lien']))
+			$s .= "<hr/>" . _T("plugin:lien_plugin") . " : " . propre($info['lien']) . "<br/>";
+
+		$s .= fin_block();
+		$vals[] = $s;
+
+		$s = "";
+		if ('O' == $plugok){
+			if ($id_input>0)
+				$s = "<a href='".generer_url_ecrire('admin_plugin',"monter=$plug_file")."'><img src='"._DIR_IMG_PACK."monter-16.png' style='border:0'></a>";
+			$vals[] = $s;
+			$s = "";
+			if (!$last_actif)
+				$s = "<a href='".generer_url_ecrire('admin_plugin',"descendre=$plug_file")."'><img src='"._DIR_IMG_PACK."descendre-16.png' style='border:0'></a>";
+		}
+		else{
+			$vals[] = $s;
+		}
+		$vals[] = $s;
+
+		$s = "";
+		$s .= "<input type='checkbox' name='statusplug_$plug_file' value='O' id='label_$id_input'";
+		$s .= ('O' == $plugok)?" checked='checked'":"";
+		$s .= " /> <label for='label_$id_input'><strong>"._T('plugin:activer_plugin')."</strong></label>";
+		$id_input++;		
+		$vals[] = $s;
+
+		return $vals;
+}
+
+function admin_plugin(){
+	global $connect_statut;
+	global $connect_toutes_rubriques;
+	$surligne = "";
+  
+	if ($connect_statut != '0minirezo' OR !$connect_toutes_rubriques) {
+		debut_page(_T('plugin:onglet_plugin'), "administration", "plugin");
+		echo _T('avis_non_acces_page');
+		fin_page();
+		exit;
+	}
+	
+	// mise à jour des données si envoi via formulaire
+	// sinon fait une passe de verif sur les plugin
+	if ($_POST['changer_plugin']=='oui'){
+		enregistre_modif_plugin();
+		// pour la peine, un redirige, 
+		// que les plugin charges soient coherent avec la liste
+		redirige_par_entete(generer_url_ecrire('admin_plugin'));
+	}
+	else if ($_GET['monter'] || $_GET['descendre']){
+		ordonne_plugin();
+		// pour la peine, un redirige, 
+		// que les plugin charges soient coherent avec la liste
+		if (isset($_GET['monter']))
+			$surligne = "surligne=".$_GET['monter']."#".$_GET['monter'];
+		if (isset($_GET['descendre']))
+			$surligne = "surligne=".$_GET['descendre']."#".$_GET['descendre'];
+		redirige_par_entete(generer_url_ecrire('admin_plugin',$surligne, true));
+	}
+	else
+		verif_plugin();
+	if (isset($_GET['surligne']))
+		$surligne = $_GET['surligne'];
+
+	debut_page(_T('plugin:onglet_plugin'), "administration", "plugin");
+	echo "<br/><br/><br/>";
+	
+	gros_titre(_T('plugin:titre_admin_plugin'));
+	// barre_onglets("administration", "plugin"); // a creer dynamiquement en fonction des plugin chargés qui utilisent une page admin ?
+	
+	debut_gauche();
+	
+	debut_boite_info();
+	
+	echo _T('info_gauche_admin_tech');
+	
+	fin_boite_info();
+	
+	debut_droite();
+	
+	debut_cadre_trait_couleur("plugin-24.png", false, "", _T('plugin:texte_plugin'));
+	
+	echo "\n<p align='justify'>"._T('plugin:texte_presente_plugin')."</p>";
+	echo "\n<div>&nbsp;</div>\n";
+	echo generer_url_post_ecrire("admin_plugin");
+	
+
+	$titre_table = _L("Liste des plugin disponibles");
+	$icone = "plugin-24.png";
+	if ($titre_table) echo "<div style='height: 12px;'></div>";
+	echo "<div class='liste'>";
+	bandeau_titre_boite2($titre_table, $icone, $couleur_claire, "black");
+	echo "<table width='100%' cellpadding='4' cellspacing='0' border='0'>";
+	$tableau = array();
+
+	//
+	// boucle sur les plugins
+	$plugins_actifs=liste_plugin_actifs();
+	$count = 0;
+	foreach ($plugins_actifs as $plug_file){
+		$tableau[] = ligne_plug($plug_file,$plugins_actifs,++$count==count($plugins_actifs),$surligne==$plug_file);
+	}
+	foreach (liste_plugin_inactifs() as $plug_file){
+		$tableau[] = ligne_plug($plug_file,$plugins_actifs,false);
+	}
+
+	$largeurs = array('','15px','20px','120px');
+	$styles = array('arial11', 'arial1','arial1', 'arial1');
+	afficher_liste($largeurs, $tableau, $styles);
+	echo "</table>";
+	echo "</div>\n";
+	
+	echo "\n<input type='hidden' name='id_auteur' value='$connect_id_auteur' />";
+	echo "\n<input type='hidden' name='hash' value='" . calculer_action_auteur("valide_plugin") . "'>";
+	echo "\n<input type='hidden' name='changer_plugin' value='oui'>";
+	//echo "\n<input type='hidden' name='redirect' value='" . _DIR_RESTREINT_ABS . "admin_plugin.php3'>";
+	echo "\n<p>";
+	
+	echo "<div style='text-align:$spip_lang_right'><input type='submit' name='Valider' value='"._T('bouton_valider')."' class='fondo'></div>";
+	fin_cadre_trait_couleur();
+	
+	
+	echo "<br />";
+	
+	fin_page();
+
+}
+
+?>
\ No newline at end of file
diff --git a/ecrire/img_pack/descendre-16.png b/ecrire/img_pack/descendre-16.png
new file mode 100644
index 0000000000000000000000000000000000000000..18bf9f9bee757e10a7b631e71f47fc943bb036de
Binary files /dev/null and b/ecrire/img_pack/descendre-16.png differ
diff --git a/ecrire/img_pack/monter-16.png b/ecrire/img_pack/monter-16.png
new file mode 100644
index 0000000000000000000000000000000000000000..a0110174b701f4c4437e7a02fe60679c36a9d58d
Binary files /dev/null and b/ecrire/img_pack/monter-16.png differ
diff --git a/ecrire/img_pack/plugin-24.png b/ecrire/img_pack/plugin-24.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d4cd5eb5ee4c391bb0bb124ec89dde0445ab155
Binary files /dev/null and b/ecrire/img_pack/plugin-24.png differ
diff --git a/ecrire/inc_boutons.php b/ecrire/inc_boutons.php
index 61e674efaffb6411756632e8ad703c202469cf57..589d9b5b68a147d305e6e8c68874c70249a851f1 100644
--- a/ecrire/inc_boutons.php
+++ b/ecrire/inc_boutons.php
@@ -177,6 +177,9 @@ function definir_barre_boutons() {
 			new Bouton("base-24.gif", "icone_maintenance_site");
 		$sousmenu['admin_vider']=
 			new Bouton("cache-24.gif", "onglet_vider_cache");
+  	if ((@file_exists(_DIR_PLUGINS))&&(is_dir(_DIR_PLUGINS)))
+			$sousmenu['admin_plugin']=
+				new Bouton("plugin-24.png", "icone_admin_plugin");
 	} else {
 		$sousmenu['admin_tech']=
 			new Bouton("base-24.gif", "icone_sauver_site");
@@ -286,7 +289,7 @@ function definir_barre_onglets($rubrique) {
 
 	}
 
-	$onglets = pipeline('ajouter_onglets', $onglets, $rubrique);
+	$onglets = pipeline('ajouter_onglets', array('data'=>$onglets,'args'=>$rubrique));
 
 	return $onglets;
 }
diff --git a/ecrire/inc_plugin.php b/ecrire/inc_plugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..61c6849159c50343bca47862b763c85366fb152d
--- /dev/null
+++ b/ecrire/inc_plugin.php
@@ -0,0 +1,290 @@
+<?
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2006                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+// librairie pour parametrage plugin
+//
+define_once('_FILE_PLUGIN_CONFIG', "plugin.xml");
+
+// besoin de inc_meta (et aussi de version mais on suppose qu'il est cahrgé par ailleurs ...)
+include_ecrire ("inc_db_mysql");
+include_ecrire ("inc_meta");
+
+// lecture des sous repertoire plugin existants
+function liste_plugin_files(){	
+	//unset $plugin_files;
+	$plugin_files=array();// tableau des repertoire de plugin
+  if ((@file_exists(_DIR_PLUGINS))&&(is_dir(_DIR_PLUGINS))){
+		if ($handle = opendir(_DIR_PLUGINS)) {
+			while (false !== ($file = readdir($handle))) {
+				if ($file != "." && $file != "..") {
+					if (@file_exists(_DIR_PLUGINS."$file/"._FILE_PLUGIN_CONFIG)) {
+						// verif de disponibilite des infos minimu
+						// nom, version, class
+						$infos = plugin_get_infos($file);
+						if (isset($infos['nom'])&&isset($infos['version'])&&isset($infos['class']))
+							$plugin_files[]=$file; //le plugin est "valide"
+					}
+				}
+			}
+			closedir($handle);
+		}
+	}
+	return $plugin_files;
+}
+
+//  à utiliser pour initialiser ma variable globale $plugin
+function liste_plugin_actifs(){
+  $meta_plugin = lire_meta('plugin');
+  if (strlen($meta_plugin)>0)
+		return explode(",",lire_meta('plugin')); // mieux avec un unserialize ?
+	else
+		return array();
+}
+
+function ecrire_plugin_actifs($plugin){
+	ecrire_meta('plugin',implode(",", $plugin)); // mieux avec un serialize ?
+
+	if (is_array($plugin)){
+		// charger les infos de plugin en memoire
+		$infos = array();
+		foreach ($plugin as $plug) {
+			$infos[$plug] = plugin_get_infos($plug);
+		}
+	}
+	$start_file = "<"."?php\nif (!defined('_ECRIRE_INC_VERSION')) return;\n";
+	$end_file = "\n?".">";
+	
+	// generer les fichier 
+	// charger_plugins_options.php
+	// charger_plugins_fonctions.php
+	foreach(array('options','fonctions') as $charge){
+		$s = "";
+		if (is_array($infos)){
+			foreach($infos as $plug=>$info){
+				if (isset($info[$charge])){
+					foreach($info[$charge] as $file)
+						$s .= "include_once _DIR_PLUGINS.'$plug/".trim($file)."';\n";
+				}
+				if ($charge=='options')
+					$s .= '$GLOBALS[\'plugins\'][]=\''.$plug.'\';'."\n";
+			}
+		}
+		$filename = _DIR_SESSIONS."charger_plugins_$charge.php";
+		if ($handle = fopen($filename, 'wb')) {
+			@fwrite($handle, $start_file . $s . $end_file);
+			@fclose($handle);
+		}
+	}
+
+	if (is_array($infos)){
+		// construire tableaux de pipelines et matrices
+		// $GLOBALS['spip_pipeline']
+		// $GLOBALS['spip_matrice']
+		foreach($infos as $plug=>$info){
+			$class = trim(array_pop($info['class']));
+			foreach($info['pipeline'] as $pipe){
+				$nom = trim(array_pop($pipe['nom']));
+				if (isset($pipe['action']))
+					$action = trim(array_pop($pipe['action']));
+				else
+					$action = $nom;
+				$GLOBALS['spip_pipeline'][$nom] .= "|$class::$action";
+				if (isset($pipe['inclure'])){
+					$GLOBALS['spip_matrice']["$class::$action"] = 
+						"_DIR_PLUGINS$plug/".array_pop($pipe['inclure']);
+				}
+			}
+		}
+	}
+
+	pipeline_precompile();
+}
+
+// precompilsation des pipelines
+function pipeline_precompile(){
+	global $spip_pipeline, $spip_matrice;
+	$nouveaux_pipe=array();
+	
+	$start_file = "<"."?php\nif (!defined('_ECRIRE_INC_VERSION')) return;\n";
+	$end_file = "\n?".">";
+	foreach($spip_pipeline as $action=>$pipeline){
+		$s_inc = "";
+		$s_call = "function execute_pipeline_$action(\$val){\n";
+		$pipe = array_filter(explode('|',$pipeline));
+		// Eclater le pipeline en filtres et appliquer chaque filtre
+		foreach ($pipe as $fonc) {
+			$s_call .= '$val = minipipe(\''.$fonc.'\', $val);'."\n";
+			if (isset($spip_matrice[$fonc])){
+				$file = $spip_matrice[$fonc];
+				$s_inc .= 'include_once(';
+				// si _DIR_PLUGINS est dans la chaine, on extrait la constante
+				if (($p = strpos($file,'_DIR_PLUGINS'))!==FALSE){
+					if ($p)
+						$s_inc .= "'".substr($file,0,$p)."'.";
+					$s_inc .= "_DIR_PLUGINS.";
+					$s_inc .= "'".substr($file,$p+12)."'";
+				}
+				else
+					$s_inc .= "'$file'";
+				$s_inc .= ');'."\n";
+			}
+		}
+		$s_inc .= "\n";
+		$s_call .= "return \$val;\n}\n";
+		$filename = _DIR_SESSIONS."charger_pipeline_$action.php";
+		if ($handle = fopen($filename, 'wb')) {
+			@fwrite($handle, $start_file . $s_inc . $s_call . $end_file);
+			@fclose($handle);
+		}
+		$nouveaux_pipe[] = "charger_pipeline_$action.php";
+	}
+
+	// nettoyer les anciens fichiers pipeline obsoletes
+	if ($handle = opendir(_DIR_SESSIONS)) {
+		while (false !== ($file = readdir($handle))) {
+			if ($file != "." && $file != "..") {
+				if (preg_match(",^charger_pipeline_(.*).php$,",$file)){
+					if (!in_array($file,$nouveaux_pipe))
+						unlink(_DIR_SESSIONS.$file);
+				}
+			}
+		}
+		closedir($handle);
+	}
+}
+
+// pas sur que ça serve juste au cas où
+function liste_plugin_inactifs(){
+	return array_diff (liste_plugin_files(),liste_plugin_actifs());
+}
+
+// mise à jour du meta en fonction de l'état du répertoire
+// penser à faire une maj du cache =>  ecrire_meta()
+// en principe cela doit aussi initialiser la valeur à vide si elle n'esite pas 
+// risque de pb en php5 à cause du typage ou de null (vérifier dans la doc php)
+function verif_plugin(){
+	$plugin_actifs = liste_plugin_actifs();
+	$plugin_liste = liste_plugin_files();
+	$plugin_new = array_intersect($plugin_actifs,$plugin_liste);
+	ecrire_plugin_actifs($plugin_new);
+	ecrire_metas();
+}
+
+// mise à jour des données si envoi via formulaire
+function enregistre_modif_plugin(){
+  // recuperer les plugins dans l'ordre des $_POST
+  $test = array();
+	foreach(liste_plugin_files() as $file){
+	  $test["statusplug_$file"] = $file;
+	}
+	$plugin=array();
+	foreach($_POST as $choix=>$val){
+	  if (isset($test[$choix])&&$val=='O')
+			$plugin[]=$test[$choix];
+	}
+	ecrire_plugin_actifs($plugin);
+	ecrire_metas();
+	//echo "mise à jour ok";
+}
+
+function ordonne_plugin(){
+	$liste = liste_plugin_actifs();
+	$liste_triee = array();
+	$i=2;
+	foreach($liste as $plug){
+		$index = $i;
+		$i = $i+2;
+		if ($_GET['monter']==$plug) $index = $index-3;
+		if ($_GET['descendre']==$plug) $index = $index+3;
+		$liste_triee[$index] = $plug;
+	}
+	ksort($liste_triee);
+	ecrire_plugin_actifs($liste_triee);
+	ecrire_metas();
+}
+
+function parse_plugin_xml($texte){
+	$out = array();
+  // enlever les commentaires
+  $txt = preg_replace(',<!--(.*?)-->,is','',$texte);
+
+	// tant qu'il y a des tags
+	while(preg_match("{<([^>]*?)>}s",$txt)){
+		// tag ouvrant
+		$chars = preg_split("{<([^>]*?)>}s",$txt,2,PREG_SPLIT_OFFSET_CAPTURE|PREG_SPLIT_DELIM_CAPTURE);
+	
+		// $before doit etre vide ou des espaces uniquements!
+		$before = trim($chars[0][0]);
+
+		if (strlen($before)>0)
+			return $texte; // before non vide, donc on est dans du texte
+	
+		$tag = $chars[1][0];
+		$txt = $chars[2][0];
+	
+		// tag fermant
+		$chars = preg_split("{(</$tag>)}s",$txt,2,PREG_SPLIT_OFFSET_CAPTURE|PREG_SPLIT_DELIM_CAPTURE);
+		if (!isset($chars[1])) { // tag fermant manquant
+			$out[$tag][]="erreur : tag fermant $tag manquant::$txt"; 
+			return $out;
+		}
+		$content = $chars[0][0];
+		$txt = trim($chars[2][0]);
+		$out[$tag][]=parse_plugin_xml($content);
+	}
+	if (count($out))
+		return $out;
+	else{
+		return $txt;
+	}
+}
+
+function chaines_lang($texte){
+	// TODO : prendre en charge le fichier langue specifique du plugin
+	// meme si pas encore charge
+	$regexp = "|<:([^>]*):>|";
+	if (preg_match_all($regexp, $texte, $matches, PREG_SET_ORDER))
+	foreach ($matches as $regs)
+		$texte = str_replace($regs[0],
+		_T($regs[1]), $texte);
+	return $texte;
+}
+
+// lecture du fichier de configuration d'un plugin
+function plugin_get_infos($plug){
+  $ret = array();
+  if ((@file_exists(_DIR_PLUGINS))&&(is_dir(_DIR_PLUGINS))){
+		if (@file_exists(_DIR_PLUGINS."$plug/plugin.xml")) {
+			$texte = file_get_contents(_DIR_PLUGINS."$plug/plugin.xml");
+			$arbre = parse_plugin_xml($texte);
+			$arbre = array_pop($arbre['plugin']); // derniere def plugin
+	
+			$ret['nom'] = join(' ',$arbre['nom']);
+			$ret['version'] = array_pop($arbre['version']);
+			if (isset($arbre['auteur']))
+				$ret['auteur'] = join(',',$arbre['auteur']);
+			if (isset($arbre['description']))
+				$ret['description'] = chaines_lang(join(' ',$arbre['description']));
+			if (isset($arbre['lien']))
+				$ret['lien'] = join(' ',$arbre['lien']);
+			$ret['options'] = $arbre['options'];
+			$ret['fonctions'] = $arbre['fonctions'];
+			$ret['class'] = $arbre['class'];
+			$ret['pipeline'] = $arbre['pipeline'];
+		}
+	}
+	return $ret;
+}
+
+?>
\ No newline at end of file
diff --git a/ecrire/inc_utils.php b/ecrire/inc_utils.php
index e30b89f31fe3f99499499213e036a1b53fcc4a31..a2135614dd536bcaf6f64f86dbb9b19bee2edde5 100644
--- a/ecrire/inc_utils.php
+++ b/ecrire/inc_utils.php
@@ -73,49 +73,46 @@ function include_fonction($nom) {
 // Cf. compose_filtres dans inc-compilo-index.php3, qui est le
 // pendant "compilŽ" de cette fonctionnalite
 
-function pipeline($action, $val) {
-	global $spip_pipeline, $spip_matrice;
-	static $pipe = array();
-	if (!strlen($spip_pipeline[$action])) return $val;
-
-	// Analyser le pipeline
-	// TODO - traiter les arguments  |filtre{arg1,arg2}
-	// TODO - traiter le filtre test |?{true,false}
-	if (!isset($pipe[$action]))
-		$pipe[$action] = array_filter(explode('|',$spip_pipeline[$action]));
-
-	// Eclater le pipeline en filtres et appliquer chaque filtre
-	foreach ($pipe[$action] as $fonc) {
-
-		// fonction
-		if (function_exists($fonc))
-			$val = call_user_func($fonc, $val);
-
-		// Class::Methode
-		else if (preg_match("/^(\w*)::(\w*)$/", $fonc, $regs)                            
-		AND $methode = array($regs[1], $regs[2])
-		AND is_callable($methode))
-			$val = call_user_func($methode, $val);
-
-		// Charger un fichier
-		else if ($f = $spip_matrice[$fonc]) {
-			require_once($f);
-			// fonction (2eme chance)
-			if (function_exists($fonc))
-				$val = call_user_func($fonc, $val);
-			// Class::Methode (2eme chance)
-			else if (preg_match("/^(\w*)::(\w*)$/", $fonc, $regs)                            
-			AND $methode = array($regs[1], $regs[2])
-			AND is_callable($methode))
-				$val = call_user_func($methode, $val);
-			else
-				spip_log("Erreur - '$fonc' non definie !");
-		}
-	}
-
+// appel unitaire d'une fonction du pipeline
+// utilisee dans le script pipeline precompile
+function minipipe($fonc,$val){
+	// fonction
+	if (function_exists($fonc))
+		$val = call_user_func($fonc, $val);
+
+	// Class::Methode
+	else if (preg_match("/^(\w*)::(\w*)$/", $fonc, $regs)
+	AND $methode = array($regs[1], $regs[2])
+	AND is_callable($methode))
+		$val = call_user_func($methode, $val);
+	else
+		spip_log("Erreur - '$fonc' non definie !");
 	return $val;
 }
 
+// chargement du pipeline sous la forme d'un fichier php prepare
+function pipeline($action,$val){
+	$ok = @is_readable($f = _DIR_SESSIONS."charger_pipeline_$action.php");
+	if (!$ok){
+		include_ecrire('inc_plugin');
+		// generer les fichiers php precompiles
+		// de chargement des plugins et des pipelines
+		verif_plugin();
+		$ok = @is_readable($f = _DIR_SESSIONS."charger_pipeline_$action.php");
+		if (!$ok)
+			spip_log("generation de $f impossible; pipeline desactives");
+	}
+	if ($ok){
+		require_once($f);
+		$f = "execute_pipeline_$action";
+		$val = $f($val);
+		// si le flux est une table qui encapsule donnees et autres
+		// on ne ressort du pipe que les donnees
+		if (is_array($val)&&isset($val['data']))
+			$val = $val['data'];
+	}
+	return $val;
+}
 
 //
 // Enregistrement des evenements
@@ -606,19 +603,7 @@ function find_in_path ($filename, $sinon = NULL, $path='AUTO') {
 			return $f;
 		}
 	}
-#	spip_log("find_in_apth a pas vu '$filename' dans $autopath");
-
-}
-
-// charger les definitions des plugins
-function charger_plugins($plugins) {
-	foreach ($plugins as $plug) {
-		if (@is_readable($f = _DIR_PLUGINS.$plug.'/version.php'))
-			include($f);
-		else if (isset($_COOKIE['spip_admin']))
-			echo _L("Erreur plugin &laquo; $plug &raquo; absent.<br />\n");
-	}
-#var_dump($plugins);var_dump($spip_pipeline);var_dump($spip_matrice);exit;
+#	spip_log("find_in_path n'a pas vu '$filename' dans $path");
 }
 
 // predicat sur les scripts de ecrire qui n'authentifient pas par cookie
diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php
index dbcb0cc0338cf1939aa25187abf6e23d803b358b..7e37f719332db77d8e7dba6e0d9e83618f226354 100644
--- a/ecrire/inc_version.php
+++ b/ecrire/inc_version.php
@@ -369,10 +369,6 @@ if ($flag_ob AND strlen(ob_get_contents())==0 AND !headers_sent()) {
 // Lien vers la page demandee et lien nettoye ne contenant que des id_objet
 $clean_link = new Link();
 
-
-if ($plugins)
-	charger_plugins($plugins);
-
 // tidy en ligne de commande (si on ne l'a pas en module php,
 // ou si le module php ne marche pas)
 // '/bin/tidy' ou '/usr/local/bin/tidy' ou tout simplement 'tidy'
@@ -399,6 +395,27 @@ if (!$langue_site) include_ecrire('inc_lang');
 $spip_lang = $langue_site;
 
 
+// chargement des plugins : doit arriver en dernier
+// car dans les plugins on peut inclure inc-version
+// qui ne sera pas execute car _ECRIRE_INC_VERSION est defini
+// donc il faut avoir tout fini ici avant de charger les plugins
+if (@is_readable(_DIR_SESSIONS."charger_plugins_options.php")){
+	// chargement optimise precompile
+	include_once(_DIR_SESSIONS."charger_plugins_options.php");
+}
+else
+{
+	include_ecrire('inc_plugin');
+	// generer les fichiers php precompiles
+	// de chargement des plugins et des pipelines
+	verif_plugin();
+	if (@is_readable(_DIR_SESSIONS."charger_plugins_options.php")){
+		include_once(_DIR_SESSIONS."charger_plugins_options.php");
+	}
+	else
+		spip_log("generation de charger_plugins_options.php impossible; pipeline desactives");
+}
+
 //
 // Installer Spip si pas installe... sauf si justement on est en train
 //
diff --git a/ecrire/lang/plugin_fr.php3 b/ecrire/lang/plugin_fr.php3
new file mode 100644
index 0000000000000000000000000000000000000000..ae485c2c5198bc78eba645799cea4199b767a4a2
--- /dev/null
+++ b/ecrire/lang/plugin_fr.php3
@@ -0,0 +1,22 @@
+<?php
+
+// This is a SPIP language file  --  Ceci est un fichier langue de SPIP
+// fichier de langue pour gestion des plugins
+$GLOBALS[$GLOBALS['idx_lang']] = array(
+'activer_plugin' => 'Activer le plugin',
+
+'auteur_plugin' => 'Auteur',
+
+'lien_plugin' => 'Lien',
+
+'onglet_plugin' => 'Gestion des plugins',
+
+'repertoire_plugin' => 'R&eacute;pertoire',
+
+'texte_plugin' => 'Liste des plugins',
+'texte_presente_plugin' => 'Cette page permet de lister les plugins pr&eacute;sents sur le site ainsi que leur &eacute;tat. Pour le changer, cocher le bouton correspondant et Valider. Les plugins sont &agrave; d&eacute;poser via ftp dans le dossier /plugins',
+'titre_admin_plugin' => 'Gestion des plugins',
+
+'version_plugin' => 'Version'
+);
+?>
\ No newline at end of file
diff --git a/ecrire/lang/spip_fr.php3 b/ecrire/lang/spip_fr.php3
index 80010ea1c3e453b6b8699a18c0cb9695ab5e81c9..7560e7887574f68b2afa37f929ee7195e6afbe93 100644
--- a/ecrire/lang/spip_fr.php3
+++ b/ecrire/lang/spip_fr.php3
@@ -292,6 +292,7 @@ Merci de votre participation
 'ical_texte_rss_breves' => 'Il existe de plus un fichier contenant les br&egrave;ves du site. En pr&eacute;cisant un num&eacute;ro de rubrique, vous obtiendrez uniquement les br&egrave;ves de cette rubrique.',
 'icone_a_suivre' => '&Agrave; suivre',
 'icone_admin_site' => 'Administration du site',
+'icone_admin_plugin' => 'Administration des plugin',
 'icone_agenda' => 'Agenda',
 'icone_aide_ligne' => 'Aide',
 'icone_articles' => 'Articles',
diff --git a/inc-calcul.php3 b/inc-calcul.php3
index b208d60ad4beca7c61309ad28daaef9bb39074c8..d0345c4099a5dbc8c847123b7c5d29dccbf1cac4 100644
--- a/inc-calcul.php3
+++ b/inc-calcul.php3
@@ -35,6 +35,10 @@ if ($f = find_in_path("mes_fonctions" . _EXTENSION_PHP)) {
 	global $dossier_squelettes;
 	include ($f);
 }
+if (@is_readable(_DIR_SESSIONS."charger_plugins_fonctions.php")){
+	// chargement optimise precompile
+	include_once(_DIR_SESSIONS."charger_plugins_fonctions.php");
+}
 
 charger_generer_url();