diff --git a/ecrire/public/balises.php b/ecrire/public/balises.php
index 8d6673d0e72d49c882c9b111245e4e8616be0a19..3eaad85bf5f4196dc6f933ae712869db9c4e0969 100644
--- a/ecrire/public/balises.php
+++ b/ecrire/public/balises.php
@@ -169,146 +169,83 @@ function balise_URL_SITE_SPIP_dist($p) {
 	return $p;
 }
 
-
 // http://doc.spip.org/@balise_URL_ARTICLE_dist
 function balise_URL_ARTICLE_dist($p) {
-	if ($p->boucles[$p->id_boucle]->sql_serveur) {
-		$p->code = 'generer_url_public("404")';
-		return $p;
-	}
-
-	$_type = $p->type_requete;
 
 	// Cas particulier des boucles (SYNDIC_ARTICLES)
-	if ($_type == 'syndic_articles') {
+	if ($p->type_requete == 'syndic_articles') {
 		$p->code = champ_sql('url', $p);
-	}
+	} else  $p->code = generer_generer_url('article', $p);
 
-	// Cas general : chercher un id_article dans la pile
-	else {
-		$_id_article = interprete_argument_balise(1,$p);
-		if (!$_id_article)
-			$_id_article = champ_sql('id_article', $p);
-		$p->code = "generer_url_article($_id_article)";
-	}
+	$p->interdire_scripts = false;
+	return $p;
+}
 
+// http://doc.spip.org/@balise_URL_AUTEUR_dist
+function balise_URL_AUTEUR_dist($p) {
+
+	$p->code = generer_generer_url('auteur', $p);
 	$p->interdire_scripts = false;
 	return $p;
 }
 
 // http://doc.spip.org/@balise_URL_RUBRIQUE_dist
 function balise_URL_RUBRIQUE_dist($p) {
-	if ($p->boucles[$p->id_boucle]->sql_serveur) {
-		$p->code = 'generer_url_public("404")';
-		return $p;
-	}
-
-	$_id_rubrique = interprete_argument_balise(1,$p);
-	if (!$_id_rubrique)
-		$_id_rubrique = champ_sql('id_rubrique',$p);
-	$p->code = "generer_url_rubrique($_id_rubrique)" ;
 
+	$p->code = generer_generer_url('rubrique', $p);
 	$p->interdire_scripts = false;
 	return $p;
 }
 
 // http://doc.spip.org/@balise_URL_BREVE_dist
 function balise_URL_BREVE_dist($p) {
-	if ($p->boucles[$p->id_boucle]->sql_serveur) {
-		$p->code = 'generer_url_public("404")';
-		return $p;
-	}
 
-	$_id_breve = interprete_argument_balise(1,$p);
-	if (!$_id_breve)
-		$_id_breve = champ_sql('id_breve',$p);
-	$p->code = "generer_url_breve($_id_breve)";
-	
+	$p->code = generer_generer_url('breve', $p);
 	$p->interdire_scripts = false;
 	return $p;
 }
 
 // http://doc.spip.org/@balise_URL_MOT_dist
 function balise_URL_MOT_dist($p) {
-	if ($p->boucles[$p->id_boucle]->sql_serveur) {
-		$p->code = 'generer_url_public("404")';
-		return $p;
-	}
-
-	$_id_mot = interprete_argument_balise(1,$p);
-	if (!$_id_mot)
-		$_id_mot = champ_sql('id_mot',$p);
-	$p->code = "generer_url_mot($_id_mot)";
 
+	$p->code = generer_generer_url('mot', $p);
 	$p->interdire_scripts = false;
 	return $p;
 }
 
-// #NOM_SITE affiche le nom du site, ou sinon l'URL ou le titre de l'objet
-// http://doc.spip.org/@balise_NOM_SITE_dist
-function balise_NOM_SITE_dist($p) {
-	if (!$p->etoile) {
-		$p->code = "construire_titre_lien(" .
-		champ_sql('nom_site',$p) ."," .
-		champ_sql('url_site',$p) . 
-		")";
-	} else
-		$p->code = champ_sql('nom_site',$p);
-
-	$p->interdire_scripts = true;
-	return $p;
-}
-
-# URL_SITE est une donnee "brute" tiree de la base de donnees
-# URL_SYNDIC correspond a l'adresse de son backend.
-# Il n'existe pas de balise pour afficher generer_url_site($id_syndic),
-# a part [(#ID_SYNDIC|generer_url_site)]
-
 // http://doc.spip.org/@balise_URL_FORUM_dist
 function balise_URL_FORUM_dist($p) {
-	if ($p->boucles[$p->id_boucle]->sql_serveur) {
-		$p->code = 'generer_url_public("404")';
-		return $p;
-	}
-
-	$_id_forum = interprete_argument_balise(1,$p);
-	if (!$_id_forum)
-		$_id_forum = champ_sql('id_forum',$p);
-	$p->code = "generer_url_forum($_id_forum)";
 
+	$p->code = generer_generer_url('forum', $p);
 	$p->interdire_scripts = false;
 	return $p;
 }
 
 // http://doc.spip.org/@balise_URL_DOCUMENT_dist
 function balise_URL_DOCUMENT_dist($p) {
-	if ($p->boucles[$p->id_boucle]->sql_serveur) {
-		$p->code = 'generer_url_public("404")';
-		return $p;
-	}
-
-	$_id_document = interprete_argument_balise(1,$p);
-	if (!$_id_document)
-		$_id_document = champ_sql('id_document',$p);
-	$p->code = "generer_url_document($_id_document)";
 
+	$p->code = generer_generer_url('document', $p);
 	$p->interdire_scripts = false;
 	return $p;
 }
 
-// http://doc.spip.org/@balise_URL_AUTEUR_dist
-function balise_URL_AUTEUR_dist($p) {
-	if ($p->boucles[$p->id_boucle]->sql_serveur) {
-		$p->code = 'generer_url_public("404")';
-		return $p;
-	}
+# URL_SITE est une donnee "brute" tiree de la base de donnees
+# URL_SYNDIC correspond a l'adresse de son backend.
+# Il n'existe pas de balise pour afficher generer_url_site($id_syndic),
+# a part [(#ID_SYNDIC|generer_url_site)]
 
-	$_id_auteur = interprete_argument_balise(1,$p);
-	if (!$_id_auteur)
-		$_id_auteur = champ_sql('id_auteur',$p);
-	$p->code = "generer_url_auteur($_id_auteur)";
+// #NOM_SITE affiche le nom du site, ou sinon l'URL ou le titre de l'objet
+// http://doc.spip.org/@balise_NOM_SITE_dist
+function balise_NOM_SITE_dist($p) {
+	if (!$p->etoile) {
+		$p->code = "construire_titre_lien(" .
+		champ_sql('nom_site',$p) ."," .
+		champ_sql('url_site',$p) . 
+		")";
+	} else
+		$p->code = champ_sql('nom_site',$p);
 
-	$p->interdire_scripts = false;
+	$p->interdire_scripts = true;
 	return $p;
 }
 
diff --git a/ecrire/public/parametrer.php b/ecrire/public/parametrer.php
index 35b4562afe0b7eba3bee2a31290beffb39119ef5..57a12d931df443dccca6fdd7255bee9584b99eea 100644
--- a/ecrire/public/parametrer.php
+++ b/ecrire/public/parametrer.php
@@ -185,6 +185,17 @@ function quete_rubrique($id_article) {
 	return $id_rubrique['id_rubrique'];
 }
 
+# retourne le fichier d'un document
+
+// http://doc.spip.org/@quete_rubrique
+function quete_fichier($id_document, $serveur) {
+	$r = sql_fetsel(array('fichier'),
+			array('spip_documents'),
+			array("id_document=" . intval($id_document)),
+			'',array(),'','','', '', '', $serveur);
+	return $r['fichier'];
+}
+
 // http://doc.spip.org/@quete_petitions
 function quete_petitions($id_article, $table, $id_boucle, $serveur, &$cache) {
 	$retour = sql_fetsel(
@@ -218,6 +229,43 @@ function quete_accepter_forum($id_article) {
 	return $cache[$id_article];
 }
 
+// recuperer une meta sur un site distant (en local il y a plus simple)
+function quete_meta($nom, $serveur) {
+	$r = sql_fetsel("valeur", "spip_meta", "nom=" . _q($nom), '','','','','','','',$serveur);
+	return $r['valeur'];
+}
+
+// Produit les appels aux fonctions generer_url parametrees par $type_urls
+// demandees par les balise #URL_xxx
+// Si ces balises sont rencontrees dans une boucle de base distante
+// on produit le generer_url std faute de connaitre le $type_urls distant
+// et sous reserve que cette base distante est geree par SPIP.
+// Autrement cette balise est vu comme un champ normal dans cette base.
+
+function generer_generer_url($type, $p)
+{
+	$_id = interprete_argument_balise(1,$p);
+
+	if (!$_id) $_id = champ_sql('id_' . $type, $p);
+
+	if ($s = $p->id_boucle) $s = $p->boucles[$s]->sql_serveur;
+
+	if (!$s)
+		return "generer_url_$type($_id)";
+	elseif ($GLOBALS['type_des_serveurs'][$s] != 'spip')
+		return calculer_champ($p);
+	else {
+		$u = "quete_meta('adresse_site', '$s')";
+		if ($type != 'document')
+			return "$u . '?page=$type&id_$type=' . " . $_id;
+		else {
+			$f = "$_id . '&file=' . quete_fichier($_id,'$s')";
+			return "$u . '?action=acceder_document&arg=' .$f";
+		}
+	}
+}
+
+
 # Determine les parametres d'URL (hors r��criture) et consorts
 # En deduit un contexte disant si la page est une redirection ou 
 # exige un squelette deductible de $fond et du contexte linguistique.