diff --git a/ecrire/action/inscription.php b/ecrire/action/inscription.php
index 05853478cd2e321c8fca64a6c3c2c88247e00fbe..9930701bb80aea446945500f7e758048c54cb6ba 100644
--- a/ecrire/action/inscription.php
+++ b/ecrire/action/inscription.php
@@ -13,7 +13,7 @@
 if (!defined("_ECRIRE_INC_VERSION")) return;
 
 include_spip('balise/formulaire_inscription');
-include_spip('public/assembler'); 
+include_spip(_DIR_COMPIL . 'assembler'); 
 include_spip('inc/lang');
 include_spip('inc/headers');
 
diff --git a/ecrire/action/pass.php b/ecrire/action/pass.php
index c5ba18c1fbd6af3f8aa59751a33b3ccb24143c37..26d086b9c9ac4e14a7333d748fb9815399955ad2 100644
--- a/ecrire/action/pass.php
+++ b/ecrire/action/pass.php
@@ -16,7 +16,7 @@ include_spip('inc/session'); # pour creer_uniq_id
 include_spip('inc/minipres'); # charge lang et execute utiliser_lang
 include_spip('inc/mail'); # pour envoyer_mail
 include_spip('inc/acces'); # pour generer_htpass
-include_spip('public/assembler'); # pour calculer la page
+include_spip(_DIR_COMPIL . 'assembler'); # pour calculer la page
 include_spip('inc/filtres'); # pour email_valide()
 
 // Ce fichier est celui d'une balise dynamique qui s'ignore.
diff --git a/ecrire/base/db_mysql.php b/ecrire/base/db_mysql.php
index a17745feadccd338596ce82694e9d66be93cbf60..1e8409f6e20c96e2051e89c62e212dfb4d92cba1 100644
--- a/ecrire/base/db_mysql.php
+++ b/ecrire/base/db_mysql.php
@@ -42,7 +42,7 @@ function spip_mysql_trace($query, $start, $result)
 		if ($GLOBALS['mysql_debug']
 		AND (($GLOBALS['connect_statut'] == '0minirezo')
 		  OR ($GLOBALS['auteur_session']['statut'] == '0minirezo'))) {
-			include_spip('public/debug');
+			include_spip(_DIR_COMPIL . 'debug');
 			echo _T('info_erreur_requete'),
 			  " ",
 			  htmlentities($query),
@@ -92,12 +92,12 @@ function spip_mysql_select($select, $from, $where,
 	// Erreur ? C'est du debug de squelette, ou une erreur du serveur
 
 	if ($GLOBALS['var_mode'] == 'debug') {
-		include_spip('public/debug');
+		include_spip(_DIR_COMPIL . 'debug');
 		boucle_debug_resultat($id, 'requete', "SELECT " . $query);
 	}
 
 	if (!($res = @spip_query("SELECT ". $query))) {
-		include_spip('public/debug');
+		include_spip(_DIR_COMPIL . 'debug');
 		erreur_requete_boucle($query, $id, $table,
 				      spip_sql_errno(),
 				      spip_sql_error());
diff --git a/ecrire/inc/indexation.php b/ecrire/inc/indexation.php
index d66f4c2fc6b76232f31fe9889bf2de4d385091bd..f29ffc1079c0a0ed7d5ea04d161c7ec2177ece9c 100644
--- a/ecrire/inc/indexation.php
+++ b/ecrire/inc/indexation.php
@@ -15,7 +15,7 @@
 if (!defined("_ECRIRE_INC_VERSION")) return;
 include_spip('base/create');
 include_spip('base/abstract_sql');
-include_spip('public/interfaces');
+include_spip(_DIR_COMPIL . 'interfaces');
 
 // Quels formats sait-on extraire ?
 $GLOBALS['extracteur'] = array (
diff --git a/ecrire/inc/mail.php b/ecrire/inc/mail.php
index 2187638132a2ef691290da5275f89ccaa0b672d1..f65d698c50aef90e20220bf2e4b292905096fb80 100644
--- a/ecrire/inc/mail.php
+++ b/ecrire/inc/mail.php
@@ -266,7 +266,7 @@ function cron_mail($t) {
 	// $t = 0 si le fichier de lock a ete detruit
 	if (!$t) $t = time() - (3600 * 24 * $jours_neuf);
 
-	$f = charger_fonction('parametrer', 'public');
+	$f = charger_fonction('parametrer', _DIR_COMPIL);
 	$page = $f('nouveautes',
 			    array('date' => date('Y-m-d H:i:s', $t),
 				  'jours_neuf' => $jours_neuf));
diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php
index 76ad7f5e3ac58b6ed3c6ad9a127b5e717ac99e47..7bc8485c8507d96d181b888db83890398cf60911 100644
--- a/ecrire/inc/utils.php
+++ b/ecrire/inc/utils.php
@@ -48,6 +48,7 @@ function charger_fonction($nom, $dossier='exec', $continue=false) {
 	if (!preg_match(',^[\w-]+$,', $nom))
 		redirige_par_entete('./');
 
+	if (substr($dossier,-1) == '/') $dossier = substr($dossier,0,-1);
 	// Si la fonction existe deja (definie par mes_options, par exemple)
 	if (function_exists($f = $dossier.'_'.$nom)
 	OR function_exists($f = $dossier.'_'.$nom.'_dist'))
diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php
index 170db0617c86caa9b11334870a4f1439e7d67008..f2c2e7a2e417a39495395d92e3a91773ed4ca489 100644
--- a/ecrire/inc_version.php
+++ b/ecrire/inc_version.php
@@ -259,6 +259,7 @@ if (defined('_FILE_OPTIONS')) {
 # des definitions (notamment de $auteur_session)
 define('_DIR_INCLUDE', _DIR_RESTREINT);
 require_once(_DIR_INCLUDE . 'inc/utils.php');
+define('_DIR_COMPIL', 'public/');
 
 
 // chargement des plugins : doit arriver en dernier
diff --git a/ecrire/public.php b/ecrire/public.php
index e9feabc02a4e042930a8b3fb39e82a5ced7b3366..513d65ca184abb3c9486b06f4bfa70af8f9dbdd6 100644
--- a/ecrire/public.php
+++ b/ecrire/public.php
@@ -30,7 +30,7 @@ if (defined('_INC_PUBLIC')) {
 	define ('_INC_PUBLIC', 1);
 
 	//
-	// Dispatcher les appels
+	// Discriminer les appels
 	//
 
 	// Faut-il initialiser SPIP ? (oui dans le cas general)
@@ -75,7 +75,7 @@ if (defined('_INC_PUBLIC')) {
 	//
 
 	$tableau_des_erreurs = array();
-	$f = charger_fonction('assembler', 'public');
+	$f = charger_fonction('assembler', _DIR_COMPIL);
 	$page = $f($fond);
 
 	if (isset($page['status'])) {
@@ -157,8 +157,8 @@ if (defined('_INC_PUBLIC')) {
 
 	// Gestion des statistiques du site public
 	if ($GLOBALS['meta']["activer_statistiques"] != "non") {
-		include_spip ('public/stats');
-		ecrire_stats();
+		$f = charger_fonction('decompter', _DIR_COMPIL);
+		$f();
 	}
 
 	// Ecrire le noyau s'il a change ;
diff --git a/ecrire/public/assembler.php b/ecrire/public/assembler.php
index 2b7b3c19fd4147269914c7d9c8e1293afaf6af98..e42ac557f8096478b21836caa22ff34691234f49 100644
--- a/ecrire/public/assembler.php
+++ b/ecrire/public/assembler.php
@@ -76,7 +76,7 @@ function assembler_page ($fond) {
 		$use_cache, $var_mode, $var_preview;
 
 	// Cette fonction est utilisee deux fois
-	$fcache = charger_fonction('cacher', 'public');
+	$fcache = charger_fonction('cacher', _DIR_COMPIL);
 	// Garnir ces quatre parametres avec les infos sur le cache
 	$fcache(NULL, $use_cache, $chemin_cache, $page, $lastmodified);
 
@@ -120,7 +120,7 @@ function assembler_page ($fond) {
 			foreach ($page['contexte'] as $var=>$val)
 				$GLOBALS[$var] = $val;
 		} else {
-			$f = charger_fonction('parametrer', 'public');
+			$f = charger_fonction('parametrer', _DIR_COMPIL);
 			$page = $f($fond, '', $chemin_cache);
 			if ($chemin_cache)
 				$fcache(NULL, $use_cache, $chemin_cache, $page, $lastmodified);
@@ -191,7 +191,7 @@ function auto_expire($page)
 function inclure_page($fond, $contexte_inclus, $cache_incluant='') {
 	global $lastmodified;
 
-	$fcache = charger_fonction('cacher', 'public');
+	$fcache = charger_fonction('cacher', _DIR_COMPIL);
 	// Garnir ces quatre parametres avec les infos sur le cache
 	$fcache($contexte_inclus, $use_cache, $chemin_cache, $page, $lastinclude);
 
@@ -216,7 +216,7 @@ function inclure_page($fond, $contexte_inclus, $cache_incluant='') {
 	if (!$use_cache) {
 		$lastmodified = max($lastmodified, $lastinclude);
 	} else {
-		$f = charger_fonction('parametrer', 'public');
+		$f = charger_fonction('parametrer', _DIR_COMPIL);
 		$page = $f($fond, $contexte_inclus, $chemin_cache);
 		$lastmodified = time();
 		if ($chemin_cache) 
@@ -310,7 +310,7 @@ function f_tidy ($texte) {
 // Inserer au besoin les boutons admins
 function f_admin ($texte) {
 	if ($GLOBALS['affiche_boutons_admin']) {
-		include_spip('public/admin');
+		include_spip(_DIR_COMPIL . 'admin');
 		$texte = affiche_boutons_admin($texte);
 	}
 
diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php
index f44268c7af0f56dbaa84f09ffc45e191cd8355e6..14dcf02cea56422fbc3f606d93784cb3d0ae4554 100644
--- a/ecrire/public/compiler.php
+++ b/ecrire/public/compiler.php
@@ -22,19 +22,19 @@ define('CODE_MONOTONE', "^(\n//[^\n]*\n)?\(?'([^'])*'\)?$");
 
 // Definition de la structure $p, et fonctions de recherche et de reservation
 // dans l'arborescence des boucles
-include_spip('public/references');
+include_spip(_DIR_COMPIL . 'references');
 
 // definition des boucles
-include_spip('public/boucles');
+include_spip(_DIR_COMPIL . 'boucles');
 
 // definition des criteres
-include_spip('public/criteres');
+include_spip(_DIR_COMPIL . 'criteres');
 
 // definition des balises
-include_spip('public/balises');
+include_spip(_DIR_COMPIL . 'balises');
 
 // definition de l'API
-include_spip('public/interfaces');
+include_spip(_DIR_COMPIL . 'interfaces');
 
 # definition des tables
 include_spip('base/serial');
@@ -620,7 +620,7 @@ function public_compiler_dist($squelette, $nom, $gram, $sourcefile) {
 	$boucles = array();
 	spip_timer('calcul_skel');
 
-	$f = charger_fonction('phraser_'.$gram, 'public');
+	$f = charger_fonction('phraser_'.$gram, _DIR_COMPIL);
 
 	$racine = $f($squelette, '',$boucles, $nom);
 
diff --git a/ecrire/public/composer.php b/ecrire/public/composer.php
index 6e9b0b5f74f460b6efbaa8897f119b1daeae2a57..cc989ec369e48d6950476fdb6f480a049f91f36a 100644
--- a/ecrire/public/composer.php
+++ b/ecrire/public/composer.php
@@ -19,7 +19,7 @@ include_spip('inc/documents');
 include_spip('inc/forum');
 include_spip('inc/distant');
 include_spip('inc/rubriques'); # pour calcul_branche (cf critere branche)
-include_spip('public/debug'); # toujours prevoir le pire
+include_spip(_DIR_COMPIL . 'debug'); # toujours prevoir le pire
 
 # Charge et retourne un composeur, i.e. la fonction principale d'un squelette
 # ou '' s'il est inconnu. Le compile au besoin
@@ -55,7 +55,7 @@ function public_composer_dist($squelette, $mime_type, $gram, $sourcefile) {
 
 	// charger le source, si possible, et compiler 
 	if (lire_fichier ($sourcefile, $skel)) {
-		$f = charger_fonction('compiler', 'public');
+		$f = charger_fonction('compiler', _DIR_COMPIL);
 		$skel_code = $f($skel, $nom, $gram, $sourcefile);
 	}
 
diff --git a/ecrire/public/stats.php b/ecrire/public/decompter.php
similarity index 100%
rename from ecrire/public/stats.php
rename to ecrire/public/decompter.php
diff --git a/ecrire/public/parametrer.php b/ecrire/public/parametrer.php
index 195729d9a6f11d4d863c1693e1b7503854f20865..8c91bb3f7a5b96275a97c7582787f3537dd3c829 100644
--- a/ecrire/public/parametrer.php
+++ b/ecrire/public/parametrer.php
@@ -316,7 +316,7 @@ function public_parametrer_dist($fond, $local='', $cache='')  {
 	if (!$GLOBALS['forcer_lang'])
 		lang_select($lang);
 
-	$f = charger_fonction('styliser', 'public');
+	$f = charger_fonction('styliser', _DIR_COMPIL);
 	list($skel,$mime_type, $gram, $sourcefile) = $f($fond, $id_rubrique_fond,$GLOBALS['spip_lang']);
 
 	// Charger le squelette en specifiant les langages cibles et source
@@ -324,7 +324,7 @@ function public_parametrer_dist($fond, $local='', $cache='')  {
 	// et appliquer sa fonction principale sur le contexte.
 	// Passer le nom du cache pour produire sa destruction automatique
 
-	$f = charger_fonction('composer', 'public');
+	$f = charger_fonction('composer', _DIR_COMPIL);
 
 	if ($fonc = $f($skel, $mime_type, $gram, $sourcefile)){
 		spip_timer('calcul page');
@@ -338,7 +338,7 @@ function public_parametrer_dist($fond, $local='', $cache='')  {
 	} else 	$page = array();
 
 	if ($GLOBALS['var_mode'] == 'debug') {
-		include_spip('public/debug');
+		include_spip(_DIR_COMPIL . 'debug');
 		debug_dumpfile ($page['texte'], $fonc, 'resultat');
 	}
 	$page['signal'] = signaler_squelette($local);
diff --git a/ecrire/public/styliser.php b/ecrire/public/styliser.php
index 76868be6e2f21fdddd10360b997dd8fd4d8d5354..416f015cd01c8e8bb41353a25f2d56cb032f92ab 100644
--- a/ecrire/public/styliser.php
+++ b/ecrire/public/styliser.php
@@ -22,7 +22,7 @@ function public_styliser_dist($fond, $id_rubrique, $lang) {
 	$ext = 'html';
 	// Accrocher un squelette de base dans le chemin, sinon erreur
 	if (!$base = find_in_path("$fond.$ext")) {
-		include_spip('public/debug');
+		include_spip(_DIR_COMPIL . 'debug');
 		erreur_squelette(_T('info_erreur_squelette2',
 			array('fichier'=>$fond)),
 			$GLOBALS['dossier_squelettes']);