diff --git a/.gitattributes b/.gitattributes
index 1cfdfaa53fc360b0b1cc0ec0258ff6e0d3102ec7..35798078b5ea6775649f3079d9b97191d1811da3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4,9 +4,6 @@
 config/remove.txt -text
 dist/favicon.ico -text
 dist/feed.png -text
-dist/fond/ajax.html -text
-dist/fond/ajax_fonctions.php -text
-dist/fond/ajax_stat.html -text
 dist/formfx.css -text
 dist/formulaires/choix_mots.html -text
 dist/formulaires/editer_article.html -text
diff --git a/dist/fond/ajax.html b/dist/fond/ajax.html
deleted file mode 100644
index 02f72184db6ec2977f89665748288a963c9cc62f..0000000000000000000000000000000000000000
--- a/dist/fond/ajax.html
+++ /dev/null
@@ -1,8 +0,0 @@
-[(#REM)
-
-	Traiter les < INCLURE {ajax} >
-
-]
-<div class='ajaxbloc[ env-(#ENV**|encoder_contexte_ajax)]'>
-<INCLURE{fond=#ENV*{fond_ajax}}{env} />
-</div><!-- ajaxbloc -->
diff --git a/dist/fond/ajax_fonctions.php b/dist/fond/ajax_fonctions.php
deleted file mode 100644
index e417070c178a2b37aa618c7092bc406835fb6250..0000000000000000000000000000000000000000
--- a/dist/fond/ajax_fonctions.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?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;
-
-/* filtre necessaire pour que la pagination ajax ne soit pas plantee
- * si on charge la page &debut_x=1 : car alors en cliquant sur l'item 0,
- * le debut_x=0 n'existe pas, et on resterait sur 1
- */
-function supprimer_debuts($env) {
-	$env = unserialize($env);
-	foreach ($env as $k => $v)
-		if (strpos($k,'debut_') === 0)
-			unset($env[$k]);
-	return serialize($env);
-}
-
-?>
\ No newline at end of file
diff --git a/dist/fond/ajax_stat.html b/dist/fond/ajax_stat.html
deleted file mode 100644
index b2d863b0b51b73dd58f2ac1d58ed1a30275626b4..0000000000000000000000000000000000000000
--- a/dist/fond/ajax_stat.html
+++ /dev/null
@@ -1,9 +0,0 @@
-[(#REM)
-
-	Traiter les # INCLURE {ajax}
-
-][
-<div class='ajaxbloc[ env-(#ENV**|encoder_contexte_ajax)]'>
-(#INCLURE{fond=#ENV*{fond_ajax}}{env})
-</div><!-- ajaxbloc -->
-]
diff --git a/dist/javascript/ajaxCallback.js b/dist/javascript/ajaxCallback.js
index d5130be5718c681e6356b6f99c1bd2eb9c4673c4..296010a288bb5721ef28c71dcb24e09536fd382c 100644
--- a/dist/javascript/ajaxCallback.js
+++ b/dist/javascript/ajaxCallback.js
@@ -113,7 +113,7 @@ jQuery.fn.formulaire_dyn_ajax = function(target) {
   });
 }
 
-// rechargement ajax d'une noisette implementee par fond/ajax.html
+// rechargement ajax d'une noisette implementee par {ajax}
 // avec mise en cache des url
 var preloaded_urls = {};
 var ajaxbloc_selecteur;
diff --git a/ecrire/inc/filtres.php b/ecrire/inc/filtres.php
index 31b5e810899a0ac75193098a3c2a63d0ee9682c9..4fa736f63919846186067962c251ad41e326f8ed 100644
--- a/ecrire/inc/filtres.php
+++ b/ecrire/inc/filtres.php
@@ -2526,6 +2526,14 @@ function encoder_contexte_ajax($c) {
 	AND !is_null(@unserialize($c)))
 		$c = unserialize($c);
 
+	// supprimer les parametres debut_x
+	// pour que la pagination ajax ne soit pas plantee
+	// si on charge la page &debut_x=1 : car alors en cliquant sur l'item 0,
+	// le debut_x=0 n'existe pas, et on resterait sur 1
+	foreach ($c as $k => $v)
+		if (strpos($k,'debut_') === 0)
+			unset($c[$k]);
+
 	include_spip("inc/securiser_action");
 	$cle = calculer_cle_action($c);
 	$c = serialize(array($c,$cle));
@@ -2544,7 +2552,7 @@ function decoder_contexte_ajax($c) {
 	$c = @base64_decode($c);
 	$c = _xor($c);
 	if (function_exists('gzinflate'))
-		$c = gzinflate($c);
+		$c = @gzinflate($c);
 	list($env, $cle) = @unserialize($c);
 
 	if ($cle == calculer_cle_action($env))
@@ -2555,8 +2563,10 @@ function decoder_contexte_ajax($c) {
 // http://www.php.net/manual/fr/language.operators.bitwise.php#81358
 // http://doc.spip.org/@_xor
 function _xor($message, $key=null){
-	if (is_null($key))
-		$key = $GLOBALS['meta']['secret_du_site'];
+	if (is_null($key)) {
+		include_spip("inc/securiser_action");
+		$key = pack("H*", calculer_cle_action('_xor'));
+	}
 
 	$keylen = strlen($key);
 	$messagelen = strlen($message);
diff --git a/ecrire/public/assembler.php b/ecrire/public/assembler.php
index b64ccf4679211b4180b1fd40d5f579dae382d577..aa0b0253791a13200c0bdc9b1243b4716366f882 100644
--- a/ecrire/public/assembler.php
+++ b/ecrire/public/assembler.php
@@ -120,7 +120,7 @@ function traiter_formulaires_dynamiques(){
 		AND $args = _request('var_ajax_env')) {
 			include_spip('inc/filtres');
 			if ($args = decoder_contexte_ajax($args)
-			AND $fond = $args['fond_ajax']) {
+			AND $fond = $args['fond']) {
 				include_spip('public/parametrer');
 				$contexte = calculer_contexte();
 				$contexte = array_merge($args, $contexte);
@@ -130,7 +130,7 @@ function traiter_formulaires_dynamiques(){
 			}
 			else {
 				include_spip('inc/actions');
-				ajax_retour('signature ajax incorrecte');
+				ajax_retour('signature ajax incorrecte 1');
 			}
 			exit();
 		}
@@ -165,7 +165,7 @@ function traiter_formulaires_dynamiques(){
 				}
 			} else {
 				include_spip('inc/actions');
-				ajax_retour('signature ajax incorrecte');
+				ajax_retour('signature ajax incorrecte 2');
 				exit;
 			}
 		}
@@ -691,11 +691,6 @@ function inclure_modele($type, $id, $params, $lien, $connect='') {
 	// Traiter les parametres
 	// par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en>
 	$arg_list = creer_contexte_de_modele($params);
-	if (isset($arg_list['ajax']) && $arg_list['ajax']=='ajax'){
-		$contexte['fond_ajax']=$contexte['fond'];
-		$contexte['fond']='fond/ajax';
-		unset($arg_list['ajax']);
-	}
 	$contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args
 	$contexte = array_merge($contexte,$arg_list);
 
@@ -737,6 +732,17 @@ function inclure_modele($type, $id, $params, $lien, $connect='') {
 	} else if ($lien)
 		$retour = "<a href='".$lien[0]."' class='".$lien[1]."'>".$retour."</a>";
 
+	// Gerer ajax
+	if (isset($arg_list['ajax'])
+	AND $arg_list['ajax']=='ajax'
+	AND strlen($retour)) {
+		$retour = "<div class='ajaxbloc env-"
+			. encoder_contexte_ajax($contexte)
+			. "'>\n"
+			. $retour
+			. "</div><!-- ajaxbloc -->\n";
+	}
+
 	$compteur--;
 	return $retour;
 }
diff --git a/ecrire/public/balises.php b/ecrire/public/balises.php
index cb385c6a2d8a09579b46643099355ed9dae09de4..f779766b20898ed192d5cb6f07704e6e68aed132 100644
--- a/ecrire/public/balises.php
+++ b/ecrire/public/balises.php
@@ -1078,13 +1078,6 @@ function balise_INCLURE_dist($p) {
 
 	if (isset($_contexte['fond'])) {
 
-		// Gerer ajax
-		if (isset($_contexte['ajax'])){
-			$_contexte['fond_ajax'] = preg_replace(",fond,","fond_ajax",$_contexte['fond'],1);
-			$_contexte['fond'] = "'fond' => 'fond/ajax_stat'";
-			unset($_contexte['ajax']);
-		}
-
 		// #INCLURE{doublons}
 		if (isset($_contexte['doublons'])) {
 			$_contexte['doublons'] = "'doublons' => \$doublons";
@@ -1106,7 +1099,19 @@ function balise_INCLURE_dist($p) {
 		$connect = !$id_boucle ? '' 
 		  : $p->boucles[$id_boucle]->sql_serveur;
 
-		$p->code = "recuperer_fond('',".$l.", false, " . sql_quote($connect) .")";
+		$p->code = "recuperer_fond('',\$l = ".$l.", false, " . sql_quote($connect) .")";
+
+		// Gerer ajax
+		if (isset($_contexte['ajax'])) {
+			$p->code = '( // {ajax}
+				($t = '.$p->code.')
+				? "<div class=\'ajaxbloc env-"
+					.encoder_contexte_ajax($l)
+					."\'>\\n".$t."</div><!-- ajaxbloc -->\\n"
+				: ""
+			)';
+		}
+
 	} else {
 		$n = interprete_argument_balise(1,$p);
 		if (!$n) {
@@ -1151,34 +1156,39 @@ function balise_MODELE_dist($p) {
 	// a priori true
 	// si false, le compilo va bloquer sur des syntaxes avec un filtre sans argument qui suit la balise
 	// si true, les arguments simples (sans truc=chose) vont degager
-	$code_contexte = argumenter_inclure($champ, $p->descr, $p->boucles, $p->id_boucle, false);
-	// Gerer ajax
-	if (isset($code_contexte['ajax'])){
-		$code_contexte['fond_ajax'] = "'fond_ajax' => '$nom'";
-		$nom = 'fond/ajax_stat';
-		unset($_contexte['ajax']);
-	}
+	$_contexte = argumenter_inclure($champ, $p->descr, $p->boucles, $p->id_boucle, false);
 
 	// Si le champ existe dans la pile, on le met dans le contexte
 	// (a priori c'est du code mort ; il servait pour #LESAUTEURS dans
 	// le cas spip_syndic_articles)
-	#$code_contexte[] = "'$nom='.".champ_sql($nom, $p);
+	#$_contexte[] = "'$nom='.".champ_sql($nom, $p);
 
 	// Reserver la cle primaire de la boucle courante si elle existe
 	if ($idb = $p->id_boucle) {
 		if ($primary = $p->boucles[$idb]->primary) {
 			$id = champ_sql($primary, $p);
-			$code_contexte[] = "'$primary='.".$id;
-			$code_contexte[] = "'id='.".$id;
+			$_contexte[] = "'$primary='.".$id;
+			$_contexte[] = "'id='.".$id;
 		}
 	}
 
 	$connect = $p->boucles[$p->id_boucle]->sql_serveur;
 	$p->code = "( ((\$recurs=(isset(\$Pile[0]['recurs'])?\$Pile[0]['recurs']:0))<5)?
 	recuperer_fond('$nom',
-		creer_contexte_de_modele(array(".join(',', $code_contexte).",'recurs='.(++\$recurs), \$GLOBALS['spip_lang'])), true, " . sql_quote($connect) . "):'')";
+		creer_contexte_de_modele(array(".join(',', $_contexte).",'recurs='.(++\$recurs), \$GLOBALS['spip_lang'])), true, " . sql_quote($connect) . "):'')";
 	$p->interdire_scripts = false; // securite assuree par le squelette
 
+	// Gerer ajax
+	if (isset($_contexte['ajax'])) {
+		$p->code = '( // {ajax}
+			strlen($t = '.$p->code.')
+			? "<div class=\'ajaxbloc env-"
+				.encoder_contexte_ajax($l)
+				."\'>\\n".$t."</div><!-- ajaxbloc -->\\n"
+			: ""
+		)';
+	}
+
 	return $p;
 }
 
diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php
index ce98eed69335ccbab9e122877245dd8ddd65500e..743334839c65982cf6e49e1b478b8eb28979146f 100644
--- a/ecrire/public/compiler.php
+++ b/ecrire/public/compiler.php
@@ -92,11 +92,7 @@ function calculer_inclure($p, $descr, &$boucles, $id_boucle) {
 	}
 
 	$_contexte = argumenter_inclure($p, $descr, $boucles, $id_boucle);
-	if (isset($_contexte['fond']) && isset($_contexte['ajax'])){
-		$_contexte['fond_ajax'] = preg_replace(",fond,","fond_ajax",$_contexte['fond'],1);
-		$_contexte['fond'] = "\'fond\' => ' . argumenter_squelette('fond/ajax') . '";
-		unset($_contexte['ajax']);
-	}
+
 	// Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
 	if ($env = (isset($_contexte['env'])|| isset($_contexte['self']))) {
 		unset($_contexte['env']);
@@ -113,13 +109,27 @@ function calculer_inclure($p, $descr, &$boucles, $id_boucle) {
 		$contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
 	}
 
-	return "\n'<".
-		"?php\n\t\$contexte_inclus = $contexte;"
-		. "\n\tinclude " .
+	$code = "\tinclude " .
 		($fichier ? "\\'$path\\'" : ('_DIR_RESTREINT . "public.php"')).
-		";" .
-		"\n?'." . "'>'";
- }
+		";";
+
+
+	// Gerer ajax
+	if (isset($_contexte['ajax'])) {
+		$code = '// {ajax}
+			echo "<div class=\\\'ajaxbloc env-"
+				.encoder_contexte_ajax($contexte_inclus)
+				."\\\'>\\n";
+			'.$code.'
+			echo "</div><!-- ajaxbloc -->\\n";
+		';
+	}
+
+	return "\n'<".
+		"?php\n\t\$contexte_inclus = $contexte;\n"
+		. $code
+		. "\n?'." . "'>'";
+}
 
 //
 // calculer_boucle() produit le corps PHP d'une boucle Spip.