diff --git a/inc-calcul-squel.php3 b/inc-calcul-squel.php3
index 72c46abb9dad21877181f4d8518836321c8fc0a7..b6ebaec63ceb40f1ba3254dcba44c853c11da55e 100644
--- a/inc-calcul-squel.php3
+++ b/inc-calcul-squel.php3
@@ -60,18 +60,24 @@ function calculer_boucle($id_boucle, &$boucles)
 	  		strpos($return,'compteur_boucle');
 	$primary_key = $table_primary[$type_boucle];
 
-	if ($primary_key) // sinon c'est une boucle hors Spip
+# invalidation des caches si c'est une boucle SPIP, non constante de surcroit
+	if ((!$primary_key) || $constant)
+	  $invalide = '';
+	else
 	  {
-	    // invalidation des caches si la boucle n'est pas constante
-	    if ($constant)
-	      $invalide = '';
-	    else
-	      {$id_table = $table_des_tables[$type_boucle]; 
-		$boucle->select[] = "$id_table.$primary_key";
-		$invalide = '
-		$Cache["' . $primary_key . '"][$Pile[$SP]["'  .
-		  $primary_key . '"]]=1;';
-	      }
+	    $id_table = $table_des_tables[$type_boucle]; 
+	    $boucle->select[] = "$id_table.$primary_key";
+	    $invalide = '
+		$Cache["' . $primary_key . '"][' .
+	      (($primary_key != 'id_forum') ?
+	       ('$Pile[$SP]["'  .  $primary_key . '"]') :
+	       ('calcul_index_forum(' . 
+# Retournera 4 [$SP] mais force la demande du champ au serveur SQL
+		index_pile($id_boucle, 'id_article', $boucles) . ',' .
+		index_pile($id_boucle, 'id_breve', $boucles) . ',' .
+		index_pile($id_boucle, 'id_syndic', $boucles) . ',' .
+		index_pile($id_boucle, 'id_rubrique', $boucles) . ')')) .
+	      '] = 1;';
 	  }
 	$debut =
 	  ((!$flag_cpt) ? "" : "\n\t\t\$compteur_boucle++;") .
@@ -163,7 +169,6 @@ function calculer_boucle($id_boucle, &$boucles)
 	return $h0;')));
 }
 
-
 // une grosse fonction pour un petit cas
 
 function calculer_parties($partie, $mode_partie, $total_parties, $id_boucle)
@@ -300,7 +305,7 @@ function calculer_liste($tableau, $prefix, $id_boucle, $niv, &$boucles, $id_mere
 		  $exp = "";
 	      } else { $texte .= $m;}
 	      $texte .= "\n\t\tif ($t = $c) {\n" . $bm;
-	      $texte .= "\n\t\t$t = $bc . $t";
+	      if ($bc != "''") $texte .= "\n\t\t$t = $bc . $t";
 	      if (!$am) {
 		$texte .= " . $ac";
 	      } else $texte .= "; $am $t .=  $ac";
diff --git a/inc-calcul_mysql3.php b/inc-calcul_mysql3.php
index d40e20c6c5ec7e349bb5587f0f9d983414033e1f..6a598a9430fa645d2ccce923857ce29cdc2a1adb 100644
--- a/inc-calcul_mysql3.php
+++ b/inc-calcul_mysql3.php
@@ -105,6 +105,16 @@ WHERE	id_article='" . ($ida ? $ida : substr(lire_meta("forums_publics"),0,3)) .
   return array($titre, $table, $forum);
 }
 
+# Index arbitraire mais ressemblant aux md5 utilisés ailleurs
+function calcul_index_forum($id_article, $id_breve, $id_rubrique, $id_syndic)
+{
+  return 
+    'a' . ($id_article ? $id_article : '0') .
+    'b' . ($id_breve ? $id_breve : '0') .
+    'c' . ($id_rubrique ? $id_rubrique : '0') . 
+    'd' . ($id_syndic ? $id_syndic : '0');
+}
+
 # Critere {branche} : recuperer les descendants d'une rubrique
 
 function calcul_mysql_in($val, $valeurs, $tobeornotobe)
@@ -241,4 +251,6 @@ SELECT id_rubrique,lang FROM spip_articles WHERE id_article='$id'"))) {
   return '';
 }
 
+
+
 ?>
diff --git a/inc-messforum.php3 b/inc-messforum.php3
index d18d5ae85e100389ae04d70e040b79e463f67c24..9003a17737a6921a7fd12e88521daaf5e6af9037 100644
--- a/inc-messforum.php3
+++ b/inc-messforum.php3
@@ -152,16 +152,27 @@ if ($validation_finale)
 
 	if (file_exists('inc-invalideur.php3'))
 	  {
-	    include('inc-invalideur.php3');
-	    applique_invalideur(($statut == 'publie') ?
-				array($var_cache, $cache) :
-				array($var_cache));
-	      }
-	else // minimum vital 
-	  {
-	    @unlink($var_cache);
-	    if ($statut == 'publie') @unlink($cache);
+	    include_local('inc-invalideur.php3');
+	    if ($statut != 'publie')
+	      applique_invalideur(array($var_cache));
+	    else {
+	      include_local('inc-calcul_mysql3.php3');
+	      suivre_invalideur("id_forum='" .
+				calcul_index_forum($forum_id_article,
+						   $forum_id_breve,
+						   $forum_id_rubrique,
+						   $forum_id_syndic) .
+				"'",
+				'spip_id_forum_caches');
+	    }
 	  }
+	// trou de sécurité si on ne vérifie pas
+	// (code transitoire ne cas d'absence d'invalideur)
+	//	else 
+	//	  {
+	// @unlink($var_cache);
+	// if ($statut == 'publie') @unlink($cache);
+	//  }
     }
     $redirect = $retour_forum;
  }