diff --git a/ecrire/inc_invalideur.php3 b/ecrire/inc_invalideur.php3
index 4a0eb285746b4de50ce5916cf817a95fd7498e60..e50a2f010d96dece5ff733ca0c60af389c23408d 100644
--- a/ecrire/inc_invalideur.php3
+++ b/ecrire/inc_invalideur.php3
@@ -73,7 +73,7 @@ function suivre_invalideur($cond) {
 	while ($row = spip_fetch_array($result))
 		$tous[] = $row['fichier'];
 
-	spip_log("suivre $cond");
+	spip_log("suivre $cond dans " . count($tous) . " caches");
 	applique_invalideur($tous);
 }
 
@@ -110,11 +110,89 @@ function applique_invalideur($depart) {
 		ecrire_meta('invalider', 'oui'); // se verifier soi-meme
 		ecrire_meta('invalider_caches', 'oui'); // supprimer les autres
 		ecrire_metas();
-		if (_DIR_RESTREINT) {
-			include_local('inc-cache.php3');
-			retire_caches();
+	}
+}
+
+
+// Utilisee pour vider le cache depuis l'espace prive
+// (ou juste les squelettes si un changement de config le necessite)
+function purger_repertoire($dir, $age='ignore', $regexp = '') {
+	$handle = @opendir($dir);
+	if (!$handle) return;
+
+	while (($fichier = @readdir($handle)) !== false) {
+		// Eviter ".", "..", ".htaccess", etc.
+		if ($fichier[0] == '.') continue;
+		if ($regexp AND !ereg($regexp, $fichier)) continue;
+		$chemin = "$dir/$fichier";
+		if (is_file($chemin))
+			@unlink($chemin);
+		else if (is_dir($chemin))
+			if ($fichier != 'CVS')
+				purger_repertoire($chemin);
+	}
+	closedir($handle);
+}
+
+function purger_cache() {
+	spip_log('vider le cache');
+	include_ecrire('inc_invalideur.php3');
+	supprime_invalideurs();
+	purger_repertoire(_DIR_CACHE, 0);
+}
+
+function purger_squelettes() {
+	spip_log('effacer les squelettes compiles');
+	purger_repertoire(_DIR_CACHE, 0, '^skel_');
+}
+
+
+function purger_cache_images() {
+	purger_repertoire(_DIR_IMG, $age='ignore', $regexp = '^cache\-');
+}
+
+
+function calculer_cache_vignettes() {
+	$handle = @opendir(_DIR_IMG);
+	if (!$handle) return;
+
+	while (($fichier = @readdir($handle)) !== false) {
+		// Eviter ".", "..", ".htaccess", etc.
+		if ($fichier[0] == '.') continue;
+		if ($regexp AND !ereg($regexp, $fichier)) continue;
+		if (is_dir(_DIR_IMG.$fichier) AND ereg("^cache-", $fichier)) {
+			$taille += calculer_taille_dossier(_DIR_IMG.$fichier);
+		}
+	}
+	closedir($handle);
+	
+	include_ecrire("inc_filtres.php3");
+	echo "<html><body>\n";
+	echo "<div style='font-family: verdana, arial, sans; font-size: 12px;'>";
+	echo "<p align='justify'>\n";
+	echo _T('ecrire:taille_cache_image', array('dir' => _DIR_IMG,
+		'taille' => "<b>".taille_en_octets($taille)."</b>"));
+	echo "</p></div></body></html>";
+
+}
+
+// Fonctions pour le cache des images (vues reduites)
+
+
+function calculer_taille_dossier ($dir) {
+	$handle = @opendir($dir);
+	if (!$handle) return;
+
+	while (($fichier = @readdir($handle)) !== false) {
+		// Eviter ".", "..", ".htaccess", etc.
+		if ($fichier[0] == '.') continue;
+		if ($regexp AND !ereg($regexp, $fichier)) continue;
+		if (is_file("$dir/$fichier")) {
+			$taille += filesize("$dir/$fichier");
 		}
 	}
+	closedir($handle);
+	return $taille;
 }
 
 ?>
diff --git a/formulaires/inc-formulaire_admin.php3 b/formulaires/inc-formulaire_admin.php3
index ce3ed48231a31875f89aa69d5d97b3c349306ffe..6b88f720f682e8634d0f75eec95e7bf8601c7fbb 100644
--- a/formulaires/inc-formulaire_admin.php3
+++ b/formulaires/inc-formulaire_admin.php3
@@ -145,7 +145,7 @@ function balise_FORMULAIRE_ADMIN_dyn($float='', $debug='') {
 				'popularite' => ceil($popularite),
 				'statistiques' => $statistiques,
 				'visites' => intval($visites),
-				'use_cache' => ($use_cache ? ' *' : ''),
+				'use_cache' => ($use_cache ? '' : ' *'),
 				'divclass' => $float,
 				'analyser' => $analyser,
 				'xhtml_error' => $GLOBALS['xhtml_error']
diff --git a/inc-cache.php3 b/inc-cache.php3
index 69218fb8b817aa2e95ab598f458a9794a0022361..dfef1253839fd5b7095203f8151f4cb710a79421 100644
--- a/inc-cache.php3
+++ b/inc-cache.php3
@@ -14,19 +14,6 @@
 //
 if (!defined("_ECRIRE_INC_VERSION")) return;
 
-
-//
-// Calcul du nom du fichier cache
-//
-
-function nettoyer_uri() {
-	$fichier_requete = $GLOBALS['REQUEST_URI'];
-	$fichier_requete = eregi_replace
-		('[?&](PHPSESSID|(var_[^=&]*))=[^&]*',
-		'', $fichier_requete);
-	return $fichier_requete;
-}
-
 //
 // Le format souhaite : "CACHE/a/bout-d-url.md5(.gz)"
 // Attention a modifier simultanement le sanity check de
@@ -117,7 +104,6 @@ function retire_caches($chemin = '') {
 		}
 	}
 
-
 	if ($n = count($suppr)) {
 		spip_log ("Retire $n caches");
 		foreach ($suppr as $cache => $ignore)
@@ -137,150 +123,118 @@ function retire_caches($chemin = '') {
 }
 
 //
-// Retourne 0 s'il faut calculer le cache, 1 si on peut l'utiliser
+// Retourne un nombre N:
+// < 0 s'il faut calculer la page sans la mettre en cache
+// = 0 si on peut utiliser un cache existant
+// > 0 s'il faut calculer la page et le mette en cache pendant N secondes
 //
-function utiliser_cache($chemin_cache, $delais) {
-	global $_SERVER;
 
-	// ne jamais calculer pour les moteurs de recherche, proxies...
-	if ($_SERVER['REQUEST_METHOD'] == 'HEAD')
-		return 1;
+function cache_valide($chemin_cache) {
+	global $delais;
 
-	//  calcul par forcage
-	if ($GLOBALS['var_mode'] &&
-		($GLOBALS['_COOKIE']['spip_session']
-		|| $GLOBALS['_COOKIE']['spip_admin']
-		|| @file_exists(_ACCESS_FILE_NAME))) # insuffisant...
-		return 0;
+	if (!isset($delais)) $delais = 3600;
 
-	// calcul par absence
-	if (!@file_exists($chemin_cache)) return 0;
+	if (!$delais) return -1;
 
-	// calcul par obsolescence
-	return ((time() - @filemtime($chemin_cache)) > $delais) ? 0 : 1;
-}
+	if (!file_exists($chemin_cache)) return $delais;
 
+	if ((time() - @filemtime($chemin_cache)) > $delais) return $delais;
 
-// Obsolete ?  Utilisee pour vider le cache depuis l'espace prive
-// (ou juste les squelettes si un changement de config le necessite)
-function purger_repertoire($dir, $age='ignore', $regexp = '') {
-	$handle = @opendir($dir);
-	if (!$handle) return;
-
-	while (($fichier = @readdir($handle)) !== false) {
-		// Eviter ".", "..", ".htaccess", etc.
-		if ($fichier[0] == '.') continue;
-		if ($regexp AND !ereg($regexp, $fichier)) continue;
-		$chemin = "$dir/$fichier";
-		if (is_file($chemin))
-			@unlink($chemin);
-		else if (is_dir($chemin))
-			if ($fichier != 'CVS')
-				purger_repertoire($chemin);
-	}
-	closedir($handle);
-}
-
-function purger_cache() {
-	spip_log('vider le cache');
-	include_ecrire('inc_invalideur.php3');
-	supprime_invalideurs();
-	purger_repertoire(_DIR_CACHE, 0);
+	return 0;
 }
 
-function purger_squelettes() {
-	spip_log('effacer les squelettes compiles');
-	purger_repertoire(_DIR_CACHE, 0, '^skel_');
-}
 
+// retourne le nom du fichier cache, 
+// et affecte le 1er param selon les specs de la fonction cache_valide
 
-// Determination du fichier cache (si besoin)
-function determiner_cache($delais, &$use_cache, &$chemin_cache) {
-	global $_SERVER;
-
-	$post = ($_SERVER['REQUEST_METHOD'] == 'POST');
-
-	// Le fichier cache est-il valide ?
-	if ($delais<>0 AND !$post)
-		$use_cache = utiliser_cache($chemin_cache, $delais);
-
-	// Sinon, tester qu'on a la connexion a la base
-	if (!$use_cache) {
-		include_local(_FILE_CONNECT);
-		if (!$GLOBALS['db_ok']) {
-			if (@file_exists($chemin_cache)) 
-				$use_cache = 1; // passer outre
-			else {
-				if (!spip_interdire_cache) {
-					spip_log("Erreur base de donnees & "
-					. "impossible utiliser $chemin_cache");
-					include_ecrire('inc_minipres.php');
-					install_debut_html(_T('info_travaux_titre'));echo _T('titre_probleme_technique');install_fin_html();
-				}
-			}
-				// continuer quand meme, ca n'ira pas loin.
+function determiner_cache(&$use_cache, $contexte,$fond) {
+	global $_SERVER, $recherche;
 
-				// mais ne plus rien signaler, ne pas mettre en cache ...
-			$GLOBALS['flag_preserver'] = true;
-			define ('spip_interdire_cache', true);
-		}
-
-		// En cas de POST (et si la connexion est ok) supprimer le cache
-		// histoire de faciliter la gestion de certaines balises dynamiques
-		else if ($post AND $chemin_cache) {
-			supprimer_fichier($chemin_cache);
-		}
+	// cas sans jamais de cache pour raison interne
 
+	if ($recherche || 
+	    ($_SERVER['REQUEST_METHOD'] == 'POST') ||
+	    ($GLOBALS['var_mode'] &&
+		($GLOBALS['_COOKIE']['spip_session']
+		 || $GLOBALS['_COOKIE']['spip_admin']
+		 || @file_exists(_ACCESS_FILE_NAME))))
+	  {
+		include_ecrire('inc_connect.php3');
+		$use_cache = -1;
+		return "";
+	  }
+
+	$chemin_cache = generer_nom_fichier_cache($contexte, $fond);
+
+	// cas sans jamais de calcul pour raison interne
+	if ($_SERVER['REQUEST_METHOD'] == 'HEAD') {
+		$use_cache = 0;
+		return $chemin_cache;
 	}
-}
-
-// Fonctions pour le cache des images (vues reduites)
 
+	// Faut-il effacer des pages invalidees (en particulier ce cache-ci) ?
+	if ($GLOBALS['meta']['invalider'] AND $GLOBALS['db_ok']) {
+		include_ecrire('inc_connect.php3');
+		include_ecrire('inc_meta.php3');
+		lire_metas();
+		retire_caches($chemin_cache);
+	}
 
-function calculer_taille_dossier ($dir) {
-	$handle = @opendir($dir);
-	if (!$handle) return;
+	$use_cache = cache_valide($chemin_cache);
 
-	while (($fichier = @readdir($handle)) !== false) {
-		// Eviter ".", "..", ".htaccess", etc.
-		if ($fichier[0] == '.') continue;
-		if ($regexp AND !ereg($regexp, $fichier)) continue;
-		if (is_file("$dir/$fichier")) {
-			$taille += filesize("$dir/$fichier");
-		}
-	}
-	closedir($handle);
-	return $taille;
-}
+	if (!$use_cache) return $chemin_cache;
 
-function calculer_cache_vignettes() {
-	$handle = @opendir(_DIR_IMG);
-	if (!$handle) return;
+	// Si pas valide mais pas de connexion a la base, le garder quand meme
 
-	while (($fichier = @readdir($handle)) !== false) {
-		// Eviter ".", "..", ".htaccess", etc.
-		if ($fichier[0] == '.') continue;
-		if ($regexp AND !ereg($regexp, $fichier)) continue;
-		if (is_dir(_DIR_IMG.$fichier) AND ereg("^cache-", $fichier)) {
-			$taille += calculer_taille_dossier(_DIR_IMG.$fichier);
+	include_ecrire('inc_connect.php3');
+	if (!$GLOBALS['db_ok']) {
+		if (file_exists($chemin_cache))
+  			$use_cache = 0 ;
+		else {
+		  // prevenir du pb (une fois, pas pour chaque inclusion)
+			if (!spip_interdire_cache) {
+				spip_log("Erreur base de donnees & "
+				. "impossible utiliser $chemin_cache");
+				include_ecrire('inc_minipres.php');
+				install_debut_html(_T('info_travaux_titre'));echo _T('titre_probleme_technique');install_fin_html();
+				// continuer quand meme, ca n'ira pas loin.
+				// mais ne plus rien signaler
+				$GLOBALS['flag_preserver'] = true;
+				define ('spip_interdire_cache', true);
+			}
 		}
 	}
-	closedir($handle);
-	
-	include_ecrire("inc_filtres.php3");
-	echo "<html><body>\n";
-	echo "<div style='font-family: verdana, arial, sans; font-size: 12px;'>";
-	echo "<p align='justify'>\n";
-	echo _T('ecrire:taille_cache_image', array('dir' => _DIR_IMG,
-		'taille' => "<b>".taille_en_octets($taille)."</b>"));
-	echo "</p></div></body></html>";
-
-}
 
-function purger_cache_images() {
-	purger_repertoire(_DIR_IMG, $age='ignore', $regexp = '^cache\-');
+	return $chemin_cache;
 }
 
+// Passage par reference juste par souci d'economie
 
+function creer_cache(&$page, $chemin_cache, $duree)
+{
+	// Entrer dans la base les invalideurs calcules par le compilateur
+	// (et supprimer les anciens)
 
+	include_ecrire('inc_invalideur.php3');
+	maj_invalideurs($chemin_cache, $page['invalideurs'], $duree);
+
+	// Enregistrer le fichier cache
+
+	$r = ecrire_fichier($chemin_cache, 
+			"<!-- "
+			. str_replace("\n", " ", serialize($page['signal']))
+			. " -->\n"
+			. $page['texte']);
+
+	// Nouveau cache : creer un invalideur 't' fixant la date
+	// d'expiration et la taille du fichier
+	if ($r) {
+			// Ici on ajoute 3600s pour eviter toute concurrence
+			// entre un invalideur et un appel public de page
+		$bedtime = time() + $duree + 3600;
+		$taille = @filesize($chemin_cache);
+		$fichier = addslashes($chemin_cache);
+		spip_query("INSERT IGNORE INTO spip_caches (fichier,id,type,taille) VALUES ('$fichier','$bedtime','t','$taille')");
+	}
+}
 ?>
diff --git a/inc-calcul.php3 b/inc-calcul.php3
index 7ecb16cdeedeb692dbde24bd60bb303a2fb1e65a..b0e693005ec927b17ff049e4ff6a9bf3788dd0c7 100644
--- a/inc-calcul.php3
+++ b/inc-calcul.php3
@@ -128,7 +128,7 @@ function charger_squelette ($squelette) {
 # definie dans inc-chercher, fichier non charge si elle est deja definie
 # (typiquement dans mes_fonctions.php3)
 
-function cherche_page ($cache, $contexte, $fond, $delais)  {
+function cherche_page ($cache, $contexte, $fond)  {
 	if (!function_exists('chercher_squelette'))
 		include_local("inc-chercher-squelette.php3");
 
@@ -166,12 +166,6 @@ function cherche_page ($cache, $contexte, $fond, $delais)  {
 		  }
 	}
 
-	// Entrer les invalideurs dans la base
-	if ($delais>0) {
-		include_ecrire('inc_invalideur.php3');
-		maj_invalideurs($cache, $page['invalideurs'], $delais);
-	}
-
 	// Retourner la structure de la page
 
 	return $page;
@@ -188,6 +182,7 @@ function cherche_page ($cache, $contexte, $fond, $delais)  {
 function calculer_contexte() {
 	global $_GET, $_POST;
 
+	$contexte = array();
 	foreach($_GET as $var => $val) {
 		if (strpos($var, 'var_') !== 0)
 			$contexte[$var] = $val;
@@ -205,7 +200,11 @@ function calculer_contexte() {
 	return $contexte;
 }
 
-function calculer_page_globale($cache, $contexte_local, $fond, $delais) {
+function calculer_page_globale($cache, $fond) {
+
+	global $lastmodified, $_SERVER;
+
+	$contexte_local = calculer_contexte();
 
 	// Gestion des URLs personnalises - sale mais historique
 	if (function_exists("recuperer_parametres_url")) {
@@ -218,7 +217,6 @@ function calculer_page_globale($cache, $contexte_local, $fond, $delais) {
 			foreach ($contexte as $var=>$val)
 				if (substr($var,0,3) == 'id_')
 					$GLOBALS[$var] = $val;
-		$contexte_local = $contexte;
 	}
 
 	// si le champ chapo commence par '=' c'est une redirection.
@@ -231,7 +229,7 @@ function calculer_page_globale($cache, $contexte_local, $fond, $delais) {
 				substr($chapo, 1)));
 				if ($url) { // sinon les navigateurs pataugent
 					$url = texte_script(str_replace('&amp;', '&', $url));
-					$page = array('texte' => "<".
+					return array('texte' => "<".
 					"?php redirige_par_entete('$url'); ?" . ">",
 					'process_ins' => 'php');
 				}
@@ -240,9 +238,8 @@ function calculer_page_globale($cache, $contexte_local, $fond, $delais) {
 	}
 
 	// Go to work !
-	if (!$page)
-		$page = cherche_page($cache, $contexte_local, $fond, $delais);
-
+	spip_timer('calculer_page');
+	$page = cherche_page($cache, $contexte_local, $fond);
 	$signal = array();
 	foreach(array('id_parent', 'id_rubrique', 'id_article', 'id_auteur',
 	'id_breve', 'id_forum', 'id_secteur', 'id_syndic', 'id_syndic_article',
@@ -252,36 +249,11 @@ function calculer_page_globale($cache, $contexte_local, $fond, $delais) {
 	}
 
 	$page['signal'] = $signal;
-
-	return $page;
-}
-
-
-
-function calculer_page($chemin_cache, $elements, $delais, $inclusion=false) {
-	global $_POST;
-
-	// Inclusion
-	if ($inclusion) {
-		$contexte_inclus = $elements['contexte'];
-		$page = cherche_page($chemin_cache,
-			$contexte_inclus, $elements['fond'], $delais);
-	}
-	else {
-		$page = calculer_page_globale($chemin_cache,
-			$elements['contexte'],
-			$elements['fond'], $delais);
-	}
-
 	$page['signal']['process_ins'] = $page['process_ins'];
-	$signal = "<!-- ".str_replace("\n", " ",
-	serialize($page['signal']))." -->\n";
-
-	// Enregistrer le fichier cache
-	if ($delais > 0 AND $GLOBALS['var_mode'] != 'debug'
-	AND !count($_POST))
-		ecrire_fichier($chemin_cache, $signal.$page['texte']);
-
+	$lastmodified = time();
+	spip_log ("calculer_page ("
+		  . spip_timer('calculer_page')."): "
+		  . $_SERVER['REQUEST_METHOD']. " $fond");
 	return $page;
 }
 ?>
diff --git a/inc-public-global.php3 b/inc-public-global.php3
index 3f9f8cb21b83bc2e97705696cd773bb9a838930b..97f2bcaac5c0d045edc03a990f841233c5df1283 100644
--- a/inc-public-global.php3
+++ b/inc-public-global.php3
@@ -14,19 +14,12 @@
 if (!defined("_ECRIRE_INC_VERSION")) return;
 
 // fonction principale declenchant tout le service
-function calcule_header_et_page ($fond, $delais) {
-	  global $auteur_session, $flag_dynamique,
-	  $flag_ob, $flag_preserver, $forcer_lang, $ignore_auth_http,
-	  $lastmodified, $recherche, $use_cache, $var_confirm, $var_mode,
-	  $var_recherche, $tableau_des_erreurs;
+// elle-meme ne fait que traiter les cas particuliers, puis passe la main.
+function calcule_header_et_page ($fond) {
+	  global $auteur_session, $forcer_lang, $ignore_auth_http,
+	  $var_confirm, $var_mode;
 	  global $_GET, $_POST, $_COOKIE, $_SERVER;
 
-	// Regler le $delais par defaut
-	if (!isset($delais))
-		$delais = 1 * 3600;
-	if ($recherche)
-		$delais = 0;
-
 	// authentification du visiteur
 	if ($_COOKIE['spip_session'] OR
 	($_SERVER['PHP_AUTH_USER']  AND !$ignore_auth_http)) {
@@ -73,86 +66,11 @@ function calcule_header_et_page ($fond, $delais) {
 		}
 	}
 
-	$tableau_des_erreurs = array();
-	$page = afficher_page_globale ($fond, $delais, $use_cache);
-
-	if (!isset($flag_preserver))
-	  $flag_preserver = ($page['process_ins'] == 'php') &&
-	  preg_match("/<[?]php\s+.*header\s*\(\s*.content\-type:/is",$page['texte']);
-
-	//
-	// Envoyer les entetes appropries
-	// a condition d'etre sur de pouvoir le faire
-	//
-	if (!headers_sent() AND !$flag_preserver) {
-
-		// Content-type: par defaut html+charset (poss surcharge par la suite)
-		header("Content-Type: text/html; charset=".$GLOBALS['meta']['charset']);
-
-		if ($flag_ob) {
-			// Si la page est vide, produire l'erreur 404
-			if (trim($page['texte']) === ''
-			AND $var_mode != 'debug') {
-				$page = message_erreur_404();	
-			}
-			// Interdire au client de cacher un login, un admin ou un recalcul
-			else if ($flag_dynamique OR $var_mode
-			OR $_COOKIE['spip_admin']) {
-#				header("Cache-Control: no-cache,must-revalidate");
-#				header("Pragma: no-cache");
-			}
-			// Pour les autres donner l'heure de modif
-			else if ($lastmodified) {
-				header("Last-Modified: ".http_gmoddate($lastmodified)." GMT");
-			}
-		}
-	}
-
-	return $page;
+	return afficher_page_globale ($fond);
 }
 
 
-//
-// Aller chercher la page dans le cache ou pas
-//
-function obtenir_page ($contexte, $chemin_cache, $delais, &$use_cache, $fond, $inclusion=false) {
-	global $lastmodified, $_SERVER;
-
-	if (!$use_cache) {
-		include_local('inc-calcul.php3');
-
-		// page globale ? calculer le contexte
-		if (!$contexte)
-			$contexte = calculer_contexte();
-
-		spip_timer('calculer_page');
-		$page = calculer_page($chemin_cache,
-			array('fond' => $fond,
-				'contexte' => $contexte),
-			$delais,
-			$inclusion);
-
-		$lastmodified = time();
-
-		// log
-		if (!$log = $chemin_cache) $log = "($fond, delais=$delais, "
-		. $_SERVER['REQUEST_METHOD'].")";
-		spip_log (($inclusion ? 'calcul inclus':'calcul').' ('
-		.spip_timer('calculer_page')."): $log");
-
-		// Nouveau cache : creer un invalideur 't' fixant la date
-		// d'expiration et la taille du fichier
-		if (@file_exists($chemin_cache)) {
-			// Ici on ajoute 3600s pour eviter toute concurrence
-			// entre un invalideur et un appel public de page
-			$bedtime = time() + $delais + 3600;
-			$taille = @filesize($chemin_cache);
-			$fichier = addslashes($chemin_cache);
-			spip_query("INSERT IGNORE INTO spip_caches (fichier,id,type,taille)
-			VALUES ('$fichier','$bedtime','t','$taille')");
-		}
-
-	} else {
+function obtenir_page_ancienne ($chemin_cache, $fond, $inclusion=false) {
 
 		//
 		// Lire le fichier cache
@@ -173,58 +91,47 @@ function obtenir_page ($contexte, $chemin_cache, $delais, &$use_cache, $fond, $i
 
 			// Remplir les globals pour les boutons d'admin
 			if (!$inclusion AND is_array($page['contexte']))
-				foreach ($page['contexte'] as $var=>$val)
+			  foreach ($page['contexte'] as $var=>$val) {
 					$GLOBALS[$var] = $val;
+			  }
 		}
-
-	}
-
 	return $page;
 }
 
+function is_preview()
+{
+	global $var_mode;
+	if ($var_mode !== 'preview') return false;
+	$statut = $GLOBALS['auteur_session']['statut'];
+	return ($statut=='0minirezo' OR
+		($GLOBALS['meta']['preview']=='1comite' AND $statut=='1comite'));
+}
 
 //
-// Appeler cette fonction pour obtenir la page principale
+// calculer la page principale et envoyer les entetes
 //
-function afficher_page_globale ($fond, $delais, &$use_cache) {
-	global $flag_preserver, $flag_dynamique, $lastmodified;
-	global $var_preview, $var_mode, $_SERVER;
-	include_local ("inc-cache.php3");
+function afficher_page_globale ($fond) {
+	global $flag_dynamique, $flag_ob, $flag_preserver,
+	  $lastmodified, $recherche, $use_cache, $var_mode;
+	global $_GET, $_POST, $_COOKIE, $_SERVER;
+
+	$f = find_in_path("inc-cache.php3");
+	if ($f && is_readable($f)) {
+        	if (!$GLOBALS['included_files'][$f]++) include($f);
+        } else include_local("inc-cache.php3");
+
+	// Peut-on utiliser un fichier cache ?
+	$chemin_cache = determiner_cache($use_cache, '', $fond);
 
 	// demande de previsualisation ?
 	// -> inc-calcul.php3 n'enregistrera pas les fichiers caches
 	// -> inc-reqsql-squel.php3 acceptera les objets non 'publie'
-	if ($var_mode == 'preview') {
-		// Verifier qu'on a le droit de previsualisation
-		$statut = $GLOBALS['auteur_session']['statut'];
-		if ($statut=='0minirezo' OR
-		($GLOBALS['meta']['preview']=='1comite' AND $statut=='1comite')) {
+	if (is_preview()) {
 			$var_mode = 'recalcul';
-			$delais = 0;
 			$var_preview = true;
 			spip_log('preview !');
 		} else
 			$var_preview = false;
-	}
-
-	// Calculer le chemin putatif du cache
-	if ($delais > 0)
-		$chemin_cache = generer_nom_fichier_cache('', $fond);
-	else
-		$chemin_cache = '';
-
-	// Faut-il effacer des pages invalidees ?
-	if ($GLOBALS['meta']['invalider']) {
-		include_ecrire('inc_connect.php3');
-		include_ecrire('inc_meta.php3');
-		lire_metas();
-		if ($GLOBALS['meta']['invalider'] AND $GLOBALS['db_ok'])
-			retire_caches($chemin_cache);
-	}
-
-
-	// Peut-on utiliser un fichier cache ?
-	determiner_cache($delais, $use_cache, $chemin_cache);
 
 	// Repondre gentiment aux requetes sympas
 	// (ici on ne tient pas compte d'une obsolence du cache ou des
@@ -249,32 +156,69 @@ function afficher_page_globale ($fond, $delais, &$use_cache) {
 	}
 	else {
 		// Obtenir la page
-		$page = obtenir_page ('', $chemin_cache, $delais, $use_cache,
-		$fond, false);
+	  if (!$use_cache)
+	    $page =  obtenir_page_ancienne ($chemin_cache, $fond, false);
+	  else {
+	    include_local('inc-calcul.php3');
+	    $page = calculer_page_globale ($chemin_cache, $fond);
+
+	    if ($chemin_cache) creer_cache($page, $chemin_cache, $use_cache);
+	  }
 	}
 
 	if ($chemin_cache) $page['cache'] = $chemin_cache;
 
+	if ($page['process_ins'] == 'php') {
+	  if (preg_match("/<[?]php\s+([^?]*[?]>)/ms",$page['texte'], $r)) {
+	    $php = $r[1];
+	    if (!isset($flag_preserver))
+	      $flag_preserver =	preg_match("/header\s*\(\s*.content\-type:/is",$php);
+	    $expire = preg_match("/header\s*\(\s*.Expire:([\s\d])*.\s*\)/is",$php, $r);
+	    if (!isset($flag_dynamique))
+	      $flag_dynamique = $expire && (intval($r[1]) === 0);
+	  }
+	}
+
 	if ($var_preview AND !$flag_preserver) {
 		include_ecrire('inc_minipres.php');
 		$page['texte'] .= afficher_bouton_preview();
 	}
+	//
+	// Envoyer les entetes appropries
+	// a condition d'etre sur de pouvoir le faire
+	//
+	if (!headers_sent() AND !$flag_preserver) {
 
-	return $page;
-}
+		// Content-type: par defaut html+charset (poss surcharge par la suite)
+		header("Content-Type: text/html; charset=".$GLOBALS['meta']['charset']);
 
+		if ($flag_ob) {
+			// Si la page est vide, produire l'erreur 404
+			if (trim($page['texte']) === ''
+			AND $var_mode != 'debug') {
+				$page = message_erreur_404();	
+			}
+			// Interdire au client de cacher un login, un admin ou un recalcul
+			else if ($flag_dynamique OR $var_mode
+			OR $_COOKIE['spip_admin']) {
+				header("Cache-Control: no-cache,must-revalidate");
+				header("Pragma: no-cache");
+			}
+			// Pour les autres donner l'heure de modif
+			else if ($lastmodified) {
+				header("Last-Modified: ".http_gmoddate($lastmodified)." GMT");
+			}
+		}
+	}
 
-function inclure_page($fond, $delais_inclus, $contexte_inclus, $cache_incluant='') {
+	return $page;
+}
 
-	$contexte_inclus['fond'] = $fond;
 
-	if ($delais_inclus > 0)
-		$chemin_cache = generer_nom_fichier_cache($contexte_inclus, $fond);
-	else
-		$chemin_cache = '';
+function inclure_page($fond, $contexte_inclus, $cache_incluant='') {
 
 	// Peut-on utiliser un fichier cache ?
-	determiner_cache($delais_inclus, $use_cache, $chemin_cache);
+	$chemin_cache = determiner_cache($use_cache, $contexte_inclus, $fond);
 
 	// Si on a inclus sans fixer le critere de lang, de deux choses l'une :
 	// - on est dans la langue du site, et pas besoin d'inclure inc_lang
@@ -286,32 +230,49 @@ function inclure_page($fond, $delais_inclus, $contexte_inclus, $cache_incluant='
 		$lang_select = true; // pour lang_dselect en sortie
 	}
 
-	$page = obtenir_page ($contexte_inclus, $chemin_cache, $delais_inclus,
-	$use_cache, $fond, true);
+	  if (!$use_cache)
+	    $page =  obtenir_page_ancienne ($chemin_cache, $fond, false);
+	  else {
+	    include_local('inc-calcul.php3');
+	    $page = cherche_page($chemin_cache, $contexte_inclus, $fond, false);
+	    $page['signal']['process_ins'] = $page['process_ins'];
+	    $lastmodified = time();
+	    if ($chemin_cache) creer_cache($page, $chemin_cache, $use_cache);
+	  }
 
-	$page['lang_select'] = $lang_select;
+	  $page['lang_select'] = $lang_select;
 
-	// Retourner le contenu...
-	return $page;
+	  return $page;
 }
 
 
 # Attention, un appel explicite a cette fonction suppose certains include
 # (voir l'exemple de spip_inscription et spip_pass)
-# $r = complexe (fond, delais, contexte) ; $echo = faut-il faire echo ou return
+# $echo = faut-il faire echo ou return
+
 function inclure_balise_dynamique($texte, $echo=true, $ligne=0) {
 	global $contexte_inclus; # provisoire : c'est pour le debuggueur
 
 	if (!is_string($texte))
 	  {
-		list($fond, $delais, $contexte_inclus) = $texte;
+	    // Revoir l'API des balises dynamiques:
+	    // leurs squelettes sont petits et sans boucle,
+	    // la gestion du delai est donc superfetatoire
+		list($fond, $delainc, $contexte_inclus) = $texte;
 
 		if ((!$contexte_inclus['lang']) AND
 		($GLOBALS['spip_lang'] != $GLOBALS['meta']['langue_site']))
 			$contexte_inclus['lang'] = $GLOBALS['spip_lang'];
 
-		// Appeler la page
-		$page = inclure_page($fond, $delais, $contexte_inclus);
+		$f = find_in_path("inc-cache.php3");
+		if ($f && is_readable($f)) {
+		  if (!$GLOBALS['included_files'][$f]++) include($f);
+		} else include_local("inc-cache.php3");
+
+		$d = $GLOBALS['delais'];
+		$GLOBALS['delais'] = $delainc;
+		$page = inclure_page($fond, $contexte_inclus);
+		$GLOBALS['delais'] = $d;
 
 		if ($page['process_ins'] == 'html') {
 				$texte = $page['texte'];
@@ -361,6 +322,17 @@ function message_erreur_404 ($erreur= "") {
 		     'process_ins' => 'php');
 }
 
+//
+// pour calcul du nom du fichier cache et autres
+//
+
+function nettoyer_uri() {
+	return eregi_replace
+		('[?&](PHPSESSID|(var_[^=&]*))=[^&]*',
+		'', 
+		 $GLOBALS['REQUEST_URI']);
+}
+
 // Renvoie le _GET ou le _POST emis par l'utilisateur
 function _request($var) {
 	global $_GET, $_POST;
diff --git a/inc-public.php3 b/inc-public.php3
index 235e24c985e182c17f21bebe8a1c8f9d3fc638b2..99a7c83abad8859bca4829404171a1bcf9217950 100644
--- a/inc-public.php3
+++ b/inc-public.php3
@@ -13,7 +13,7 @@
 
 // Distinguer une inclusion d'un appel initial
 if (defined("_INC_PUBLIC")) {
-	$page = inclure_page($fond, $delais, $contexte_inclus);
+	$page = inclure_page($fond, $contexte_inclus);
 	if ($page['process_ins'] == 'html')
 		echo $page['texte'];
 	else
@@ -29,8 +29,9 @@ if (defined("_INC_PUBLIC")) {
 	}
 	include_local('inc-public-global.php3');
 
-	// Calculer la page sans evaluer le php qu'elle contient
-	$page = calcule_header_et_page ($fond, $delais);
+	// Calculer la page en envoyant seulement les en-tetes, pas la page
+	$tableau_des_erreurs = array();
+	$page = calcule_header_et_page ($fond);
 
 	// est-on admin ?
 	if ($affiche_boutons_admin = (
diff --git a/page.php3 b/page.php3
index ab4a5e453ab3553e508670084b89f2ef08a150f9..53e08e60aed585a8ac2b2b6feb3d32d7b996b7b9 100644
--- a/page.php3
+++ b/page.php3
@@ -13,11 +13,6 @@ else if (isset($_GET["fond"]))
 else
 	$fond = '404';
 
-// Reglage du $delais
-// par defaut : la valeur existante (inclusion) ou sinon SPIP fera son reglage
-if (isset($contexte_inclus['delais']))
-	$delais = $contexte_inclus['delais'];
-
 // Securite 
 if (strstr($fond, '/')) {
 	die ("Faut pas se gener");
diff --git a/spip_cache.php3 b/spip_cache.php3
index 842227322100391663c7ee24637b554be15f587b..d4dc73b4468f6212980b644cc98fac82b7ad8f9b 100644
--- a/spip_cache.php3
+++ b/spip_cache.php3
@@ -15,7 +15,7 @@ include ("ecrire/inc_version.php3");
 
 include_ecrire("inc_meta.php3");
 include_ecrire("inc_session.php3");
-include_local("inc-cache.php3");
+include_ecrire("inc_invalideur.php3");
 
 if ($purger_cache == "oui"
 AND verifier_action_auteur("purger_cache", $hash, $id_auteur)) {
diff --git a/spip_inscription.php3 b/spip_inscription.php3
index c5c6b479bfc097e4649b2deb427b4ae348f8e785..7fa1ea313e2b5b1ad680ce9b9cb65dc985f6b798 100644
--- a/spip_inscription.php3
+++ b/spip_inscription.php3
@@ -13,7 +13,6 @@
 include ("ecrire/inc_version.php3");
 include_local(find_in_path("inc-formulaire_inscription.php3"));
 include_local("inc-public-global.php3"); 
-include_local ("inc-cache.php3");
 include_ecrire("inc_lang.php3");
 include_ecrire('inc_headers.php');
 
diff --git a/spip_pass.php3 b/spip_pass.php3
index 0cb3f70693074d1389dcabc9fce22143f78d6ab1..d55e6a3782bfb548b7345d4f9939660c31815435 100644
--- a/spip_pass.php3
+++ b/spip_pass.php3
@@ -16,7 +16,6 @@ include_ecrire("inc_session.php3"); # pour creer_uniq_id
 include_ecrire("inc_mail.php3"); # pour envoyer_mail
 include_ecrire("inc_acces.php3"); # pour generer_htpass
 include_local("inc-public-global.php3"); # pour calculer la page
-include_local ("inc-cache.php3"); # ici c'est pour tester la connexion SQL
 include_ecrire("inc_lang.php3");
 include_ecrire("inc_filtres.php3"); # pour email_valide()
 include_ecrire('inc_headers.php');