diff --git a/dist/formulaires/ecrire_auteur.php b/dist/formulaires/ecrire_auteur.php
index 6f27ff8892ef9debd320a3be7b7e306ef0277160..1f1c7a6599a9e83191cda1aaba4a843986bc0579 100644
--- a/dist/formulaires/ecrire_auteur.php
+++ b/dist/formulaires/ecrire_auteur.php
@@ -59,7 +59,7 @@ function formulaires_ecrire_auteur_traiter_dist($id_auteur, $id_article, $mail){
 				"X-Originating-IP: ".$GLOBALS['ip']);
 	$message = _T("form_prop_message_envoye");
 
-	return _T("form_prop_message_envoye");
+	return array('message_ok'=>$message);
 }
 
 ?>
\ No newline at end of file
diff --git a/dist/formulaires/forum.php b/dist/formulaires/forum.php
index a05fcdda96ca612eac20350153f40c82116d65fc..4a3c89f216436452e00c39453a48bb7788455d60 100644
--- a/dist/formulaires/forum.php
+++ b/dist/formulaires/forum.php
@@ -287,10 +287,8 @@ function formulaires_forum_traiter_dist() {
 
 	$forum_insert = charger_fonction('forum_insert', 'inc');
 
-	$redirect = $forum_insert();
-
-	include_spip('inc/headers');
-	return redirige_formulaire($redirect);
+	list($redirect,$id_forum) = $forum_insert();
+	return array('redirect'=>$redirect,'id_forum'=>$id_forum);
 }
 
 
diff --git a/dist/formulaires/inscription.php b/dist/formulaires/inscription.php
index ab043343ed8fe0e8516d230f5fe9a1c639109ef0..426dcdfeeeb4632f549d420aaf5ca6ad41c351b9 100644
--- a/dist/formulaires/inscription.php
+++ b/dist/formulaires/inscription.php
@@ -106,7 +106,7 @@ function formulaires_inscription_traiter_dist($mode, $focus, $id=0) {
 			$desc = _T('form_forum_probleme_mail');
 	}
 
-	return is_string($desc) ? $desc : _T('form_forum_identifiant_mail');
+	return array('message_ok'=>is_string($desc) ? $desc : _T('form_forum_identifiant_mail'));
 }
 
 // fonction qu'on peut redefinir pour filtrer les adresses mail et les noms,
diff --git a/dist/formulaires/mot_de_passe.php b/dist/formulaires/mot_de_passe.php
index 431669037ed84e0feb2774aa6728b85bc3a3409f..c7d10db4a6b930a573b04b712da14f55ff4f6b36 100644
--- a/dist/formulaires/mot_de_passe.php
+++ b/dist/formulaires/mot_de_passe.php
@@ -91,6 +91,6 @@ function formulaires_mot_de_passe_traiter_dist($id_auteur=null){
 		$message = "<b>" . _T('pass_nouveau_enregistre') . "</b>".
 		"<p>" . _T('pass_rappel_login', array('login' => $login));
 	}
-	return $message;
+	return array('message_ok'=>$message);
 }
 ?>
\ No newline at end of file
diff --git a/dist/formulaires/oubli.php b/dist/formulaires/oubli.php
index b237fb4c5bea0f63e9e0c406c3ed2ba493e98e11..595f875fb22d683af917f7a7298cc6256a46feae 100644
--- a/dist/formulaires/oubli.php
+++ b/dist/formulaires/oubli.php
@@ -56,7 +56,7 @@ function message_oubli($email, $param)
 function formulaires_oubli_traiter_dist(){
 
 	$message = message_oubli(_request('oubli'),'p');
-	return $message;
+	return array('message_ok'=>$message);
 }
 
 
diff --git a/dist/formulaires/signature.php b/dist/formulaires/signature.php
index fd3f1f66ec9bf32f186bddeda1252ee9ac71034c..3d3c33139a4a114b07a8d6f17af60261094dd4ae 100644
--- a/dist/formulaires/signature.php
+++ b/dist/formulaires/signature.php
@@ -123,7 +123,7 @@ function formulaires_signature_traiter_dist($id_article, $petition, $texte, $sit
 		_request('signature_url_site'), _request('url_page'));
 	}
 
-	return $reponse;
+	return array('message_ok'=>$reponse);
 }
 
 // Retour a l'ecran du lien de confirmation d'une signature de petition.
diff --git a/dist/formulaires/site.php b/dist/formulaires/site.php
index 525f7afacff39da1480646bea58caad277532e4a..e40017fe5275117616482ab3eeea533ae9267a79 100644
--- a/dist/formulaires/site.php
+++ b/dist/formulaires/site.php
@@ -39,15 +39,14 @@ function formulaires_site_verifier_dist($id_rubrique){
 }
 
 function formulaires_site_traiter_dist($id_rubrique){
-	
-	$message = _T('titre_probleme_technique');
+	$res = array('message_erreur'=>_T('titre_probleme_technique'));
 
 	$nom = _request('nom_site');
 	$url = _request('url_site');
 	$desc = _request('description_site');
 
 	include_spip('base/abstract_sql');
-	if (sql_insertq('spip_syndic', array(
+	if ($id_syndic = sql_insertq('spip_syndic', array(
 		'nom_site' => $nom,
 		'url_site' => $url,
 		'id_rubrique' => $id_rubrique,
@@ -57,9 +56,9 @@ function formulaires_site_traiter_dist($id_rubrique){
 		'date_syndic' => 'NOW()',
 		'statut' => 'prop',
 		'syndication' => 'non')))
-			  $message = _T('form_prop_enregistre');
+			  $res = array('message_ok' => _T('form_prop_enregistre'), 'id_syndic'=>$id_syndic);
 
-	return $message;
+	return $res;
 }
 
 ?>
diff --git a/ecrire/inc/documents.php b/ecrire/inc/documents.php
index 76f832ff9881aa8ff85b2a9a9589a6f0cace12d2..c67ca86948fe710399ceda89b8e478492641fb82 100644
--- a/ecrire/inc/documents.php
+++ b/ecrire/inc/documents.php
@@ -35,11 +35,15 @@ function get_spip_doc($fichier) {
 	// gestion d'erreurs, fichier=''
 	if (!strlen($fichier))
 		return false;
+	
+	$fichier = (strpos($fichier, _DIR_IMG) === false)
+		? _DIR_IMG . $fichier
+		: $fichier ;
+	if ($m = @filemtime($fichier))
+		$fichier .= "?$m";
 
 	// fichier normal
-	return (strpos($fichier, _DIR_IMG) === false)
-		? _DIR_IMG . $fichier
-		: $fichier;
+	return $fichier;
 }
 
 // Filtre pour #ID_DOCUMENT ou #FICHIER
diff --git a/ecrire/inc/editer.php b/ecrire/inc/editer.php
index 13f14492437cfa789d58e3aca4e7938f7b675d45..2f67ef79e4d1bf1cba3fd57a115caf83881c5265 100644
--- a/ecrire/inc/editer.php
+++ b/ecrire/inc/editer.php
@@ -16,18 +16,19 @@ include_spip('base/abstract_sql');
 // http://doc.spip.org/@formulaires_editer_objet_traiter
 function formulaires_editer_objet_traiter($type, $id='new', $id_parent=0, $lier_trad=0, $retour='', $config_fonc='articles_edit_config', $row=array(), $hidden=''){
 
-	$message = "";
+	$res = array();
 	$action_editer = charger_fonction("editer_$type",'action');
 	list($id,$err) = $action_editer();
+	$id_table_objet = id_table_objet($type);
+	$res[$id_table_objet] = $id;
 	if ($err){
-		$message .= $err;
+		$res['message_erreur'] =$err;
 	}
 	elseif ($retour) {
-		include_spip('inc/headers');
-		$id_table_objet = id_table_objet($type);
-		$message .= redirige_formulaire(parametre_url($retour,$id_table_objet,$id));
+		$res['message_ok'] = ""; // il faudrait faire mieux que cela !
+		$res['redirect'] = parametre_url($retour,$id_table_objet,$id);
 	}
-	return $message;
+	return $res;
 }
 
 // http://doc.spip.org/@formulaires_editer_objet_verifier
diff --git a/ecrire/inc/forum_insert.php b/ecrire/inc/forum_insert.php
index a1893538fb56c4a68b15d47febcebde001b4ec22..7f9461b96110ea8afb04878386baccf6b6224391 100644
--- a/ecrire/inc/forum_insert.php
+++ b/ecrire/inc/forum_insert.php
@@ -104,14 +104,14 @@ function inc_forum_insert_dist($force_statut = NULL) {
 
 	$id_message = forum_insert_base($c, $id_forum, $id_article, $id_breve, $id_syndic, $id_rubrique, $statut, $retour);
 
-	if (!$id_message) return $retour; // echec
+	if (!$id_message) return array($retour,0); // echec
 
 	// En cas de retour sur (par exemple) {#SELF}, on ajoute quand
 	// meme #forum12 a la fin de l'url, sauf si un #ancre est explicite
 	if ($reqret !== '!')
-		return strstr('#', $retour) ?
+		return array(strstr('#', $retour) ?
 			$retour
-			: $retour.'#forum'.$id_message;
+			: $retour.'#forum'.$id_message,$id_message);
 
 	// le retour par defaut envoie sur le thread, ce qui permet
 	// de traiter elegamment le cas des forums moderes a priori.
@@ -119,7 +119,7 @@ function inc_forum_insert_dist($force_statut = NULL) {
 	// dans le cas des forums moderes a posteriori, ce qui n'est
 	// pas plus mal.
 
-	return generer_url_entite($id_message, 'forum');
+	return array(generer_url_entite($id_message, 'forum'),$id_message);
 }
 
 // http://doc.spip.org/@forum_insert_base
diff --git a/ecrire/inc/plugin.php b/ecrire/inc/plugin.php
index eb03c88a65bbb16b3d25fc321a97830ec515218f..c5fb390075ca868ccf82c7ec81464f37e45030ef 100644
--- a/ecrire/inc/plugin.php
+++ b/ecrire/inc/plugin.php
@@ -433,7 +433,7 @@ function pipeline_precompile(){
 			}
 		}
 		$content .= "// Pipeline $action \n";
-		$content .= "function execute_pipeline_$action(\$val){\n";
+		$content .= "function execute_pipeline_$action(&\$val){\n";
 		$content .= $s_inc?"error_reporting(SPIP_ERREUR_REPORT_INCLUDE_PLUGINS);\n":"";
 		$content .= $s_inc;
 		$content .= $s_inc?"error_reporting(SPIP_ERREUR_REPORT);\n":"";
diff --git a/ecrire/public/aiguiller.php b/ecrire/public/aiguiller.php
index d05cbcc6b03793f0664e31621e348a582a439704..be765bb41968304716f64edae1e196e84b7fee5b 100644
--- a/ecrire/public/aiguiller.php
+++ b/ecrire/public/aiguiller.php
@@ -141,12 +141,46 @@ function traiter_formulaires_dynamiques($get=false){
 						'args'=>array('form'=>$form,'args'=>$args),
 						'data'=>$rev)
 					);
-					// traiter peut retourner soit un message, soit un array(editable,message)
-					if (is_array($rev)) {
-						$post["editable_$form"] = reset($rev);
-						$post["message_ok_$form"] = end($rev);
-					} else
-						$post["message_ok_$form"] = $rev;
+			// le retour de traiter peut avoir 3 formats
+			// - simple message texte
+			// - tableau a deux entrees ($editable,$message)
+			// - tableau explicite ('editable'=>$editable,'message_ok'=>$message,'redirect'=>$redirect,'id_xx'=>$id_xx)
+			// le dernier format est celui conseille car il permet le pipelinage, en particulier
+			// en y passant l'id de l'objet cree/modifie
+			// si message_erreur est present, on considere que le traitement a echoue
+			// cas du message texte simple
+			if (!is_array($rev)){
+				$post["message_ok_$form"] = $rev;
+			}
+			// cas du tableau deux valeurs simple (ancien format, deconseille)
+			elseif (count($rev)==2 
+			  AND !array_key_exists('message_ok',$rev)
+			  AND !array_key_exists('message_erreur',$rev)
+			  AND !array_key_exists('redirect',$rev)) {
+				$post["editable_$form"] = reset($rev);
+				$post["message_ok_$form"] = end($rev);
+			}
+			// cas du tableau explicite (conseille)
+			else {
+				// verifier si traiter n'a pas echoue avec une erreur :
+				if (isset($rev['message_erreur'])) {
+					$post["erreurs_$form"]["message_erreur"] = $rev['message_erreur'];
+					
+				}
+				else {
+					// sinon faire ce qu'il faut :
+					if (isset($rev['message_ok']))
+						$post["message_ok_$form"] = $rev['message_ok'];
+					if (isset($rev['editable']))
+						$post["editable_$form"] = $rev['editable'];
+					// si une redirection est demandee, appeler redirigae_formulaire qui choisira
+					// le bon mode de redirection (302 et on ne revient pas ici, ou javascript et on continue)
+					if (isset($rev['redirect'])){
+						include_spip('inc/headers');
+						$post["message_ok_$form"] .= redirige_formulaire($rev['redirect']);
+					}
+				}
+			}
 		}
 		// si le formulaire a ete soumis en ajax, on le renvoie direct !
 		if (_request('var_ajax')){
diff --git a/ecrire/public/composer.php b/ecrire/public/composer.php
index 2e6af3f170736627e15692b0f7403a110fe4b734..bd019d9fa76d3b47dc8663d72d7e51dd17201ae6 100644
--- a/ecrire/public/composer.php
+++ b/ecrire/public/composer.php
@@ -234,7 +234,10 @@ function calcule_logo($type, $onoff, $id, $id_rubrique, $flag_fichier) {
 			else {
 				$off = ($onoff != 'ON') ? '' :
 					$chercher_logo($id, $type, 'off');
-				return array ($on[0], ($off ? $off[0] : ''));
+				// on retourne une url du type IMG/artonXX?timestamp
+				// qui permet de distinguer le changement de logo
+				// et placer un expire sur le dossier IMG/
+				return array ($on[0].($on[4]?"?$on[4]":"") , ($off ? $off[0] . ($off[4]?"?$off[4]":"") : ''));
 			}
 		}
 		else if ($id_rubrique) {
diff --git a/prive/formulaires/editer_groupe_mot.php b/prive/formulaires/editer_groupe_mot.php
index e8f8935bcedae0d2d84519bda5d9e53ca36880e6..220cb1982c0857238b82f53e3690e0aceb9680eb 100644
--- a/prive/formulaires/editer_groupe_mot.php
+++ b/prive/formulaires/editer_groupe_mot.php
@@ -51,20 +51,8 @@ function formulaires_editer_groupe_mot_verifier_dist($id_groupe='new',$retour=''
 
 // http://doc.spip.org/@inc_editer_groupe_mot_dist
 function formulaires_editer_groupe_mot_traiter_dist($id_groupe='new',$retour='', $config_fonc='groupes_mots_edit_config', $row=array(), $hidden=''){
-	$message = '';
 	set_request('redirect','');
-	$action_editer = charger_fonction("editer_groupe_mot",'action');
-	list($id_groupe,$err) = $action_editer();
-	if ($err){
-		$message .= $err;
-	}
-	else {
-		if ($retour) {
-			include_spip('inc/headers');
-			$message .= redirige_formulaire(parametre_url($retour,'id_groupe',$id_groupe));
-		}
-	}
-	return $message;
+	return formulaires_editer_objet_traiter('groupe_mot',$id_groupe,0,0,$retour,$config_fonc,$row,$hidden);
 }
 
 
diff --git a/prive/formulaires/editer_mot.php b/prive/formulaires/editer_mot.php
index ccf4255b570976338cf2b324b65046849ae3fe63..390ca66ac39dd914f3e005052c6c5998333a8881 100644
--- a/prive/formulaires/editer_mot.php
+++ b/prive/formulaires/editer_mot.php
@@ -53,24 +53,22 @@ function formulaires_editer_mot_verifier_dist($id_mot='new', $id_groupe=0, $reto
 
 // http://doc.spip.org/@inc_editer_mot_dist
 function formulaires_editer_mot_traiter_dist($id_mot='new', $id_groupe=0, $retour='', $ajouter_id_article=0, $table='', $table_id=0, $config_fonc='mots_edit_config', $row=array(), $hidden=''){
-	$message = '';
+	$res = '';
 	set_request('redirect','');
 	$action_editer = charger_fonction("editer_mot",'action');
 	list($id_mot,$err) = $action_editer();
 	if ($err){
-		$message .= $err;
+		$res['message_erreur'] = $err;
 	}
 	else {
 		if ($ajouter_id_article){
 			$id_groupe = intval(_request('id_groupe'));
 			ajouter_nouveau_mot($id_groupe, $table, $table_id, $id_mot, $ajouter_id_article);
 		}
-		if ($retour) {
-			include_spip('inc/headers');
-			$message .= redirige_formulaire(parametre_url($retour,'id_mot',$id_mot));
-		}
+		if ($retour)
+			$res['redirect'] = $retour;
 	}
-	return $message;
+	return $res;
 }
 
 
diff --git a/prive/formulaires/login.php b/prive/formulaires/login.php
index 96e732e16f79f3280d277a915bdf6139c98c3c2f..2531c07dc557a2b76027e02a72a87170ee19d5e1 100644
--- a/prive/formulaires/login.php
+++ b/prive/formulaires/login.php
@@ -176,7 +176,7 @@ function formulaires_login_verifier_dist($cible="",$login="",$prive=null){
 }
 
 function formulaires_login_traiter_dist($cible="",$login="",$prive=null){
-	$message = '';	
+	$res = array();
 	// Si on se connecte dans l'espace prive, 
 	// ajouter "bonjour" (repere a peu pres les cookies desactives)
 	if (is_null($prive) ? is_url_prive($cible) : $prive) {
@@ -204,14 +204,14 @@ function formulaires_login_traiter_dist($cible="",$login="",$prive=null){
 	 AND ($cible!=self())) {
 		if (!headers_sent() AND !$_GET['var_mode']) {
 			include_spip('inc/headers');
-			$message .= redirige_formulaire($cible);
+			$res['redirect'] = $cible;
 		} else {
-			$message .= "<a href='$cible'>" .
+			$res['message_ok'] .= "<a href='$cible'>" .
 			  _T('login_par_ici') .
 			  "</a>";
 		}
 	}
-	return $message;
+	return $res;
 }