diff --git a/dist/formulaires/formulaire_.html b/dist/formulaires/formulaire_.html
index 57259f6357b9b156c8adc02104f8ba8beea20986..d935a22fb8b67df19dc81ba9e26d435ce41f20f4 100644
--- a/dist/formulaires/formulaire_.html
+++ b/dist/formulaires/formulaire_.html
@@ -1,10 +1,8 @@
 <div id='#ENV{ajaxid}'>
 <INCLURE{fond=formulaires/#ENV{form}}{env}>
 </div>
-<script type='text/javascript' src='#CHEMIN{javascript/layer.js}'></script>
-<script type='text/javascript'>if (window.jQuery){
-jQuery('document').ready(function(){
-	jQuery('div#[(#ENV{ajaxid})] form').formulaire_dyn_ajax('#ENV{ajaxid}');
-});
-}
+<script type='text/javascript'>
+var ajaxform_#ENV{ajaxid} = function() {if (window.jQuery) jQuery('div#[(#ENV{ajaxid})] form',this).formulaire_dyn_ajax('#ENV{ajaxid}');}
+jQuery('document').ready(ajaxform_#ENV{ajaxid});
+onAjaxLoad(ajaxform_#ENV{ajaxid});
 </script>
\ No newline at end of file
diff --git a/dist/javascript/ajaxCallback.js b/dist/javascript/ajaxCallback.js
index 775ed3e1be795060b8dcaba4759c78eb46eb37ad..7c110c2abfd80d3015fbad82c96189c9e70beeef 100644
--- a/dist/javascript/ajaxCallback.js
+++ b/dist/javascript/ajaxCallback.js
@@ -55,3 +55,67 @@ if(!jQuery.load_handlers) {
 	};
 
 }
+
+// animation du bloc cible pour faire patienter
+jQuery.fn.animeajax = function(end) {
+	this.children().css('opacity', 0.5);
+	if (typeof ajax_image_searching != 'undefined')
+		this.prepend(ajax_image_searching);
+	return this; // don't break the chain
+}
+
+// rechargement ajax d'un formulaire dynamique implemente par formulaires/forumlaire_.html
+jQuery.fn.formulaire_dyn_ajax = function(target) {
+	this
+	.not('.noajax')
+	.prepend("<"+"input type='hidden' name='var_ajax' value='1' /"+">")
+	.ajaxForm({"target":'#'+target,
+			"beforeSubmit":
+			function(){
+				$('#'+target).animeajax().addClass('loading');
+			},
+			"success":
+			function(){
+				$('#'+target).removeClass('loading');
+			}
+	})
+	.addClass('.noajax');	// previent qu'on n'ajaxera pas deux fois le meme formulaire en cas de ajaxload
+	return this; // don't break the chain
+}
+
+// rechargement ajax d'une noisette implementee par fond/ajax.html
+// avec mise en cache des url
+var preloaded_urls = {};
+var ajaxbloc_selecteur;
+jQuery.fn.ajaxbloc = function() {
+		var blocfrag = this;
+		var ajax_env = $('input[@name=var_ajax_env]',this).eq(0).attr('value');
+		if (!ajax_env || ajax_env==undefined) return;
+		var ajax_cle = $('input[@name=var_ajax_cle]',this).eq(0).attr('value');
+		if (!ajax_cle || ajax_cle==undefined) return;
+		if (ajaxbloc_selecteur==undefined)
+			ajaxbloc_selecteur = '.pagination a,a.ajax';
+		$(ajaxbloc_selecteur,this).not('.noajax').each(function(){
+			var url = this.href.split('#');
+			url[0] += (url[0].indexOf("?")>0 ? '&':'?')+'var_ajax=1&var_ajax_env='+ajax_env+'&var_ajax_cle='+ajax_cle;
+			if ($(this).is('.preload') && !preloaded_urls[url[0]]) {
+				$.ajax({"url":url[0],"success":function(r){preloaded_urls[url[0]]=r;}});
+			}
+			$(this).click(function(){
+				$(blocfrag).animeajax().addClass('loading');
+				var on_pagination = function(contenu) {
+					preloaded_urls[url[0]] = contenu;
+					$(blocfrag).html(preloaded_urls[url[0]]);
+					$(blocfrag).removeClass('loading');
+					window.location.hash = url[1];
+				}
+				if(preloaded_urls[url[0]]) {
+					on_pagination(preloaded_urls[url[0]]);
+					triggerAjaxLoad(blocfrag);
+				} else {
+					$.ajax({"url":url[0],"success":on_pagination});
+				}
+				return false;
+			});
+		}).addClass('.noajax'); // previent qu'on ajax pas deux fois le meme lien
+};
\ No newline at end of file
diff --git a/dist/javascript/layer.js b/dist/javascript/layer.js
index bfeb23b5efb65bfe085675aa6c848bf4cdc59d48..01be340042811cf8d1bb8184fb3bce0a2a4f0b4f 100644
--- a/dist/javascript/layer.js
+++ b/dist/javascript/layer.js
@@ -269,30 +269,6 @@ function verifForm(racine) {
 	});
 }
 
-
-// animation de la cible pour faire patienter
-jQuery.fn.animeajax = function(end) {
-	this.children().css('opacity', 0.5);
-	if (typeof ajax_image_searching != 'undefined')
-		this.prepend(ajax_image_searching);
-}
-
-jQuery.fn.formulaire_dyn_ajax = function(target) {
-	this
-	.not('.noajax')
-	.prepend("<"+"input type='hidden' name='var_ajax' value='1' /"+">")
-	.ajaxForm({"target":'#'+target,
-			"success":
-			function(){
-				$('#'+target+' form').formulaire_dyn_ajax(target);
-			},
-			"beforeSubmit":
-			function(){
-				$('#'+target).animeajax();
-			}
-	});	
-}
-
 // Si Ajax est disponible, cette fonction l'utilise pour envoyer la requete.
 // Si le premier argument n'est pas une url, ce doit etre un formulaire.
 // Le deuxieme argument doit etre l'ID d'un noeud qu'on animera pendant Ajax.
diff --git a/ecrire/public/assembler.php b/ecrire/public/assembler.php
index 18661cec7749eaf401e924c447c72c3680ae44a1..14607e78c654c0344d1287212cf12e85c7b0979b 100644
--- a/ecrire/public/assembler.php
+++ b/ecrire/public/assembler.php
@@ -123,7 +123,29 @@ function public_assembler_dist($fond, $connect='') {
 			}
 		}
 	}
-
+	
+	// traiter les appels de bloc ajax
+	if (_request('var_ajax')
+	 AND ($args = _request('var_ajax_env'))
+	 AND ($cle = _request('var_ajax_cle')) ){ 
+		 if ((include_spip('inc/securiser_action'))
+		 AND ($cle == calculer_cle_action($args))) {
+			$args = unserialize(base64_decode($args));
+			if ($fond = $args['fond_ajax']){
+				include_spip('public/parametrer');
+				$contexte = calculer_contexte();
+				$contexte = array_merge($contexte,$args);
+				$page = evaluer_fond($fond,$contexte);
+				include_spip('inc/actions');
+				ajax_retour($page['texte']);
+				exit();
+			}
+		}
+		include_spip('inc/actions');
+		ajax_retour('signature ajax incorrecte');
+		exit();
+	}
+	
 	// si signature de petition, l'enregistrer avant d'afficher la page
 	// afin que celle-ci contienne la signature
 	if (isset($_GET['var_confirm'])) {