diff --git a/.gitattributes b/.gitattributes
index 6dfe355508cf98e2ebf705b1ab446830d5b0621b..c154bdbaae9658043bd288cce971b5e579f54231 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -6,6 +6,9 @@ dist/favicon.ico -text
 dist/feed.png -text
 dist/formulaires/choix_mots.html -text
 dist/formulaires/login_forum_abo.html -text
+dist/formulaires/oubli/charger.php -text
+dist/formulaires/oubli/modifier.php -text
+dist/formulaires/oubli/valider.php -text
 dist/icones_barre/agrave-maj.png -text
 dist/icones_barre/blanc.png -text
 dist/icones_barre/eacute-maj.png -text
@@ -436,6 +439,7 @@ ecrire/action/tester.php -text
 ecrire/action/tester_taille.php -text
 ecrire/action/tourner.php -text
 ecrire/action/virtualiser.php -text
+ecrire/balise/formulaire_.php -text
 ecrire/balise/index.php -text
 ecrire/balise/logo_.php -text
 ecrire/balise/url_.php -text
diff --git a/dist/formulaires/oubli.html b/dist/formulaires/oubli.html
index 8ee48299af2ad6db304d19b4458e751758aa9ce7..69bbf9a12c92a1f015678c08d7222364a366125e 100644
--- a/dist/formulaires/oubli.html
+++ b/dist/formulaires/oubli.html
@@ -1,10 +1,13 @@
 <div class="formulaire_spip formulaire_oubli">[
-(#ENV*{message})
+(#ENV*{message_erreur})
 ][
-(#ENV*{message}|?{'',' '})
+(#ENV*{message_ok})
+][
+(#ENV*{editable}|?{' '})
 
 <form id="oubli_form" action="[(#ENV{action})]" method="post">
-	[(#ENV{action}|form_hidden)]
+	[(#REM) activer le traitement auto et dispatch sur charger/valider/modifier]
+	#ACTION_FORMULAIRE{#ENV{action}}
 	<fieldset>
 	<legend><:pass_nouveau_pass:></legend>[
 	<input type="hidden" name="p" value="(#ENV{p})" />
@@ -23,9 +26,8 @@
 </div>
 
 <script type="text/javascript"><!--
-[
-(#ENV*{message}|?{'',' '})
-document.getElementById('oubli').focus()
+[(#ENV*{editable}|?{' '})
+ document.getElementById('oubli').focus()
 ]
 //--></script>
 </div>
\ No newline at end of file
diff --git a/dist/formulaires/oubli/charger.php b/dist/formulaires/oubli/charger.php
new file mode 100644
index 0000000000000000000000000000000000000000..03c50db02b48f12f41acae0912e7afb69b7cc4a9
--- /dev/null
+++ b/dist/formulaires/oubli/charger.php
@@ -0,0 +1,24 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2008                                                *
+ *  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;
+
+// chargement des valeurs par defaut des champs du formulaire
+function formulaires_oubli_charger_dist(){
+	$valeurs = array('p'=>'','oubli'=>'');
+	if (_request('oubli'))
+		return false; // pas de saisie au second tour
+	else
+		return $valeurs;
+}
+
+?>
\ No newline at end of file
diff --git a/dist/formulaires/oubli/modifier.php b/dist/formulaires/oubli/modifier.php
new file mode 100644
index 0000000000000000000000000000000000000000..e235a1e8beaa4fa980a5b40eca87a7cf5dd2bd9f
--- /dev/null
+++ b/dist/formulaires/oubli/modifier.php
@@ -0,0 +1,38 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2008                                                *
+ *  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;
+
+// la saisie a ete validee, on peut agir
+function formulaires_oubli_modifier_dist(){
+echo 'plop';
+	$message = "";
+	if (
+	    ($p = _request('p'))
+	 && ($oubli = _request('oubli'))) {
+		include_spip('inc/acces');
+		$mdpass = md5($oubli);
+		$htpass = generer_htpass($oubli);
+		include_spip('base/abstract_sql');
+		$res = sql_select("login", "spip_auteurs", "cookie_oubli=" . sql_quote($p) . " AND statut<>'5poubelle' AND pass<>''");
+		$row = sql_fetch($res);
+		sql_updateq('spip_auteurs', array('htpass' =>$htpass, 'pass'=>$mdpass, 'alea_actuel'=>'', 'cookie_oubli'=>''), "cookie_oubli=" . sql_quote($p));
+		
+	
+		$login = $row['login'];
+		$message = "<b>" . _T('pass_nouveau_enregistre') . "</b>".
+		"<p>" . _T('pass_rappel_login', array('login' => $login));
+	}
+	return $message;
+}
+
+?>
\ No newline at end of file
diff --git a/ecrire/balise/formulaire_oubli.php b/dist/formulaires/oubli/valider.php
similarity index 59%
rename from ecrire/balise/formulaire_oubli.php
rename to dist/formulaires/oubli/valider.php
index 87827305ee47504d98979b7455338e37cb80aa63..9fd52d99a62e54f56ecafc113a0471eaecc426ac 100644
--- a/ecrire/balise/formulaire_oubli.php
+++ b/dist/formulaires/oubli/valider.php
@@ -27,6 +27,8 @@ function test_oubli($email)
 // http://doc.spip.org/@message_oubli
 function message_oubli($email, $param)
 {
+	include_spip('inc/filtres'); # pour email_valide()
+
 	if (function_exists('test_oubli'))
 		$f = 'test_oubli';
 	else 
@@ -36,6 +38,7 @@ function message_oubli($email, $param)
 	if (!is_array($declaration))
 		return $declaration;
 
+	include_spip('base/abstract_sql');
 	$res = sql_select("id_auteur,statut,pass", "spip_auteurs", "email =" . sql_quote($declaration['mail']));
 
 	if (!$row = sql_fetch($res)) 
@@ -56,57 +59,33 @@ function message_oubli($email, $param)
 			  _T('pass_mail_passcookie',
 			     array('nom_site_spip' => $nom,
 				   'adresse_site' => url_de_base(),
-				   'sendcookie' => generer_url_public('spip_pass', "$param=$cookie", true)))) )
+				   'sendcookie' => generer_url_public('spip_pass', 
+				   "$param=$cookie&formulaire_action="._request('formulaire_action')
+				   ."&formulaire_action_cle="._request('formulaire_action_cle')
+				   ."&formulaire_action_args="._request('formulaire_action_args')
+				   , true)))) )
 	  return _T('pass_recevoir_mail');
 	else
 	  return  _T('pass_erreur_probleme_technique');
 }
 
-// http://doc.spip.org/@balise_FORMULAIRE_OUBLI
-function balise_FORMULAIRE_OUBLI ($p) {
-  return calculer_balise_dynamique($p,'FORMULAIRE_OUBLI',array());
-}
-
-// http://doc.spip.org/@balise_FORMULAIRE_OUBLI_stat
-function balise_FORMULAIRE_OUBLI_stat($args, $filtres) {
-
-	return $args;
-}
-
-// http://doc.spip.org/@balise_FORMULAIRE_OUBLI_dyn
-function balise_FORMULAIRE_OUBLI_dyn()
-{
-$p = _request('p');
-$oubli = _request('oubli');
-$message = '';
-
-// au 3e appel la variable P est positionnee et oubli = mot passe.
-// au 2e appel, P est vide et oubli vaut le mail a qui envoyer le cookie
-// au 1er appel, P et oubli sont vides
-
- if (!$p) {
-	  if ($oubli) $message = message_oubli($oubli, 'p');
- } else {
-	$res = sql_select("login", "spip_auteurs", "cookie_oubli=" . sql_quote($p) . " AND statut<>'5poubelle' AND pass<>''");
-	if (!$row = sql_fetch($res)) 
-		$message = _T('pass_erreur_code_inconnu');
-	else {
-		if ($oubli) {
-			include_spip('inc/acces');
-			$mdpass = md5($oubli);
-			$htpass = generer_htpass($oubli);
-			sql_updateq('spip_auteurs', array('htpass' =>$htpass, 'pass'=>$mdpass, 'alea_actuel'=>'', 'cookie_oubli'=>''), "cookie_oubli=" . sql_quote($p));
-
-			$login = $row['login'];
-			$message = "<b>" . _T('pass_nouveau_enregistre') . "</b>".
-			"<p>" . _T('pass_rappel_login', array('login' => $login));
-		}
+function formulaires_oubli_valider_dist(){
+	$erreurs = array();
+	$p = _request('p');
+	$oubli= _request('oubli');
+	// au second passage, afficher le message
+	if (!$p && $oubli)
+		$erreurs['message_erreur'] = message_oubli($oubli, 'p');
+	elseif($p) {
+		include_spip('base/abstract_sql');
+		$res = sql_select("login", "spip_auteurs", "cookie_oubli=" . sql_quote($p) . " AND statut<>'5poubelle' AND pass<>''");
+		if (!$row = sql_fetch($res))
+			$erreurs['message_erreur'] = _T('pass_erreur_code_inconnu');
+		elseif (!$oubli)
+			$erreurs['message_erreur'] = ' '; // activer la saisie a nouveau
 	}
- }
- return array('formulaires/oubli', 0, 
-	      array('p' => $p,
-		    'message' => $message,
-		    'action' => self()));
+
+	return $erreurs;
 }
 
 ?>
\ No newline at end of file
diff --git a/ecrire/balise/formulaire_.php b/ecrire/balise/formulaire_.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc5adb93cf16f7b1de65fdf569d8e90c34564a7f
--- /dev/null
+++ b/ecrire/balise/formulaire_.php
@@ -0,0 +1,64 @@
+<?php
+
+
+/* prendre en charge par defaut les balises formulaires simples */
+function balise_FORMULAIRE__dist($p) {
+	preg_match(",^FORMULAIRE_(.*)?$,", $p->nom_champ, $regs);
+	$form = $regs[1];
+	
+	return calculer_balise_dynamique($p,"FORMULAIRE_$form",array());
+}
+
+
+/* prendre en charge par defaut les balises dynamiques formulaires simples */
+function balise_FORMULAIRE__dyn($form)
+{
+	$form = strtolower(substr($form,11));
+	
+	// recuperer les arguments passes a la balise
+	$args = func_get_args();
+	// en enlevant le premier qui est le nom de la balise et deja recuperer ci-dessus
+	array_shift($args);
+	
+	$erreurs = isset($_POST["erreurs_$form"])?$_POST["erreurs_$form"]:array();
+	$message_ok = isset($_POST["message_ok_$form"])?$_POST["message_ok_$form"]:"";
+	$message_erreur = isset($erreurs['message_erreur'])?$erreurs['message_erreur']:"";
+	$valeurs = array();
+	$editable = (!isset($_POST["erreurs_$form"])) || count($erreurs);
+
+	if ($charger_valeurs = charger_fonction("charger","formulaires/$form/",true))
+		$valeurs = call_user_func($charger_valeurs,$args);
+	if ($valeurs===false) {
+		// pas de saisie
+		$editable = false;
+		$valeurs = array();
+	}
+
+	$action = self();
+	// recuperer la saisie en cours si erreurs
+	foreach(array_keys($valeurs) as $champ){
+		if ($v = _request($champ))
+			$valeurs[$champ] = $v;
+		$action = parametre_url($action,$champ,''); // nettoyer l'url des champs qui vont etre saisis
+	}
+	$action = parametre_url($action,'formulaire_action',''); // nettoyer l'url des champs qui vont etre saisis
+	$action = parametre_url($action,'formulaire_action_cle',''); // nettoyer l'url des champs qui vont etre saisis
+	$action = parametre_url($action,'formulaire_action_args',''); // nettoyer l'url des champs qui vont etre saisis
+
+	return array("formulaires/$form", 0, 
+		array_merge($valeurs,
+		array(
+			'action' => $action,
+			'formulaire_args' => base64_encode(serialize($args)),
+			'redirect' => '',
+			'id' => isset($valeurs['id'])?$valeurs['id']:'new',
+			'erreurs' => $erreurs,
+			'message_ok' => $message_ok,
+			'message_erreur' => $message_erreur,
+			'form' => $form,
+			'editable' => $editable,
+		))
+	);
+}
+
+?>
\ No newline at end of file
diff --git a/ecrire/public/assembler.php b/ecrire/public/assembler.php
index 861897f83894ffadb5d9d70218280801f6924592..029f52584ba24b9b58914f2718897fa7b0a263ab 100644
--- a/ecrire/public/assembler.php
+++ b/ecrire/public/assembler.php
@@ -97,6 +97,23 @@ function public_assembler_dist($fond, $connect='') {
 		redirige_par_entete($forum_insert());
 	}
 
+	// traiter les formulaires dynamiques simplifies en charger/valider/modifier
+	if (($form = _request('formulaire_action'))
+	 AND ($cle = _request('formulaire_action_cle'))
+	 AND (($args = _request('formulaire_action_args'))!==NULL)) {
+		include_spip('inc/securiser_action');
+		if (($cle == calculer_cle_action($form . $args))
+		 && ($valider = charger_fonction("valider","formulaires/$form/",true))
+		 // charger la langue pour les messages d'erreur et autres
+		 && (include_spip('inc/lang'))
+		 && utiliser_langue_visiteur()
+		 && (count($_POST["erreurs_$form"] = call_user_func_array($valider,unserialize(base64_decode($args))))==0)
+		 && ($modifier = charger_fonction("modifier","formulaires/$form/"))
+		 ) {
+			$_POST["message_ok_$form"] = call_user_func_array($modifier,unserialize(base64_decode($args)));
+		}
+	}
+
 	// si signature de petition, l'enregistrer avant d'afficher la page
 	// afin que celle-ci contienne la signature
 	if (isset($_GET['var_confirm'])) {
diff --git a/ecrire/public/balises.php b/ecrire/public/balises.php
index d94a4730c936e08593d05c50aad3be5c0aa7ad3e..e07366c32daf15d1254d23d2cbda14089af4608c 100644
--- a/ecrire/public/balises.php
+++ b/ecrire/public/balises.php
@@ -1293,4 +1293,27 @@ function balise_AIDER_dist($p) {
 	return $p;
 }
 
+// creer le contexte de traitement des formulaires dynamiques en charger/valider/modifier
+// et les hidden de l'url d'action
+function balise_ACTION_FORMULAIRE($p){
+	$_form = "'".addslashes(basename($p->descr['sourcefile'],'.html'))."'";
+	$_url = interprete_argument_balise(1,$p);
+	$p->code = "";
+
+	if (strlen($_url))
+		$p->code .= " . (form_hidden($_url))";
+	if (strlen($_form))
+		$p->code .= 
+		// envoyer le nom du formulaire que l'on traite
+		". '<input type=\'hidden\' name=\'formulaire_action\' value=\'' . $_form . '\' />'"
+		// transmettre les eventuels args de la balise formulaire
+		. ". '<input type=\'hidden\' name=\'formulaire_action_args\' value=\'' . @\$Pile[0]['formulaire_args']. '\' />'"
+		. ". '<input type=\'hidden\' name=\'formulaire_action_cle\' value=\'' . (include_spip('inc/securiser_action')?calculer_cle_action(".$_form." . @\$Pile[0]['formulaire_args'] ):'') . '\' />'";
+	
+	if (strlen($p->code))
+		$p->code = "'<div>'" . $p->code . " . '</div>'";
+	$p->interdire_scripts = false;
+	return $p;
+}
+
 ?>