Introduction▲
Dans une précédente note technique, nous avons présenté la notion de syndication en particulier sous la forme de flux RSS. Nous avons également réalisé un lecteur 4D de flux RSS. Pour compléter, cette présentation, nous allons dans cette nouvelle note nous intéresser à l’aspect serveur de flux RSS depuis une application 4D.
Élaboration de l’exemple▲
Conception technique▲
Un flux RSS est une structure XML respectant un modèle particulier.
Pour générer un flux, nous devons donc :
· choisir un moyen de générer du XML ;
· choisir le modèle de flux que nous allons respecter.
Pour les différents moyens de générer des structures XML depuis une application 4D, nous vous renvoyons aux notes techniques parues sur ce sujet :
· Générer du XML avec 4D 2004 - 1re partie (réf 4D-200409-27-FR)
· Générer du XML avec 4D 2004 - 2e partie (réf 4D-200410-28-FR)
Comme le flux RSS doit être servi par le serveur http interne de 4D, nous effectuons le choix de travailler avec des modèles semi-dynamiques. Cette approche évite de coder la génération de l’arbre XML, mais présente l’inconvénient de se limiter à un codage de caractères en ISO-8859-1 (ISO-Latin-1).
Nous avons vu dans la note précédente que deux branches de format RSS coexistaient. La version 2.0 présentant l’avantage d’une plus grande simplicité, nous l’avons retenue pour cet exemple.
Choix des informations à publier▲
Via le mécanisme de l’élément <link> pour une ressource en ligne ou de l’élément <enclosure> pour le contenu multimédia, nous sommes en mesure de publier tout type d’information géré par une base 4D. Comme il s’agit d’une note technique, nous avons simplement choisi de publier un flux RSS listant les dernières notes techniques parues.
Pour cela, nous avons complété l’application 4DKnowledge_184 en 4D version 2004.
Structure de données▲
Voici un extrait de la structure de données de la base avec les tables qui vont nous concerner :
La table [TECHNOTES] contient les métadonnées sur les notes techniques, nous retiendrons les champs :
· [TECHNOTES]Title : le titre de la note ;
· [TECHNOTES]Ref4D : la référence de la note ;
· [TECHNOTES]Summary : le résumé de la note ;
· [TECHNOTES]ID : l’identifiant unique.
La publication s’effectuera sur les 20 dernières notes techniques parues.
Le contenu de la note s’obtient par relation vers la table [ZONESWRITE]. Plusieurs enregistrements peuvent correspondre à un enregistrement [TECHNOTES]. Pour simplifier, nous ne considérerons que le premier enregistrement lié. La note technique au format 4D Write est contenue dans le champ [ZONESWRITE]ZoneNT. 4D Write nous permettra une conversion aisée en HTML.
Pour récupérer les auteurs (plusieurs auteurs peuvent avoir collaboré sur une note), l’application utilise la méthode BuildAuthorsNames et concatène les noms d’auteurs dans la variable interprocess <>NomAuteurs. Il nous suffit de recopier cette méthode en utilisant cette fois une variable process pour obtenir notre liste d’auteurs et garantir un fonctionnement multiprocess correct.
Modèle de flux XML semi-dynamique▲
La première étape de notre publication consiste à créer un modèle semi-dynamique qui, traité par le serveur http, générera automatiquement notre flux XML-RSS.
Voici le code source de ce modèle :
<?xml version="1.0" encoding="ISO-8859-1"?>
<rss
version
=
"2.0"
>
<channel>
<title>
4D 2004 exemple de publication RSS</title>
<link>
http://<!--#4DVAR rss_vt_local_IP-->
/4DAction/rss_Home</link>
<language>
fr</language>
<managingEditor>
<!--#4dvar rss_vt_author-->
</managingEditor>
<description>
Exemple de publication RSS avec 4D 2004</description>
<pubDate>
<!--#4dvar rss_vt_pubDate-->
</pubDate>
<generator>
4eme Dimension 2004</generator>
<docs>
http://blogs.law.harvard.edu/tech/rss</docs>
<image>
<title>
4D 2004 exemple de publication RSS</title>
<link>
http://<!--#4DVAR rss_vt_local_IP-->
/4DAction/RSS_Home</link>
<url>
http://<!--#4DVAR rss_vt_local_IP-->
/images/4dlogo.gif</url>
</image>
<!--#4dloop [TECHNOTES]-->
<!--#4dscript/rss_BuildAuthorsNames/-->
<item>
<pubDate>
<!--#4dscript/rss_getPubDate/-->
</pubDate>
<author>
<!--#4dvar rss_vt_Author-->
</author>
<title>
<!--#4dvar [TECHNOTES]Title-->
/<!--#4dvar [TECHNOTES]Ref4D-->
/<!--#4dvar rss_vt_NomAuteurs-->
</title>
<description>
<!--#4dvar [TECHNOTES]Summary-->
</description>
<link>
http://<!--#4DVAR rss_vt_local_IP-->
/4DAction/rss_nt_html/id=<!--#4dvar [TECHNOTES]ID-->
</link>
<guid>
http://<!--#4DVAR rss_vt_local_IP-->
/4DAction/rss_nt_html/id=<!--#4dvar [TECHNOTES]ID-->
</guid>
</item>
<!--#4dendloop-->
</channel>
</rss>
Pour en comprendre le fonctionnement, il faut distinguer deux parties :
1) les métadonnées sur le <channel>, constituées par tous les premiers enfants de <channel> jusqu’à </image> ;
2) la liste des items publiés, un item par note technique. Notre modèle décrit seulement un item encadré par une boucle 4D :
<!--#4dloop [TECHNOTES]--> Structure d’un item <!--#4dendloop-->
Le code compris entre ces deux balises sera répété autant de fois que nous aurons d’enregistrements dans notre sélection [TECHNOTES].
Pour connaître la signification des différents champs de channel, se reporter au lien déjà mentionné dans la note précédente :
http://www.stervinou.com/projets/rss/#sampleFiles.
Notons simplement que nous devrons gérer l’appel décrit dans <link> afin d’afficher le site Web HTML correspondant au <channel> :
<link>http://<!--#4DVAR rss_vt_local_IP-->/4DAction/rss_Home</link>
La variable rss_vt_local_IP contient l’adresse IP du serveur de flux RSS.
Dans la structure <item>, nous ne pouvons écrire le nom des auteurs dans l’enfant <author>. En effet, ce champ doit contenir une adresse email. C’est pourquoi nous y insérons la variable rss_vt_Author qui contient l’adresse email de la personne responsable des notes techniques chez 4D.
Utilisation de l’élément <enclosure>▲
Rappelons que l’élément <item> peut également comprendre un enfant facultatif <enclosure>.
Voici ce que nous indique la page citée plus haut :
<enclosure> est un sous-élément facultatif de <item>.
Il possède trois attributs obligatoires :
· url dit où l’enclosure est située,
· length dit quelle taille elle fait en octets,
· type dit quel est son type, un standard type MIME.
L’url doit être une url http.
<enclosure url=« http://www.scripting.com/mp3s/weatherReportSuite.mp3 » length=« 12216320 » type=« audio/mpeg » />
L’exemple indiqué permet de retrouver une ressource mp3, mais il est possible de pointer sur un autre type de fichier, par exemple un BLOB exporté depuis 4D. Par ce mécanisme, il serait possible de proposer au téléchargement les bases exemples accompagnant la note technique. Une autre possibilité serait de proposer une version PDF de la note.
Méthode appelée : rss_serverPublish▲
Le lecteur appelle la méthode rss_serverPublish grâce à la balise 4DACTION.
Voici son code source :
` Methode : rss_serverPublish
` Description :
` routine appelée par un lecteur de flux RSS, renvoi le flux RSS
`127.0.0.1/4dAction/rss_ServerPublish/news.rss
`
` Parametres :
` $1:TEXTE:parametre
`
` Version : 1
` Appel : rss_serverPublish(parametre)
` ----------------------------------------------------
C_TEXTE($1)
Si ($1="/news.rss")
`on renvoie les 20 dernières NT
TOUT SELECTIONNER([TECHNOTES])
TRIER([TECHNOTES];[TECHNOTES]Date;<)
REDUIRE SELECTION([TECHNOTES];20)
Si (Indefinie(<>rss_vt_locaIP))
rss_surOuverture
Sinon
Si (<>rss_vt_locaIP="")
rss_surOuverture
Fin de si
Fin de si
C_TEXTE(rss_vt_local_IP)
rss_vt_local_IP:=<>rss_vt_locaIP
`date de publication
C_TEXTE(rss_vt_pubDate)
C_HEURE($tiTime)
$tiTime:=Heure courante
C_DATE($sgmtDate)
C_HEURE($sgmtTime)
rss_vt_pubDate:=AP Timestamp to GMT (Date du jour;$tiTime;$sgmtDate;$sgmtTime)
C_TEXTE(rss_vt_author)
rss_vt_author:="martine.mourier@4D.fr"
Si (Faux)
ENVOYER FICHIER HTML("rss_nt.xml")
Sinon `on passe par un BLOB pour pouvoir effectuer des traitements supplémentaires
C_TEXTE($_vt_rssModel)
$_vt_rssModel:=rss_get_DossierWeb +"rss_nt.xml"
C_BLOB($_vx_blobRSS)
DOCUMENT VERS BLOB($_vt_rssModel;$_vx_blobRSS)
TRAITER BALISES HTML($_vx_blobRSS;$_vx_blobRSS)
`les résumés contiennent des caractères qui posent problème, on les remplace avant l’envoi
C_BLOB($_vx_blobReplace)
TEXTE VERS BLOB("'";$_vx_blobReplace;Texte sans longueur )
ZBLOB_ReplaceTag (->$_vx_blobRSS;"’";->$_vx_blobReplace)
ENVOYER BLOB HTML($_vx_blobRSS;"text/xml")
Fin de si
Fin de si
La routine rss_surOuverture se charge de différentes initialisations, dont l’adresse IP du serveur.
Dans une première version, nous avions tenté d’envoyer simplement le modèle xml : ENVOYER FICHIER HTML(« rss_nt.xml »), ce qui a pour effet de déclencher le traitement par 4D des balises HTML. Mais cela se traduisait par un échec lors de la tentative de validation du flux, car les textes contenaient des caractères invalides pour le codage considéré. Il nous a donc fallu passer par un BLOB intermédiaire, effectuer le traitement des balises par la commande TRAITER BALISES HTML, effectuer les remplacements dans le BLOB, puis envoyer le BLOB final.
Résultat▲
Voici un extrait du flux XML résultant :
Affichage dans un lecteur de flux▲
Vienna est un agrégateur de syndication compatible RSS et Atom.
Il s’agit d’un projet open source pour MacOSX, vous pouvez le trouver ici :
http://www.opencommunity.co.uk/vienna2.php
Validation du flux▲
Nous avions vu qu’il existait des sites de validation de flux RSS, nous avons donc soumis le résultat produit à http://validator.w3.org/ :
Lien vers la note complète▲
La balise <link>, enfant d’item, contient un lien qui doit déclencher l’affichage de la note technique correspondante sous forme d’une page HTML :
<link>http://192.168.1.10/4DAction/rss_nt_html/id=334</link>
Pour ce faire nous appelons la méthode rss_nt_html en lui passant en paramètre l’id de note.
` Methode : rss_nt_html
` Description :
` envoie la note technique sous forme HTML
`
` Parametres :
` $1:TEXTE:/id=id NT
`
` Version : 1
` Appel : rss_nt_html("/id=id NT")
` ----------------------------------------------------
C_TEXTE($1) `rss_nt_html/id=329
Si ($1#"/images@") `demande de la page elle-même
C_ENTIER LONG($_vl_idNT)
$_vl_idNT:=Num(Sous chaine($1;Position("id=";$1)+Longueur("id=")))
LECTURE SEULEMENT([ZONESWRITE])
CHERCHER([ZONESWRITE];[ZONESWRITE]Technote_ID=$_vl_idNT)
Si (Enregistrements trouves([ZONESWRITE])>0)
Si (Vrai) `l’enregistrement du BLOB write au format HTML
C_TEXTE($_vt_htmlPath)
$_vt_htmlPath:=Dossier 4D+"NT"+FILE_PlateformSeparator
Si (Tester chemin acces($_vt_htmlPath)#Est un répertoire )
CREER DOSSIER($_vt_htmlPath)
Fin de si
$_vt_htmlPath:=$_vt_htmlPath+"nt"+Chaine($_vl_idNT)+"_"
+Chaine(Nombre de millisecondes)+".html"
C_ENTIER LONG($_vl_refZone)
$_vl_refZone:=WR Hors ecran
WR BLOB VERS ZONE ($_vl_refZone;[ZONESWRITE]ZoneNT)
WR SAUVER DOCUMENT ($_vl_refZone;$_vt_htmlPath;"HTML")
WR DETRUIRE HORS ECRAN ($_vl_refZone)
Fin de si
ENVOYER FICHIER HTML($_vt_htmlPath)
Fin de si
Sinon `demande d’une image de la page
`http://192.168.1.10/4DAction/rss_nt_html/images/nt328_354859749001.jpg
`envoi d’une image de lpage HTML
C_BLOB($_vx_blob)
C_TEXTE($_vt_htmlPath)
$_vt_htmlPath:=Dossier 4D+"NT"+FILE_PlateformSeparator +
Sous chaine($1;Position("/images/";$1)+1)
$_vt_htmlPath:=Remplacer chaine($_vt_htmlPath;"/";FILE_PlateformSeparator )
DOCUMENT VERS BLOB($_vt_htmlPath;$_vx_blob)
ENVOYER BLOB HTML($_vx_blob;"image/jpeg")
Fin de si
Cette méthode comprend deux cas.
Dans le premier, nous recherchons le premier enregistrement [ZONESWRITE] correspondant à la note technique souhaitée, puis nous effectuons la transformation en HTML. La page correspondante est stockée dans un sous-dossier du dossier 4D :
$_vt_htmlPath:=Dossier 4D+"NT"+FILE_PlateformSeparator
Ce dossier sera supprimé par un appel à rss_surFermeture lors de la fermeture de l’application.
Lors de la conversion en HTML, 4D Write crée un sous-dossier Images dans lequel il enregistre au format JPEG les images présentes dans la note technique. Ces images sont référencées dans le document HTML sous forme de liens :
http://192.168.1.10/4DAction/rss_nt_html/images/nt328_354859749001.jpg
Le traitement d’un appel de ce type constitue le deuxième cas de notre méthode afin de charger l’image correspondante dans un BLOB, puis de la renvoyer vers le client HTTP.
Nettoyage lors de la fermeture de l’application▲
Lors de la fermeture de l’application, la méthode base ‘Sur fermeture' appelle rss_surFermeture pour supprimer le dossier contenant nos notes techniques converties en HTML.
Attention, l’utilisation de la commande SUPPRIMER DOSSIER n’est pas suffisante, car elle ne permet de supprimer qu’un dossier vide de contenu !
` Methode : rss_surFermeture
` Description :
` appelé sur fermeture de l’application
` pour nettoyer le dossier des pages HTML
`
` Parametres :
`
`
` Version : 1
` Appel : rss_surFermeture
` ----------------------------------------------------
C_TEXTE($_vt_html)
$_vt_html:=Dossier 4D+"NT"+FILE_PlateformSeparator
Si (Tester chemin acces($_vt_html)=Est un répertoire )
FILE_DeleteFolder ($_vt_html)
Fin de si
Note :
la méthode FILE_DeleteFolder présentait un bug, il faut donc utiliser la version corrigée présente dans le dossier RSS.
Lien vers le site complet▲
Le lien <link>, enfant de <channel>, doit nous amener vers le site Web affichant en HTML les informations listées dans le flux RSS :
<link>http://192.168.1.10/4DAction/rss_Home</link>
Aspect HTML de la liste des notes techniques▲
La liste de toutes les notes techniques de la base de données est présentée, triée par date décroissante.
Méthode rss_Home▲
Nous devons créer une méthode rss_Home appelée par 4DAction et dont voici le source :
` Methode : Méthode : rss_Home
` Description :
` affichage HTML de toutes les notes techniques de la base
`
` Parametres :
` $1:TEXTE:vide
`
` Version : 1
` Appel : http://192.168.1.10/4DAction/rss_Home
` ----------------------------------------------------
C_TEXTE($1)
Si (Indefinie(<>rss_vt_locaIP))
rss_surOuverture
Fin de si
C_TEXTE(rss_vt_local_IP)
rss_vt_local_IP:=<>rss_vt_locaIP
LECTURE SEULEMENT([TECHNOTES])
TOUT SELECTIONNER([TECHNOTES])
TRIER([TECHNOTES];[TECHNOTES]Date;<)
ENVOYER FICHIER HTML("rss_nt_full.shtm")
Cette méthode, très simple, effectue la sélection des notes techniques, initialise les variables process utilisées par balises 4DVAR et renvoie la page semi-dynamique « rss_nt_full.shtm ».
Modèle semi-dynamique▲
Voici le modèle semi-dynamique utilisé :
<!
DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
>
<html>
<head>
<title>Liste des notes techniques</title>
<meta http-equiv
=
"Content-Type"
content
=
"text/html; charset=iso-8859-1"
>
</head>
<body>
<h1 align
=
"center"
><img src
=
"/images/4D_Rss.gif"
width
=
"39"
height
=
"53"
><strong>
Liste des notes techniques </strong></h1>
<!--#4dloop [TECHNOTES]-->
<!--#4dscript/rss_BuildAuthorsNames/-->
<Table width
=
"100%"
border
=
"0"
>
<tr>
<td width
=
"10%"
>
<strong>Titre :</strong></td>
<td width
=
"60%"
><a href
=
"http://<!--#4DVAR rss_vt_local_IP-->/4DAction/rss_nt_html/id=<!--#4dvar [TECHNOTES]ID-->"
>
<!--#4dvar [TECHNOTES]Title-->
</a></td>
<td width
=
"10%"
><div align
=
"right"
><strong>Ref4D :</strong></div></td>
<td width
=
"20%"
>
<!--#4dvar [TECHNOTES]Ref4D-->
</td>
</tr>
<tr>
<td><strong>Date :</strong></td>
<td> <!--#4dvar [TECHNOTES]Date-->
</td>
<td><div align
=
"right"
><strong>Auteurs :</strong></div></td>
<td><!--#4DVAR rss_vt_NomAuteurs--->
</td>
</tr>
</Table>
<!--#4dvar [TECHNOTES]Summary-->
<hr>
<!--#4dendloop-->
<br>
</body>
</html>
Rien de particulier non plus dans cette page semi-dynamique classique dont l’analyse et le traitement seront effectués automatiquement par le serveur http de 4D.
Installation dans 4D Knowledge.4DB▲
Recopie des éléments requis▲
Aucun formulaire n’est utilisé.
Il suffit :
· de transférer via 4D Insider les méthodes du dossier RSS de la librairie rss.4IL dans votre version de 4D Knowledge.4DB ;
· de recopier le dossier « DossierWeb » auprès de « 4D Knowledge.4DB » ;
· puis d’effectuer les vérifications décrites au paragraphe suivant.
Paramétrage du serveur http▲
Pour que tout cela fonctionne, il faut que le serveur http et les méthodes utilisées soient paramétrés convenablement.
Méthodes accédées par le serveur http▲
Rappelons que toutes les méthodes sollicitées par le serveur http doivent, en version 2004, être paramétrées explicitement en cochant « Disponible via 4DACTION, 4DMETHOD et 4DSCRIPT » dans leurs propriétés :
Ces méthodes sont ensuite reconnaissables à leur icône particulière dans l’explorateur :
DossierWeb▲
Dans la version originale de l’application, la racine HTML par défaut se nommait « WebFolder », remplaçons-la par « DossierWeb » pour compatibilité avec nos méthodes.
Vérification dans un client riche▲
La société Adobe propose un outil de création de client riche Internet : Flex.
Cet environnement permet de réaliser des applications aux interfaces évoluées s’exécutant dans le contexte d’un navigateur grâce au plugin Flash player dans sa version 9 :
www.adobe.com/fr/products/flex/
Il est très simple avec cet outil de créer un lecteur de flux RSS qui affiche les données publiées par notre application. Si vous travaillez en local, il vous suffit de saisir l’URL suivante dans le navigateur pour voir un exemple :
http://127.0.0.1/BlogReader.html
Et le client riche affiche le flux RSS :
Conclusion▲
Dans cette deuxième note sur les flux RSS, nous avons montré comment publier un flux depuis une application 4D existante. Vous pouvez ainsi constater qu’il s’agit d’une opération technique assez simple. Dans les mois qui suivent, nous devrions donc assister à une forte augmentation des publications RSS depuis des applications 4D !
Télécharger la base exemple▲
Télécharger la base exemple.