<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://www.numabilis.com">
<channel>
 <title>Numabilis - Ingénierie web</title>
 <link>http://www.numabilis.com/taxonomy/term/1/0</link>
 <description></description>
 <language>fr</language>
<item>
 <title>Google Maps API : gestionnaire automatique de marqueurs</title>
 <link>http://www.numabilis.com/blog/2007-11-21-google_maps_api_gestionnaire_automatique_de_marqueurs</link>
 <description>&lt;p&gt;Comme nous l&#039;avons vu dans le billet précédent sur le &lt;a href=&quot;/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;gestionnaire de marqueurs&lt;/a&gt;, l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt; ne gère pas automatiquement le remplacement d&#039;un groupe de marqueurs proches par un marqueur unique à faible facteur de zoom. Heureusement, &lt;a href=&quot;http://en.wikipedia.org/wiki/Jef_Poskanzer&quot; title=&quot;Lire l&#039;article Jef Poskanzer sur Wikipédia&quot; hreflang=&quot;en&quot;&gt;Jef &lt;span class=&quot;np&quot;&gt;Poskanzer&lt;/span&gt;&lt;/a&gt; a écrit une librairie implémentant cette fonctionnalité : &lt;a href=&quot;http://www.acme.com/javascript/#Clusterer&quot; title=&quot;Aller sur la page de la librairie Clusterer&quot; hreflang=&quot;en&quot;&gt;Clusterer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Partons de l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple09.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;9&lt;/a&gt; qui est identique à l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple04.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;4&lt;/a&gt; d&#039;un &lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;précédent billet&lt;/a&gt; auquel j&#039;ai ajouter une concentration importante de marqueurs à l&#039;est de Paris. Déclarons la librairie dans l&#039;en-tête HTML&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;script src=&quot;http://www.acme.com/javascript/Clusterer2.jsm&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/div&gt;
&lt;/p&gt;La gestion automatique se fait en déclarant une variable &lt;tt&gt;clusterer&lt;/tt&gt;, instanciée dans la fonction &lt;tt&gt;load&lt;/tt&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;code_highlight&quot;&gt;var clusterer;&lt;/span&gt;

function load() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById(&quot;map&quot;));
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(46.85, 1.75), 6);
    &lt;span class=&quot;code_highlight&quot;&gt;clusterer = new Clusterer(map);
    clusterer.SetMaxVisibleMarkers(10);
    clusterer.SetMinMarkersPerCluster(5);&lt;/span&gt;

    GDownloadUrl(&quot;exemple10.json&quot;, setup_json);
  } else {
    alert(&quot;Desole, l&#039;API Google Maps n&#039;est pas compatible avec votre navigateur.&quot;);
  }
}&lt;/div&gt;
&lt;p&gt;Un objet &lt;tt&gt;Clusterer&lt;/tt&gt; possède 4 méthodes&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;tt&gt;SetMaxVisibleMarkers(n)&lt;/tt&gt;&lt;/strong&gt;&amp;nbsp;: définie le nombre de marqueurs au delà duquel le &lt;em&gt;clustering&lt;/em&gt; est mis en place (150 par défaut).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;tt&gt;SetMinMarkersPerCluster(n)&lt;/tt&gt;&lt;/strong&gt;&amp;nbsp;: définie le nombre minimum de marqueurs constituant un &lt;em&gt;cluster&lt;/em&gt; (5 par défaut).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;tt&gt;SetMaxLinesPerInfoBox(n)&lt;/tt&gt;&lt;/strong&gt;&amp;nbsp;: définie le nombre de ligne s&#039;affichant dans la fenêtre d&#039;information du marqueur correspondant au &lt;em&gt;cluster&lt;/em&gt; (10 par défaut).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;tt&gt;SetIcon(icon)&lt;/tt&gt;&lt;/strong&gt;&amp;nbsp;: définie l&#039;icône du marqueur correspondant au &lt;em&gt;cluster&lt;/em&gt; si celui par défaut ne convient pas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il suffit ensuite de remplacer chaque appel à &lt;tt&gt;map.addOverlay(marker)&lt;/tt&gt; par un appel à &lt;tt&gt;clusterer.AddMarker(marker, title)&lt;/tt&gt; (où &lt;tt&gt;title&lt;/tt&gt; est la ligne du marqueur réel qui s&#039;affichera dans la fenêtre d&#039;information du marqueur correspondant au &lt;em&gt;cluster&lt;/em&gt;) et chaque appel à &lt;tt&gt;map.removeOverlay(marker)&lt;/tt&gt; par un appel à &lt;tt&gt;clusterer.RemoveMarker(marker)&lt;/tt&gt;. Exemple dans la fonction &lt;tt&gt;setup_json&lt;/tt&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;setup_json = function(json, status) {
  var data = eval(&#039;(&#039; + json + &#039;)&#039;);
  
  for (var i=0; i&amp;lt;data.markers.length; i++) {
    var point = new GLatLng(data.markers[i].lat, data.markers[i].lng);
    var marker = createMarker(point, data.markers[i].html);
    &lt;span class=&quot;code_highlight&quot;&gt; clusterer.AddMarker(marker, data.markers[i].html);&lt;/span&gt;
  }

}&lt;/div&gt;
&lt;p&gt;Le résultat est visible sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple10.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;10&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cette solution permet de rendre de bons services, mais n&#039;est toute fois pas idéale. En effet, le &lt;em&gt;clustering&lt;/em&gt; est lié au nombre de marqueurs plutôt qu&#039;à leur densité. Ainsi, deux marqueurs supperposés ne seront vus que comme un seul marqueur à fort grossissement (en l&#039;absence de &lt;em&gt;clustering&lt;/em&gt;). D&#039;autre part, l&#039;algorithme n&#039;est pas très précis&amp;nbsp;: sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple10.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;10&lt;/a&gt;, le marqueur placé sur Le Havre a été intégré au &lt;em&gt;cluster&lt;/em&gt; bien qu&#039;il en soit assez éloigné&amp;nbsp;!&lt;/p&gt;
&lt;p&gt;Les autres billets de cette série sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-10-api_google_maps_premieres_cartes&quot; title=&quot;Lire le billet&quot;&gt;API Google Maps : premières cartes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : marqueurs et fenêtres d&#039;informations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : affichage des données d&#039;un fichier JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_geolocalisation_geocoding&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : géolocalisation (geocoding)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : un marqueur déplaçable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Maps API : gestionnaire automatique de marqueurs&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Wed, 21 Nov 2007 20:42:00 +0100</pubDate>
</item>
<item>
 <title>Google Maps API : gestionnaire de marqueurs</title>
 <link>http://www.numabilis.com/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs</link>
 <description>&lt;p&gt;Reprenons notre exploration de l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt; pour résoudre le problème suivant&amp;nbsp;: &lt;strong&gt;comment afficher un unique marqueur regroupant plusieurs marqueurs lorsque le niveau de zoom est faible&amp;nbsp;?&lt;/strong&gt; En effet, lorsque le nombre de marqueurs est très important sur une petite région, la carte est difficile à lire et lente à s&#039;afficher. La réponse semble être le gestionnaire de marqueurs &lt;a href=&quot;http://www.google.com/apis/maps/documentation/reference.html#GMarkerManager&quot; title=&quot;Lire la documentation de l&#039;API&quot; hreflang=&quot;en&quot;&gt;GMarkerManager&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Partons de l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple04.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;4&lt;/a&gt; d&#039;un &lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;précédent billet&lt;/a&gt; dans lequel nous déléguons l&#039;affichage des marqueurs à un gestionnaire de marqueurs. Pour cela, on déclare une variable &lt;tt&gt;mgr&lt;/tt&gt;, que l&#039;on instancie dans la fonction &lt;tt&gt;load&lt;/tt&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;code_highlight&quot;&gt;var mgr;&lt;/span&gt;

function load() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById(&quot;map&quot;));
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(46.85, 1.75), 6);
    &lt;span class=&quot;code_highlight&quot;&gt;mgr = new MarkerManager(map);&lt;/span&gt;

    GDownloadUrl(&quot;exemple04.json&quot;, setup_json);
  } else {
    alert(&quot;Desole, l&#039;API Google Maps n&#039;est pas compatible avec votre navigateur.&quot;);
  }
}&lt;/div&gt;
&lt;p&gt;L&#039;ajout des marqueurs se fait dans la fonctions &lt;tt&gt;setup_json&lt;/tt&gt; en créant d&#039;abord un tableau de marqueurs, &lt;tt&gt;markers&lt;/tt&gt;, ajouter en une fois à la carte via la fonction &lt;tt&gt;addMarkers&lt;/tt&gt; prenant comme second paramètre le niveau de zoom minimum en deçà duquel les marqueurs ne sont pas affichés, et un troisième argument optionnel, le niveau de zoom maximum au delà duquel les marqueurs ne sont pas affichés&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;setup_json = function(json, status) {
  var data = eval(&#039;(&#039; + json + &#039;)&#039;);
  &lt;span class=&quot;code_highlight&quot;&gt;var markers = new Array();&lt;/span&gt;
  
  for (var i=0; i&amp;lt;data.markers.length; i++) {
    var point = new GLatLng(data.markers[i].lat, data.markers[i].lng);
    var marker = createMarker(point, data.markers[i].html);
    &lt;span class=&quot;code_highlight&quot;&gt;markers.push(marker);&lt;/span&gt;
  }

  &lt;span class=&quot;code_highlight&quot;&gt;mgr.addMarkers(markers, 5);
  mgr.refresh();&lt;/span&gt;
}&lt;/div&gt;
&lt;p&gt;Le résultat est visible sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple08.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;8&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On peut appeler plusieurs fois la méthode &lt;tt&gt;addMarkers&lt;/tt&gt; avec différents tableaux de marqueurs pour différents niveau de zoom et gérer ainsi, &lt;em&gt;à la mano&lt;/em&gt;, les regroupements de marqueurs. Cela implique donc de calculer, sur le serveur, l&#039;emplacement des marqueurs qui prendront la place d&#039;un ensemble de marqueurs et du niveau de zoom auquel on affiche chacun... Pas simple&amp;nbsp;! Heureusement il existe une solution toute faite via une librairie JavaScript... Suite au prochain épisode&amp;nbsp;!&lt;/p&gt;
&lt;p&gt;Les autres billets de cette série sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-10-api_google_maps_premieres_cartes&quot; title=&quot;Lire le billet&quot;&gt;API Google Maps : premières cartes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : marqueurs et fenêtres d&#039;informations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : affichage des données d&#039;un fichier JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_geolocalisation_geocoding&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : géolocalisation (geocoding)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : un marqueur déplaçable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Maps API : gestionnaire de marqueurs&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-21-google_maps_api_gestionnaire_automatique_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire automatique de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Tue, 20 Nov 2007 19:54:34 +0100</pubDate>
</item>
<item>
 <title>Développer en local une application mashup (Google Maps API, facebook, etc)</title>
 <link>http://www.numabilis.com/blog/2007-08-30-developper_en_local_une_application_mashup_google_maps_api_facebook_etc</link>
 <description>&lt;p&gt;Le développement d&#039;une application s&#039;appuyant sur un service externe (&lt;em&gt;mashup&lt;/em&gt;) tel que &lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;Google Maps&lt;/a&gt; ou &lt;a href=&quot;http://developers.facebook.com/&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;facebook&lt;/a&gt; nécessite de le faire sur un serveur accessible depuis Internet. Cela est imposé par le fournisseur du service qui soit délivre une clé liée au nom du serveur (&lt;a href=&quot;http://maps.google.com/&quot; title=&quot;Aller sur le site Google Maps&quot; hreflang=&quot;fr&quot;&gt;Google Maps&lt;/a&gt; par exemple), soit fait des requêtes directement sur le serveur (&lt;a href=&quot;http://www.facebook.com/&quot; title=&quot;Aller sur le site facebook&quot; hreflang=&quot;en&quot;&gt;facebook&lt;/a&gt;). Voici une adaptation d&#039;un &lt;a href=&quot;http://www.insidefacebook.com/2007/07/16/how-to-local-facebook-app-development/&quot; title=&quot;Lire le tutoriel &#039;How To Local Facebook App Development&#039;&quot; hreflang=&quot;en&quot;&gt;tutoriel&lt;/a&gt; permettant de développer une telle application sur votre propre poste de développement local (si vous maîtrisez votre réseau).&lt;/p&gt;

&lt;p&gt;Il n&#039;y a pas de solution miracle. La seule possibilité est de mettre son poste de développement (le PC) sur Internet. Cela implique de pouvoir faire de la translation de port sur votre &lt;a href=&quot;http://fr.wikipedia.org/wiki/Routeur&quot; title=&quot;Lire l&#039;article &#039;Routeur&#039; sur Wikipédia&quot; hreflang=&quot;fr&quot;&gt;routeur&lt;/a&gt; &lt;a href=&quot;http://fr.wikipedia.org/wiki/Network_address_translation&quot; title=&quot;Lire l&#039;article &#039;Network address translation&#039; sur Wikipédia&quot; hreflang=&quot;fr&quot;&gt;NAT&lt;/a&gt;. Cette opération varie d&#039;un routeur à un autre. Mais vous aurez généralement besoin de connaître l&#039;&lt;a href=&quot;http://fr.wikipedia.org/wiki/Adresse_IP&quot; title=&quot;Lire l&#039;article &#039;Adresse IP&#039; sur Wikipédia&quot; hreflang=&quot;fr&quot;&gt;adresse IP&lt;/a&gt; du PC sur le réseau interne ainsi que son &lt;a href=&quot;http://fr.wikipedia.org/wiki/Adresse_MAC&quot; title=&quot;Lire l&#039;article &#039;Adresse MAC&#039; sur Wikipédia&quot; hreflang=&quot;fr&quot;&gt;adresse MAC&lt;/a&gt;. Pour cela il suffit de taper la commande &lt;span class=&quot;code&quot;&gt;ifconfig eth0&lt;/span&gt; qui vous sort un truc comme ça (les adresses ci-dessous sont fictives)&amp;nbsp;:&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;eth0    Lien encap:Ethernet  HWaddr &lt;span class=&quot;code_highlight&quot;&gt;00:12:62:4A:BA:28&lt;/span&gt;
        inet adr:&lt;span class=&quot;code_highlight&quot;&gt;192.168.0.13&lt;/span&gt;  Bcast:192.168.0.255  Masque:255.255.255.0
        adr inet6: fa70::153:73ef:fb9a:da16/64 Scope:Lien
        UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
        Packets reçus:55899 erreurs:0 :0 overruns:0 frame:0
        TX packets:49661 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 lg file transmission:1000 
        Octets reçus:62053810 (59.1 MiB) Octets transmis:8498200 (8.1 MiB)
        Interruption:16 
&lt;/div&gt;
&lt;p&gt;L&#039;adresse IP du PC sur le réseau interne est donc &lt;span class=&quot;code&quot;&gt;192.168.0.13&lt;/span&gt; et son adresse MAC &lt;span class=&quot;code&quot;&gt;00:12:62:4A:BA:28&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Il suffit de configurer son routeur pour lui indiquer que l&#039;adresse MAC &lt;span class=&quot;code&quot;&gt;00:12:62:4A:BA:28&lt;/span&gt; doit toujours être associée à l&#039;adresse IP &lt;span class=&quot;code&quot;&gt;192.168.0.13&lt;/span&gt; et que les requêtes reçu par le routeur sur le port 80 doivent être renvoyées vers le port 80 de la machine d&#039;adresse IP &lt;span class=&quot;code&quot;&gt;192.168.0.13&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Vous pouvez chercher la procédure adaptée à votre routeur sur le site &lt;a href=&quot;http://www.portforward.com/english/routers/port_forwarding/routerindex.htm&quot; title=&quot;Aller sur la page indexant les routeurs&quot; hreflang=&quot;en&quot;&gt;Port Forward&lt;/a&gt;. Dans le cas d&#039;une freebox, il suffit d&#039;aller sur la page de configuration accessible après &lt;a href=&quot;http://subscribe.free.fr/login/&quot;title=&quot;S&#039;authentifier sur le service Free&quot; hreflang=&quot;fr&quot;&gt;login&lt;/a&gt;, et de remplir le formulaire&amp;nbsp;:&lt;/p&gt;
&lt;center&gt;&lt;br&gt;&lt;a href=&quot;/files/pictures/configuration-routeur-freebox-nat-big.png&quot; title=&quot;Agrandir l&#039;image&quot;&gt;&lt;img title=&quot;Exemple de configuration sur la Freebox&quot; alt=&quot;Exemple de configuration sur la Freebox&quot; src=&quot;/files/pictures/configuration-routeur-freebox-nat-small.png&quot; height=&quot;557&quot; width=&quot;350&quot; /&gt;&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;/files/pictures/configuration-routeur-freebox-nat-big.png&quot; title=&quot;Agrandir l&#039;image&quot;&gt;Exemple de configuration sur la Freebox (agrandir)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/center&gt;
&lt;p&gt;Vérifiez que cela fonctionne en pointant votre navigateur vers l&#039;adresse IP publique de votre routeur, récupérable via son interface de configuration ou via le service web &lt;a href=&quot;http://whatismyip.org/&quot; title=&quot;Aller sur le site &#039;What is my IP&#039;&quot; hreflang=&quot;en&quot;&gt;What is my IP&lt;/a&gt; (&lt;span class=&quot;code&quot;&gt;88.171.154.137&lt;/span&gt; par exemple). Vous devez voir la racine de votre serveur web... Vous pouvez même donner un nom DNS à cette adresse IP. Il ne vous reste plus qu&#039;à générer la clé du service pour cette adresse IP&amp;nbsp;!
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Thu, 30 Aug 2007 20:53:06 +0200</pubDate>
</item>
<item>
 <title>Google Maps API : coordonnées d&#039;un marqueur</title>
 <link>http://www.numabilis.com/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur</link>
 <description>&lt;p&gt;Ce sixième et dernier billet (pour le moment du moins) sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt; vous apprendra à récupérer les coordonnées d&#039;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le précédent billet&quot;&gt;un marqueur déplaçable&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Partons de l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple06.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;6&lt;/a&gt; du &lt;a href=&quot;/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le cinquième billet&quot;&gt;billet précédent&lt;/a&gt;. Les coordonnées sont des propriétés du marqueur qu&#039;il suffit de récupérer à la fin d&#039;un glisser/déposer dans la fonction &lt;tt&gt;createMarker&lt;/tt&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;GEvent.addListener(marker, &quot;dragend&quot;, function() {
  htm = html + &#039;&amp;lt;br /&amp;gt;Lat_1 = &#039; + point.lat() + &#039; Lat_2 = &#039; + marker.getPoint().lat();
  htm = htm + &#039;&amp;lt;br /&amp;gt;Lng_1 = &#039; + point.lng() + &#039; Lng_2 = &#039; + marker.getPoint().lng();
  marker.openInfoWindowHtml(htm);
});&lt;/div&gt;
&lt;p&gt;Voilà&amp;nbsp;! Nous avons tout ce dont nous avons besoin pour faire un formulaire d&#039;enregistrement de coordonnées en plus de l&#039;affichage de marqueurs correspondants à des emplacements fournis sous forme de données JSON.&lt;/p&gt;
&lt;p&gt;Le résultat est visible sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple07.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;7&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les autres billets de cette série sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-10-api_google_maps_premieres_cartes&quot; title=&quot;Lire le billet&quot;&gt;API Google Maps : premières cartes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : marqueurs et fenêtres d&#039;informations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : affichage des données d&#039;un fichier JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_geolocalisation_geocoding&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : géolocalisation (geocoding)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : un marqueur déplaçable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-21-google_maps_api_gestionnaire_automatique_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire automatique de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Sun, 08 Jul 2007 22:55:10 +0200</pubDate>
</item>
<item>
 <title>Google Maps API : un marqueur déplaçable</title>
 <link>http://www.numabilis.com/blog/2007-07-08-google_maps_api_un_marqueur_deplacable</link>
 <description>&lt;p&gt;Ce cinqième billet sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt; vous apprendra à créer un marqueur déplaçable par simple glisser/déposer (&lt;em&gt;drag and drop&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Partons de l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple05.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;5&lt;/a&gt; du &lt;a href=&quot;/blog/2007-07-08-google_maps_api_geolocalisation_geocoding&quot; title=&quot;Lire le quatrième billet&quot;&gt;billet précédent&lt;/a&gt; dont nous allons simplement modifier la fonction de création de marqueur &lt;tt&gt;createMarker&lt;/tt&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;function createMarker(point,html) {
  var icon = new GIcon(G_DEFAULT_ICON);
  icon.image = &quot;http://www.numabilis.com/files/demos/google-maps/blue-dot.png&quot;;
  
  var options = {
    icon: icon,
    draggable: true
  };
  var marker = new GMarker(point, options);
  GEvent.addListener(marker, &quot;dragstart&quot;, function() {
    map.closeInfoWindow();
  });
  
  GEvent.addListener(marker, &quot;dragend&quot;, function() {
    marker.openInfoWindowHtml(html);
  });
  
  GEvent.addListener(marker, &quot;click&quot;, function() {
    marker.openInfoWindowHtml(html);
  });
  
  return marker;
}&lt;/div&gt;
&lt;p&gt;Le marqueur est donc construit en passant des options au constructeur&amp;nbsp;: l&#039;URL (absolue) d&#039;une icône (pour différencier le marqueur déplaçable des autres) et un simple booléen indiquant que le marqueur est déplaçable&amp;nbsp;! Il est également possible, comme dans cet exemple de définir des fonctions appelées au début et à la fin du déplacement.&lt;/p&gt;
&lt;p&gt;Le résultat est visible sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple06.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;6&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les autres billets de cette série sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-10-api_google_maps_premieres_cartes&quot; title=&quot;Lire le billet&quot;&gt;API Google Maps : premières cartes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : marqueurs et fenêtres d&#039;informations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : affichage des données d&#039;un fichier JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_geolocalisation_geocoding&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : géolocalisation (geocoding)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Maps API : un marqueur déplaçable&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-21-google_maps_api_gestionnaire_automatique_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire automatique de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Sun, 08 Jul 2007 19:02:32 +0200</pubDate>
</item>
<item>
 <title>Google Maps API : géolocalisation (geocoding)</title>
 <link>http://www.numabilis.com/blog/2007-07-08-google_maps_api_geolocalisation_geocoding</link>
 <description>&lt;p&gt;Ce quatrième billet sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt; vous apprendra à afficher la carte d&#039;un lieu à partir de son adresse. C&#039;est ce que l&#039;on nomme &lt;a href=&quot;http://www.google.com/apis/maps/documentation/services.html#Geocoding&quot; title=&quot;Lire la documentation de l&#039;API&quot; hreflang=&quot;en&quot;&gt;geocoding&lt;/a&gt; dans l&#039;API, opération réalisée grâce à un objet JavaScript, le &lt;a href=&quot;http://www.google.com/apis/maps/documentation/reference.html#GClientGeocoder&quot; title=&quot;Lire le détail de l&#039;API du geocoder&quot; hreflang=&quot;en&quot;&gt;geocoder&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Partons de l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple04.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;4&lt;/a&gt; du &lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le troisième billet&quot;&gt;billet précédent&lt;/a&gt; auquel nous ajoutons la variable globale &lt;tt&gt;geocoder&lt;/tt&gt;. Le chargement du fichier JSON est remplacé par l&#039;instanciation du geocoder dans la fonction &lt;tt&gt;load&lt;/tt&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;var geocoder;

function load() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById(&quot;map&quot;));
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(46.85, 1.75), 6);
    &lt;span class=&quot;code_highlight&quot;&gt;geocoder = new GClientGeocoder();&lt;/span&gt;
  } else {
    alert(&quot;Desole, l&#039;API Google Maps n&#039;est pas compatible avec votre navigateur.&quot;);
  }
}&lt;/div&gt;
&lt;p&gt;Nous ajoutons à la page un formulaire permettant la saisie de l&#039;adresse cherchée. La validation du formulaire est interceptée par la fonction &lt;tt&gt;geocode&lt;/tt&gt; qui prend en paramètre l&#039;adresse saisie&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;form &lt;span class=&quot;code_highlight&quot;&gt;onsubmit=&quot;return geocode(this.address.value);&quot;&lt;/span&gt;&amp;gt;
  Adresse : &amp;lt;input type=&quot;text&quot; size=&quot;80&quot; name=&quot;address&quot; /&amp;gt;
  &amp;lt;input type=&quot;submit&quot; value=&quot;GO&quot; /&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/div&gt;
&lt;p&gt;Cette fonction &lt;tt&gt;geocode&lt;/tt&gt;, qui va faire tout le travail, est extrêmement simple&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;function geocode(address) {
  geocoder.getLatLng(
    address,
    function(point) {
      if (!point) {
        alert(address + &quot; not found&quot;);
      } else {
        map.setCenter(point, 13);
        var marker = createMarker(point, address);
        map.addOverlay(marker);
        marker.openInfoWindowHtml(address);
      }
    }
  );
  
  return false;
}&lt;/div&gt;
&lt;p&gt;Elle consiste à appeler la fonction &lt;tt&gt;getLatLng&lt;/tt&gt; du &lt;tt&gt;geocoder&lt;/tt&gt; en lui passant en paramètre l&#039;adresse saisie et une fonction appelée par le &lt;tt&gt;geocoder&lt;/tt&gt; au retour de la requête HTTP. En cas de succès, on centre la carte sur le point correspondant à l&#039;adresse, on créé un marqueur que l&#039;on ajoute sur la carte et on affiche la fenêtre d&#039;information.&lt;/p&gt;
&lt;p&gt;Le résultat est visible sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple05.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;5&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les autres billets de cette série sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-10-api_google_maps_premieres_cartes&quot; title=&quot;Lire le billet&quot;&gt;API Google Maps : premières cartes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : marqueurs et fenêtres d&#039;informations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : affichage des données d&#039;un fichier JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Maps API : géolocalisation (geocoding)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.numabilis.com/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : un marqueur déplaçable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-21-google_maps_api_gestionnaire_automatique_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire automatique de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Sun, 08 Jul 2007 14:55:14 +0200</pubDate>
</item>
<item>
 <title>Google Maps API : affichage des données d&#039;un fichier JSON</title>
 <link>http://www.numabilis.com/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json</link>
 <description>&lt;p&gt;Ce troisième billet sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt; vous apprendra à afficher des données distantes au format &lt;a href=&quot;http://www.json.org/jsonfr.html&quot; title=&quot;Lire la présentation de la notation objet de JavaScript&quot; hreflang=&quot;fr&quot;&gt;JSON&lt;/a&gt; (produites dynamiquement par un serveur par exemple). L&#039;API peut utiliser le format XML. Je préfère cependant utiliser le format JSON, plus compact et plus rapide à traiter en JavaScript, mais aussi plus complexe.&lt;/p&gt;
&lt;p&gt;Partons de l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple03.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;3&lt;/a&gt; du &lt;a href=&quot;/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations&quot; title=&quot;Lire le second billet&quot;&gt;billet précédent&lt;/a&gt; dont nous supprimons la création du marqueur lors du chargement de la page (fonction &lt;tt&gt;load&lt;/tt&gt;) pour la remplacer par un appel à la fonction &lt;tt&gt;GDownloadUrl&lt;/tt&gt;. Cette fonction permet de charger une ressource de manière asynchrone et prends deux paramètres&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;&lt;strong&gt;url&lt;/strong&gt;&lt;/tt&gt;&amp;nbsp;: l&#039;URL de la ressource, &lt;a href=&quot;/files/demos/google-maps/exemple04.json&quot; title=&quot;Voir le fichier JSON utilisé pour ce tutoriel&quot;&gt;&lt;tt&gt;exemple04.json&lt;/tt&gt;&lt;/a&gt; dans notre exemple.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;&lt;strong&gt;onload&lt;/strong&gt;&lt;/tt&gt;&amp;nbsp;: la fonction à appeler après le chargement de la ressource. Cette fonction doit avoir deux paramètres&amp;nbsp;:
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;&lt;strong&gt;text&lt;/strong&gt;&lt;/tt&gt;&amp;nbsp;: le texte du document téléchargé.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;&lt;strong&gt;status&lt;/strong&gt;&lt;/tt&gt;&amp;nbsp;: le code du statut de la réponse HTTP.&lt;/li&gt;
&lt;/ul&gt;
En cas de &lt;em&gt;timeout&lt;/em&gt; de la requête, la fonction est appelée avec &lt;tt&gt;null&lt;/tt&gt; et &lt;tt&gt;-1&lt;/tt&gt; comme arguments.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nous avons donc la fonction &lt;tt&gt;load&lt;/tt&gt; suivante&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;function load() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById(&quot;map&quot;));
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(46.85, 1.75), 6);
    
    GDownloadUrl(&quot;exemple04.json&quot;, setup_json);
  } else {
    alert(&quot;Desole, l&#039;API Google Maps n&#039;est pas compatible avec votre navigateur.&quot;);
  }
}&lt;/div&gt;
&lt;p&gt;Notons au passage que la vairable &lt;tt&gt;map&lt;/tt&gt; a été sortie de la fonction afin de la rendre globale et de pouvoir y accéder dans la fonction &lt;tt&gt;set_json&lt;/tt&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;setup_json = function(json, status) {
  var data = eval(&#039;(&#039; + json + &#039;)&#039;);
  
  for (var i=0; i&amp;lt;data.markers.length; i++) {
    var point = new GLatLng(data.markers[i].lat, data.markers[i].lng);
    var marker = createMarker(point, data.markers[i].html);
    map.addOverlay(marker);
  }
}&lt;/div&gt;
&lt;p&gt;Le résultat est visible sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple04.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;4&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Plus de précisions : &lt;a href=&quot;http://econym.googlepages.com/basic12.htm&quot; title=&quot;Lire le tutorial&quot; hreflang=&quot;en&quot;&gt;Data in JSON files&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les autres billets de cette série sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-10-api_google_maps_premieres_cartes&quot; title=&quot;Lire le billet&quot;&gt;API Google Maps : premières cartes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : marqueurs et fenêtres d&#039;informations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Maps API : affichage des données d&#039;un fichier JSON&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;/blog/2007-07-08-google_maps_api_geolocalisation_geocoding&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : géolocalisation (geocoding)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.numabilis.com/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : un marqueur déplaçable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-21-google_maps_api_gestionnaire_automatique_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire automatique de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Sat, 07 Jul 2007 13:47:49 +0200</pubDate>
</item>
<item>
 <title>Google Maps API : marqueurs et fenêtres d&#039;informations</title>
 <link>http://www.numabilis.com/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations</link>
 <description>&lt;p&gt;Ce second billet vous apprendra à ajouter des marqueurs affichant une fenêtre d&#039;information lorsque l&#039;on clique dessus.&lt;/p&gt;
&lt;p&gt;Partons de l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple02.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;2&lt;/a&gt; du &lt;a href=&quot;/blog/2007-06-10-api_google_maps_premieres_cartes&quot; title=&quot;Lire le premier billet&quot;&gt;billet précédent&lt;/a&gt; auquel nous ajoutons le bloc suivant dans le corps, afin de pr&amp;eacute;venir les utilisateurs ne disposant pas de JavaScript&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;noscript&amp;gt;
  &amp;lt;b&amp;gt;JavaScript doit &amp;ecirc;tre activ&amp;eacute; pour utiliser Google Maps.&amp;lt;/b&amp;gt;
  Il semblerait que JavaScript soit d&amp;eacute;sactiv&amp;eacute; ou non support&amp;eacute; par votre navigateur.
  Pour visualiser les cartes Google Maps, activez JavaScript dans les options de votre navigateur et r&amp;eacute;essayez.
&amp;lt;/noscript&amp;gt;
&lt;/div&gt;
&lt;p&gt;Pr&amp;eacute;venons aussi les utilisateurs dont le navigateur n&#039;est pas compatible avec l&#039;API Google Maps en définissant la clause &lt;tt&gt;else&lt;/tt&gt; du test de compatibilit&amp;eacute; dans la fonction &lt;tt&gt;load&lt;/tt&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;if (GBrowserIsCompatible()) {
  // ...
} else {
  alert(&quot;Desole, l&#039;API Google Maps n&#039;est pas compatible avec votre navigateur.&quot;);
}
&lt;/div&gt;
&lt;p&gt;Ajoutons ensuite, lors de la création de la carte, dans la fonction &lt;tt&gt;load&lt;/tt&gt;, l&#039;affichage du contrôle de positionnement et de zoom&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;map.addControl(new GLargeMapControl());&lt;/div&gt;
&lt;p&gt;ainsi que le contrôle du type de carte (plan, satellite ou mixte)&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;map.addControl(new GMapTypeControl());&lt;/div&gt;
&lt;p&gt;Définissons un premier marqueur sur &lt;a href=&quot;http://fr.wikipedia.org/wiki/Mantes-la-Jolie&quot; title=&quot;Voir la page Wikipédia sur Mantes-la-Jolie&quot; hreflang=&quot;fr&quot;&gt;Mantes-la-Jolie&lt;/a&gt; (de coordonnées 48.9908338, 1.717222)&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;var point = new GLatLng(48.9908338,1.717222);
var marker = createMarker(point,&#039;Ici, c\&#039;est chez moi&amp;nbsp;!&#039;)
map.addOverlay(marker);
&lt;/div&gt;
&lt;p&gt;La fonction &lt;tt&gt;createMarker&lt;/tt&gt; est la suivante&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;function createMarker(point,html) {
  var marker = new GMarker(point);
  GEvent.addListener(marker, &quot;click&quot;, function() {
    marker.openInfoWindowHtml(html);
  });

  return marker;
}
&lt;/div&gt;
&lt;p&gt;Le résultat est visible sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple03.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;3&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;La fenêtre d&#039;information affiche du HTML standard et il est possible de définir autant de marqueur que l&#039;on souhaite...&lt;/p&gt;
&lt;p&gt;Plus de précisions : &lt;a href=&quot;http://econym.googlepages.com/basic1.htm&quot; title=&quot;Lire le tutorial&quot; hreflang=&quot;en&quot;&gt;Markers and info windows&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les autres billets de cette série sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-10-api_google_maps_premieres_cartes&quot; title=&quot;Lire le billet&quot;&gt;API Google Maps : premières cartes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Maps API : marqueurs et fenêtres d&#039;informations&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : affichage des données d&#039;un fichier JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;/blog/2007-07-08-google_maps_api_geolocalisation_geocoding&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : géolocalisation (geocoding)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.numabilis.com/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : un marqueur déplaçable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-21-google_maps_api_gestionnaire_automatique_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire automatique de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Thu, 21 Jun 2007 19:27:09 +0200</pubDate>
</item>
<item>
 <title>API Google Maps : premières cartes</title>
 <link>http://www.numabilis.com/blog/2007-06-10-api_google_maps_premieres_cartes</link>
 <description>&lt;p&gt;Je me lance dans la découverte de l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt; et en profite pour rédiger une série de billets sur le sujet. Voici le premier tutoriel permettant de débuter dont la plupart des informations viennent de ce &lt;a href=&quot;http://econym.googlepages.com/index.htm&quot; title=&quot;Visiter la page du tutorial&quot; hreflang=&quot;en&quot;&gt;Google Maps API Tutorial&lt;/a&gt; de Mike Williams.&lt;/p&gt;

&lt;p&gt;Avant toute chose, il faut disposer d&#039;un &lt;a href=&quot;http://www.google.com/accounts/&quot; title=&quot;Créer un comte Google&quot; hreflang=&quot;fr&quot;&gt;compte Google&lt;/a&gt; car Google ne donne accès à son service qu&#039;à travers une clé d&#039;identification fournie aux seuls possesseurs de compte Google.&lt;/p&gt;

&lt;p&gt;Disposant d&#039;un compte Google, vous devez ensuite, &lt;a href=&quot;http://www.google.com/apis/maps/signup.html&quot; title=&quot;Allez sur la page de création de la clé&quot; hreflang=&quot;en&quot;&gt;générer la clé d&#039;identification&lt;/a&gt; valable pour une URL donnée (et toutes ses sous URL) et qui devra être communiquée à chaque requête. La validation du formulaire vous donne&amp;nbsp;:&lt;/p&gt;
&lt;p&gt;Une clé du genre&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;ABQIAAAA1x2klffHrefUjPpt9uu-YRSFwTc1YMYqORShagowwmhC3WCZJBTJ7YUSLR4rEGMAxpz2Jm54o0aACw
&lt;/div&gt;

&lt;p&gt;et le code d&#039;une page permettant de tester le service avec cette clé&amp;nbsp:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
  &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&amp;gt;
&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&amp;gt;
  &amp;lt;head&amp;gt;&lt;!li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/a&gt;&lt;/li&gt;
    &amp;lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;/&amp;gt;
    &amp;lt;title&amp;gt;Google Maps JavaScript API Example&amp;lt;/title&amp;gt;
    &amp;lt;script src=&quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=ABQIAAAA1x2klffHrefUjPpt9uu-YRSFwTc1YMYqORShagowwmhC3WCZJBTJ7YUSLR4rEGMAxpz2Jm54o0aACw&quot;
      type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;

    //&amp;lt;![CDATA[

    function load() {
      if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById(&quot;map&quot;));
        map.setCenter(new GLatLng(37.4419, -122.1419), 13);
      }
    }

    //]]&amp;gt;
    &amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body onload=&quot;load()&quot; onunload=&quot;GUnload()&quot;&amp;gt;
    &amp;lt;div id=&quot;map&quot; style=&quot;width: 500px; height: 300px&quot;&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/div&gt;

&lt;p&gt;Le résultat de cette page ressemble à cet &lt;a href=&quot;/files/demos/google-maps/exemple01.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;1&lt;/a&gt;. Le code source est assez limpide et simple à modifier pour centrer la carte sur la France avec un facteur de zoom adapté à la taille du &lt;tt&gt;div&lt;/tt&gt;. Pour cela il suffit de modifier la ligne suivante&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;        map.setCenter(new GLatLng(37.4419, -122.1419), 13);
&lt;/div&gt;
&lt;p&gt;en fournissant latitude, longitude et facteur de zoom voulus&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;        map.setCenter(new GLatLng(46.85, 1.75), 6);
&lt;/div&gt;
&lt;p&gt;J&#039;utilise aussi un &lt;tt&gt;div&lt;/tt&gt; de taille supérieure&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;div id=&quot;map&quot; style=&quot;width: 650px; height: 650px&quot;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/div&gt;
&lt;p&gt;Le résultat est visible sur l&#039;&lt;a href=&quot;/files/demos/google-maps/exemple02.html&quot; title=&quot;Voir la page d&#039;exemple&quot;&gt;exemple&amp;nbsp;2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Plus de détails sur &lt;a href=&quot;http://econym.googlepages.com/wizard.htm&quot; title=&quot;Lire le tutoriel de Mike Williams&quot; hreflang=&quot;en&quot;&gt;Instant maps with the Google Wizard&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les autres billets de cette série sur l&#039;&lt;a href=&quot;http://www.google.com/apis/maps/index.html&quot; title=&quot;Visiter le site de l&#039;API&quot; hreflang=&quot;en&quot;&gt;API Google Maps&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API Google Maps : premières cartes&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-06-21-google_maps_api_marqueurs_et_fenetres_dinformations&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : marqueurs et fenêtres d&#039;informations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-07-google_maps_api_affichage_des_donnees_dun_fichier_json&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : affichage des données d&#039;un fichier JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;/blog/2007-07-08-google_maps_api_geolocalisation_geocoding&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : géolocalisation (geocoding)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.numabilis.com/blog/2007-07-08-google_maps_api_un_marqueur_deplacable&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : un marqueur déplaçable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-07-08-google_maps_api_coordonnees_dun_marqueur&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : coordonnées d&#039;un marqueur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-20-google_maps_api_gestionnaire_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/2007-11-21-google_maps_api_gestionnaire_automatique_de_marqueurs&quot; title=&quot;Lire le billet&quot;&gt;Google Maps API : gestionnaire automatique de marqueurs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <category domain="http://www.numabilis.com/blog/Web-2.0">Web 2.0</category>
 <pubDate>Sun, 10 Jun 2007 15:08:59 +0200</pubDate>
</item>
<item>
 <title>Critères de choix d&#039;un framework PHP</title>
 <link>http://www.numabilis.com/blog/2007-05-30-criteres_de_choix_dun_framework_php</link>
 <description>&lt;p&gt;En tant que chef de projet dans une grosse structure, &lt;a href=&quot;/blog/2007-01-15-framework_php_mvc_pourquoi_sen_passer&quot; title=&quot;Lire le billet précédent&quot;&gt;justifiant son poste par sa capacité à résoudre les problèmes qu&#039;il a lui-même créés&lt;/a&gt;, vous êtes décidé à bâtir la prochaine application &lt;em&gt;corporate&lt;/em&gt; sur un &lt;em&gt;framework&lt;/em&gt; PHP. En plus des &lt;a href=&quot;/blog/2006-10-02-criteres_de_choix_dun_logiciel_libre&quot; title=&quot;Lire le billet sur les critères de choix d&#039;un logiciel (libre)&quot;&gt;critères de choix&lt;/a&gt; déjà évoqués, vous veillerez à la présence de fonctionnalités qui permettent aux développeurs de se concentrer sur les particularités de l&#039;application, en les libérant de l&#039;écriture des briques de base&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implémentation du &lt;em&gt;design pattern&lt;/em&gt; MVC&lt;/li&gt;
&lt;li&gt;Présence d&#039;un module de &lt;em&gt;logging&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Contrôle total sur les URLs&lt;/li&gt;
&lt;li&gt;Validation des formulaires&lt;/li&gt;
&lt;li&gt;Gestion des accès aux bases de données&lt;/li&gt;
&lt;li&gt;Implémentation de l&#039;&lt;a href=&quot;/blog/2006-10-09-inversion_de_controle_en_php_comment_ne_pas_limplementer&quot; title=&quot;Lire mon billet sur l&#039;implémentation IoC en PHP&quot;&gt;inversion de contrôle&lt;/a&gt; (IoC)&lt;/li&gt;
&lt;li&gt;Gestion de l&#039;internationalisation&lt;/li&gt;
&lt;li&gt;Système de caching&lt;/li&gt;
&lt;li&gt;Authentification et gestion des profils utilisateurs&lt;/li&gt;
&lt;li&gt;Gestion de la montée en charge&lt;/li&gt;
&lt;li&gt;Prise en compte de la sécurité (cross scripting, code injection, sql injection, vols de session, etc)&lt;/li&gt;
&lt;li&gt;Système de communication entre les modules&lt;/li&gt;
&lt;li&gt;Module Ajax&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&#039;examen d&#039;un certain nombre de &lt;em&gt;framework&lt;/em&gt; (&lt;a href=&quot;http://framework.zend.com/&quot; title=&quot;Visiter le site du framework Zend&quot;&gt;Zend Framework&lt;/a&gt;, &lt;a href=&quot;http://www.cakephp.org/&quot; title=&quot;Visiter le site du framework CakePHP&quot;&gt;CakePHP&lt;/a&gt;, &lt;a href=&quot;http://www.symfony-project.com/&quot; title=&quot;Visiter le site du framework Symfony&quot;&gt;Symfony Project&lt;/a&gt;, &lt;a href=&quot;http://seagull.phpkitchen.com/&quot; title=&quot;Visiter le site du framework Seagull&quot;&gt;Seagull Framework&lt;/a&gt;, &lt;a href=&quot;http://www.phpwact.org/&quot; title=&quot;Visiter le site du framework WACT&quot;&gt;WACT&lt;/a&gt;, &lt;a href=&quot;http://phpontrax.com/&quot; title=&quot;Visiter le site du framework PHP on TRAX&quot;&gt;PHP on TRAX&lt;/a&gt;, &lt;a href=&quot;http://zoopframework.com/&quot; title=&quot;Visiter le site du framework ZooP Framework&quot;&gt;ZooP Framework&lt;/a&gt;, &lt;a href=&quot;http://www.navphp.net/&quot; title=&quot;Visiter le site du framework Navigator&quot;&gt;Navigator&lt;/a&gt;, &lt;a href=&quot;http://www.codeigniter.com/&quot; title=&quot;Visiter le site du framework CodeIgniter&quot;&gt;CodeIgniter&lt;/a&gt;) montre que se sont surtout des usines à gaz. Seul &lt;a href=&quot;http://www.codeigniter.com/&quot; title=&quot;Visiter le site du framework CodeIgniter&quot;&gt;CodeIgniter&lt;/a&gt; sort du lot&amp;nbsp;: il est très léger grâce aux modules indépendants, qui ne sont chargés qu&#039;à la demande du contrôleur, mais il a le défaut de la rigidité des URLs. LE &lt;em&gt;framework&lt;/em&gt; MVC est donc plus une collection de composants utilisables au sein d&#039;un micro container. C&#039;est la démarche de &lt;a href=&quot;http://www.codeigniter.com/&quot; title=&quot;Visiter le site du framework CodeIgniter&quot;&gt;CodeIgniter&lt;/a&gt; et de &lt;a href=&quot;http://framework.zend.com/&quot; title=&quot;Visiter le site du framework Zend&quot;&gt;Zend Framework&lt;/a&gt;, bien que ce dernier soit un peu plus complexe.&lt;/p&gt;
&lt;p&gt;L&#039;utilisation d&#039;un &lt;em&gt;framework&lt;/em&gt; nécessite toujours un investissement pour former les développeurs. Cet investissement sera d&#039;autant plus important que le &lt;em&gt;framework&lt;/em&gt; sera complexe. Cette complexité entrainera également des frais plus élevé de maintenance et d&#039;évolution. Dans bien des cas, cet investissement est beaucoup plus rentable s&#039;il est effectué dans le développement d&#039;un micro-noyau maison...&lt;/p&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/Maitrise-d-oeuvre">Maîtrise d&#039;œuvre</category>
 <category domain="http://www.numabilis.com/blog/PHP">PHP</category>
 <pubDate>Wed, 30 May 2007 19:27:58 +0200</pubDate>
</item>
<item>
 <title>Framework PHP MVC : pourquoi s&#039;en passer</title>
 <link>http://www.numabilis.com/blog/2007-01-15-framework_php_mvc_pourquoi_sen_passer</link>
 <description>&lt;p&gt;Beaucoup plus populaire que les &lt;a href=&quot;/blog/2006-10-09-inversion_de_controle_en_php_comment_ne_pas_limplementer&quot; title=&quot;Lire mon pr&amp;eacute;c&amp;eacute;dent billet sur l&#039;impl&amp;eacute;mentation de IoC en PHP&quot;&gt;conteneurs impl&amp;eacute;mentant l&#039;inversion de contr&amp;ocirc;le&lt;/a&gt;, les &lt;em&gt;frameworks&lt;/em&gt; &lt;a href=&quot;http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html&quot; title=&quot;Lire les articles originaux d&amp;eacute;crivant ce design pattern&quot; hreflang=&quot;en&quot;&gt;MVC&lt;/a&gt; (Model-View-Controller ou Mod&amp;egrave;le-Vue-Contr&amp;ocirc;leur) en PHP sont l&amp;eacute;gion. Ils participent de cette attente irrationnelle du monde PHP envers la programmation orient&amp;eacute;e objet et son corollaire, le &lt;a href=&quot;http://fr.wikipedia.org/wiki/Cadre_d%27applications&quot; title=&quot;Lire l&#039;article Framework sur Wikip&amp;eacute;dia&quot; hreflang=&quot;fr&quot;&gt;&lt;em&gt;framework&lt;/em&gt;&lt;/a&gt;. Seul &lt;a href=&quot;http://fr.wikipedia.org/wiki/Rasmus_Lerdorf&quot; title=&quot;Lire la biographie de l&#039;inventeur de PHP sur Wikip&amp;eacute;dia&quot; hreflang=&quot;fr&quot;&gt;Rasmus &lt;span class=&quot;np&quot;&gt;Lerdorf&lt;/span&gt;&lt;/a&gt; semble percevoir le comique de la situation avec son &lt;a href=&quot;http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html&quot; title=&quot;Lire l&#039;article d&amp;eacute;crivant ce framework.&quot; hreflang=&quot;en&quot;&gt;&lt;em&gt;no-framework PHP MVC framework&lt;/em&gt;&lt;/a&gt;. Avant de vous d&amp;eacute;cidez de d&amp;eacute;marrer votre prochain projet avec un tel &lt;em&gt;framework&lt;/em&gt;, consid&amp;eacute;rez d&#039;abord les inconv&amp;eacute;nients suivants&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Une application moins performante.&lt;/strong&gt; Les diverses couches d&#039;abstraction et la panoplie impressionnante de composants accompagnant tout &lt;em&gt;framework&lt;/em&gt; en font un m&amp;eacute;canisme lourd, consommant beaucoup de ressources mat&amp;eacute;rielles. La mise en production peut alors s&#039;accompagner de l&#039;achat, en urgence, d&#039;un syst&amp;egrave;me de cache performant pour rem&amp;eacute;dier aux performance d&amp;eacute;plorables. Rappelons-nous des &lt;a href=&quot;http://fr.wikipedia.org/wiki/G%C3%A9oportail#Difficult.C3.A9s_de_lancement&quot; title=&quot;Lire la description que donne Wikip&amp;eacute;dia du lancement du G&amp;eacute;oPortail&quot; hreflang=&quot;fr&quot;&gt;difficult&amp;eacute;s de lancement&lt;/a&gt; du &lt;a href=&quot;http://www.geoportail.fr/&quot; title=&quot;visiter le site du G&amp;eacute;oPortail&quot; hreflang=&quot;fr&quot;&gt;G&amp;eacute;oPortail&lt;/a&gt; ou plus r&amp;eacute;cemment les &lt;a href=&quot;http://ljouanneau.com/blog/2007/01/03/626-prix-carburants-avec-copix&quot; title=&quot;Lire le billet de Laurent Jouanneau sur ce sujet&quot; hreflang=&quot;fr&quot;&gt;d&amp;eacute;buts difficiles&lt;/a&gt; du &lt;a hef=&quot;http://www.prix-carburants.gouv.fr/&quot; title=&quot;Aller sur le site du comparateur de prix des carburants&quot; hreflang=&quot;fr&quot;&gt;comparateur de prix des carburants&lt;/a&gt; du &lt;a href=&quot;http://www.minefi.gouv.fr/&quot; title=&quot;Aller sur le site du Minist&amp;egrave;re de l&#039;&amp;Eacute;conomie, des finances et de l&#039;industrie&quot; hreflang=&quot;fr&quot;&gt;Minefi&lt;/a&gt;.
&lt;li&gt;&lt;strong&gt;Co&amp;ucirc;t de d&amp;eacute;veloppement accrus.&lt;/strong&gt; La complexit&amp;eacute; du framework induit des salaires plus &amp;eacute;lev&amp;eacute;s pour les d&amp;eacute;veloppeurs sp&amp;eacute;cialis&amp;eacute;s en raison de leur raret&amp;eacute; ou des frais de formation (ou de perte de productivit&amp;eacute;) pour les autres d&amp;eacute;veloppeurs. Ajoutez les frais de formation &amp;agrave; un nouveau langage de script si le &lt;em&gt;framework&lt;/em&gt; s&#039;appuie sur un moteur de template style &lt;a href=&quot;http://smarty.php.net/&quot; title=&quot;Visiter le site de Smarty&quot; hreflang=&quot;en&quot;&gt;Smarty&lt;/a&gt;, tr&amp;egrave;s &amp;agrave; la mode chez les d&amp;eacute;veloppeurs PHP. Ces moteurs n&#039;ont aucune utilit&amp;eacute; (si ce n&#039;est de complexifier le d&amp;eacute;veloppement) comme le montre bien l&#039;article &lt;a href=&quot;http://www.digital-web.com/articles/php_for_designers/&quot; title=&quot;Lire l&#039;article PHP for designers&quot;&gt;PHP for designers&lt;/a&gt; de &lt;a href=&quot;http://photomatt.net/&quot; title=&quot;Visiter le site de Matt Mullenweg&quot;&gt;Matt Mullenweg&lt;/a&gt; (co-fondateur et d&amp;eacute;veloppeur principal de &lt;a href=&quot;http://wordpress.com/&quot; title=&quot;Visiter le site de Wordpress&quot;&gt;WordPress&lt;/a&gt;). Seule compte la &lt;a href=&quot;/blog/2006-10-16-au_dela_de_mvc_2&quot; title=&quot;Lire mon pr&amp;eacute;c&amp;eacute;dent billet sur MVC et la s&amp;eacute;paration des pr&amp;eacute;occupations&quot;&gt;s&amp;eacute;paration des pr&amp;eacute;occupations&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Une application brid&amp;eacute;e.&lt;/strong&gt; Une autre cons&amp;eacute;quence de la complexit&amp;eacute; d&#039;un &lt;em&gt;framework&lt;/em&gt; est la difficult&amp;eacute; de l&#039;&amp;eacute;tendre ou de l&#039;adapter &amp;agrave; ses besoins particuliers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Une application ne r&amp;eacute;pondant pas aux besoins des utilisateurs.&lt;/strong&gt; La plupart des &lt;em&gt;framework&lt;/em&gt; font des choix radicaux en termes de conception gr&amp;eacute;vant les fonctionnalit&amp;eacute;s de l&#039;application. L&#039;exemple le plus simple&amp;nbsp;: l&#039;&lt;em&gt;URL rewriting&lt;/em&gt;. L&#039;URL d&#039;une page est g&amp;eacute;n&amp;eacute;ralement de la forme &lt;code&gt;http://my.web.com/module/action/params&lt;/code&gt; pour invoquer l&#039;action &lt;code&gt;action&lt;/code&gt; du module &lt;code&gt;module&lt;/code&gt;. Aussi lorsque l&#039;on souhaite cr&amp;eacute;er un site web dont les URLs repr&amp;eacute;sentent l&#039;architecture fonctionnelle du site, cela s&#039;av&amp;egrave;re tr&amp;egrave;s compliqu&amp;eacute;&amp;nbsp;! Ainsi au lieu d&#039;avoir l&#039;URL &lt;code&gt;http://www.numabilis.com/services/realisation_de_sites_web&lt;/code&gt; on a quelque chose comme &lt;code&gt;http://www.numabilis.com/article/view/id/35&lt;/code&gt;. Le module de r&amp;eacute;&amp;eacute;criture fourni est g&amp;eacute;n&amp;eacute;ralement insuffisant&amp;nbsp;: les sections &lt;em&gt;Services&lt;/em&gt; et &lt;em&gt;R&amp;eacute;alisations&lt;/em&gt; &amp;eacute;tant toutes deux constitu&amp;eacute;es d&#039;articles, la r&amp;eacute;&amp;eacute;criture ne permet pas de distingu&amp;eacute;s les articles de ces deux sections&amp;nbsp;! Comme souvent &lt;strong&gt;les couches techniques imposent des contraintes fortes sur le fonctionnel&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les &lt;em&gt;frameworks&lt;/em&gt; PHP, dans leur tr&amp;egrave;s grande majorit&amp;eacute;, souffrent d&#039;une trop grande complexit&amp;eacute;. Ils singent le monde Java (voir les impl&amp;eacute;mentations PHP de Struts&amp;nbsp;: &lt;a href=&quot;https://www.phrame.org/&quot; title=&quot;Visiter le site du framework Phrame&quot;&gt;Phrame&lt;/a&gt;, &lt;a href=&quot;http://www.phpmvc.net/&quot; title=&quot;Visiter le site du framework PhpMVC&quot;&gt;PhpMVC&lt;/a&gt; ou &lt;a href=&quot;http://www.mojavelinux.com/projects/studs/&quot; title=&quot;Visiter le site du framework Studs&quot;&gt;Studs&lt;/a&gt;) en faisant du &lt;strong&gt;tout objet&lt;/strong&gt; avec force renfort de &lt;a href=&quot;http://en.wikipedia.org/wiki/Template_engine&quot; title=&quot;Lire l&#039;article sur template engine sur Wikip&amp;eacute;dia&quot; hreflang=&quot;en&quot;&gt;&lt;em&gt;template engine&lt;/em&gt;&lt;/a&gt; et de &lt;a href=&quot;http://www.modrewrite.com/&quot; title=&quot;Visiter le site du module apache mod_rewrite&quot; hreflang=&quot;en&quot;&gt;&lt;em&gt;mod_rewrite&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Par cons&amp;eacute;quent, sauf si vous &amp;ecirc;tes chef de projet dans une grosse structure, dont le poste n&#039;est justifi&amp;eacute; que par votre capacit&amp;eacute; &amp;agrave; r&amp;eacute;soudre les probl&amp;egrave;mes que vous avez vous m&amp;ecirc;me cr&amp;eacute;&amp;eacute;s, vous devriez vous passer d&#039;un tel &lt;em&gt;framework&lt;/em&gt;.&lt;/p&gt;
&lt;center&gt;&lt;br&gt;&lt;a href=&quot;http://blaugh.com/2006/09/20/veni-vidi-wiki/&quot; title=&quot;Voir le billet original&quot;&gt;&lt;img title=&quot;Veni Vidi Wiki&quot; alt=&quot;Dessin humoristique Veni Vidi Wiki&quot; src=&quot;/files/pictures/blaugh_060920_dyslexic_wiki_kiwi.gif&quot; height=&quot;250&quot; width=&quot;447&quot;&gt;&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;http://blaugh.com/2006/09/20/veni-vidi-wiki/&quot; hreflang=&quot;en&quot; title=&quot;Voir le billet original&quot;&gt;Veni Vidi Wiki&lt;/a&gt; (dessin de &lt;a href=&quot;http://bradfitzpatrick.com/weblog/&quot; title=&quot;Visiter le blog de Brad Fitzpatrick&quot; hreflang=&quot;en&quot;&gt;Brad Fitzpatrick&lt;/a&gt;)&lt;/center&gt;
&lt;div style=&quot;visibility: hidden&quot;&gt;
&lt;a href=&quot;http://www.technorati.com/claim/a744kfxee&quot; rel=&quot;me&quot;&gt;Technorati Profile&lt;/a&gt;
&lt;/div&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/Maitrise-d-oeuvre">Maîtrise d&#039;œuvre</category>
 <category domain="http://www.numabilis.com/blog/PHP">PHP</category>
 <pubDate>Mon, 15 Jan 2007 21:41:56 +0100</pubDate>
</item>
<item>
 <title>Héritage en JavaScript</title>
 <link>http://www.numabilis.com/blog/2006-12-12-heritage_en_javascript</link>
 <description>&lt;p&gt;Comment faire hériter une &lt;em&gt;classe&lt;/em&gt; &lt;code&gt;Book&lt;/code&gt; d&#039;une &lt;em&gt;classe&lt;/em&gt; &lt;code&gt;Item&lt;/code&gt; en JavaScript&amp;nbsp;?&lt;/p&gt;
&lt;p&gt;La classe &lt;code&gt;Item&lt;/code&gt; possède deux propriétés (&lt;code&gt;id&lt;/code&gt; et &lt;code&gt;price&lt;/code&gt;), deux méthodes pour lire ces propriétés (&lt;code&gt;getId&lt;/code&gt; et &lt;code&gt;getPrice&lt;/code&gt;) et une méthode pour obtenir une représentation de l&#039;objet sous forme d&#039;une chaîne de caractères (&lt;code&gt;toString&lt;/code&gt;)&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;function Item(id, price) {
  this.id = id;
  this.price = price;
}
Item.prototype.getId = function() {
  return this.id;
}
Item.prototype.getPrice = function() {
  return this.price;
}
Item.prototype.toString = function() {
  return &quot;Item[id=&quot;+this.getId()+&quot;,price=&quot;+this.getPrice()+&quot;]&quot;;
}&lt;/div&gt;
&lt;p&gt;Une méthode classique d&#039;&lt;a href=&quot;http://www.aidejavascript.com/article68.html &quot; title=&quot;Lire l&#039;article décrivant en détail cette méthode&quot; hreflang=&quot;fr&quot;&gt;héritage en Javascript&lt;/a&gt; est dite par prototypage&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;Book.prototype = new Item;
function Book(id, price, title) {
  this.super = Item;
  this.super(id, price);
  this.title = title;
}
Book.prototype.getTitle = function() {
  return this.title;
}
Book.prototype.toString = function() {
  return &quot;Book[id=&quot;+this.getId()+&quot;,price=&quot;+this.getPrice()+&quot;,title=&quot;+this.getTitle()+&quot;]&quot;;
}
&lt;/div&gt;
&lt;p&gt;Ainsi, le code suivant&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;var myBook = new Book(1001, 10.5, &quot;The definitive JS Guide&quot;);
alert(myBook);
&lt;/div&gt;
&lt;p&gt;provoquera l&#039;affichage de la chaîne de caractères&amp;nbsp: &lt;code&gt;Book[id=1001,price=10.5,title=The definitive JS Guide]&lt;/code&gt;. Parfait&amp;nbsp;! Mais l&#039;article de Douglas Crockford intitulé &lt;a href=&quot; http://javascript.crockford.com/prototypal.html&quot; title=&quot;Lire l&#039;article&quot; hreflang=&quot;en&quot;&gt;Prototypal Inheritance in JavaScript&lt;/a&gt; m&#039;a inspiré une autre méthode pour définir de manière automatique et dynamique la fonction &lt;code&gt;Book&lt;/code&gt;. Pour cela on écrit une fonction &lt;code&gt;inherit&lt;/code&gt; prenant la &lt;em&gt;classe&lt;/em&gt; de base en paramètre et renvoyant la fonction définissant la &lt;em&gt;sous-classe&lt;/em&gt;. Cette fonction&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Détermine le nombre et le noms des arguments du constructeur de la &lt;em&gt;classe&lt;/em&gt; de base (&lt;code&gt;args&lt;/code&gt;) par un mécanisme mimant l&#039;introspection,&lt;/li&gt;
&lt;li&gt;Construit une chaîne de caractère (&lt;code&gt;str&lt;/code&gt;) dont l&#039;évaluation définira la fonction faisant appel au constructeur de la &lt;em&gt;classe&lt;/em&gt; de base avec les bons paramètres.&lt;/li&gt;
&lt;li&gt;Copie tous les attributs et toutes les fonctions de la &lt;em&gt;classe&lt;/em&gt; de base dans la &lt;em&gt;classe&lt;/em&gt; dérivée.&lt;/li&gt;
&lt;li&gt;Retourne la fonction&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;code&quot;&gt;function inherit(super) {
  var introspect = &#039;&#039; + super;
  introspect = introspect.substring (introspect.indexOf(&#039;(&#039;)+1);
  introspect = introspect.substring(0, introspect.indexOf(&#039;)&#039;));
  var args = introspect.explode(&#039;,&#039;);

  var str = &quot;new Function(&quot;;
  for(var i = 0; i &lt; args.length ; i++) {
    str += &quot;\&quot;&quot;+args[i]+&quot;\&quot;, &quot;;
  }
  str += &quot;\&quot;this.super=\&quot;+super+\&quot;;this.super(&quot;;
  for(var i = 0; i &lt; args.length; i++) {
    str += &quot;&quot;+args[i];
    if(i &lt; args.length-1) {
      str += &quot;, &quot;;
    }
  }
  str += &quot;);\&quot;);&quot;;
  F = eval(str);
  for (property in super) {
    F[property] = super[property];
  }

  return F;
}
&lt;/div&gt;
&lt;p&gt;Ce code s&#039;appuie sur les extensions &lt;code&gt;trim&lt;/code&gt; et &lt;code&gt;explode&lt;/code&gt; apportées à l&#039;objet &lt;code&gt;String&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;String.prototype.trim = function() {
  return this.replace(/(^\s*)|(\s*$)/g,&#039;&#039;);
}

String.prototype.explode = function(delim) {
  var exploded = new Array();
  var copy = this;
  var i = copy.indexOf(delim);
  while(i&gt;0) {
    extracted = copy.substring(0, i);
    copy = copy.substring(i+1);
    exploded.push (extracted.trim());
    i = copy.indexOf(delim);
  }
  exploded.push(copy.trim());

  return exploded;
}
&lt;/div&gt;
&lt;p&gt;Le constructeur étant défini automatiquement, on ne peut pas lui ajouter des paramètres spécifiques à la &lt;em&gt;sous-classe&lt;/em&gt; (&lt;code&gt;title&lt;/code&gt; par exemple). L&#039;initialisation de l&#039;objet dérivé doit donc se terminer à l&#039;extérieur du constructeur&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;Book = inherit(Item);
Book.prototype.title = &quot;&quot;;
Book.prototype.getTitle = function() {
  return this.title;
}
Book.prototype.toString = function() {
  return &quot;Book[id=&quot;+this.getId()+&quot;,price=&quot;+this.getPrice()+&quot;,title=&quot;+this.getTitle()+&quot;]&quot;;
}
&lt;/div&gt;
&lt;p&gt;Le code suivant&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;var myBook = new Book(1001, 10.5);
myBook.title = &quot;The definitive JS Guide&quot;;
alert(myBook);
&lt;/div&gt;
&lt;p&gt;provoquera l&#039;affichage de la chaîne de caractères&amp;nbsp: &lt;code&gt;Book[id=1001,price=10.5,title=The definitive JS Guide]&lt;/code&gt; comme précédemment.&lt;/p&gt;
&lt;p&gt;Il serait possible d&#039;étendre ce mécanisme en ajoutant des paramètres à la fonction &lt;code&gt;inherit&lt;/code&gt; afin d&#039;avoir un constructeur prenant plus de paramètres que le constructeur de base. Un des paramètres serait un bout de code à exécuter pour finir l&#039;initialisation de l&#039;objet dérivé. Mais cela aurait-il un intérêt&amp;nbsp;?&lt;/p&gt;
&lt;p&gt;Si l&#039;on met de côté le fait que la définition de fonction à l&#039;aide de la fonction &lt;code&gt;Function&lt;/code&gt; et l&#039;utilisation de la fonction &lt;code&gt;eval&lt;/code&gt; sont fortement déconseillées, cette méthode est amusante, non&amp;nbsp;?&lt;/p&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/JavaScript">JavaScript</category>
 <pubDate>Tue, 12 Dec 2006 21:54:41 +0100</pubDate>
</item>
<item>
 <title>Au-delà de MVC(2)</title>
 <link>http://www.numabilis.com/blog/2006-10-16-au_dela_de_mvc_2</link>
 <description>&lt;p&gt;
Le &lt;em&gt;design pattern&lt;/em&gt; &lt;a href=&quot;http://www.andywardley.com/computers/web/mvc.html&quot; title=&quot;Lire l&#039;article d&#039;Andy Wardley sur MVC&quot; hreflang=&quot;en&quot;&gt;MVC&lt;/a&gt; est très à la mode dans le monde PHP. Beaucoup d&#039;articles le présentent, mais peu en font comprendre l&#039;essence. Ils passent généralement à côté de l&#039;essentiel : la &lt;strong&gt;séparation des préoccupations&lt;/strong&gt;.
&lt;center&gt;
&lt;a href=&quot;http://flickr.com/photos/dotpolka/83025846/in/photostream&quot; title=&quot;what happened here? photo de dotpolka sur flickr&quot;&gt;&lt;img src=&quot;/files/pictures/police_line_do_not_cross.jpg&quot; alt=&quot;&quot;/&gt;&lt;/a&gt;
&lt;br /&gt;&lt;strong&gt;MVC&amp;nbsp;: la séparation des préoccupations&lt;/strong&gt;
&lt;/center&gt;
&lt;/p&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/PHP">PHP</category>
 <pubDate>Mon, 16 Oct 2006 17:19:31 +0200</pubDate>
</item>
<item>
 <title>Inversion de contrôle en PHP : comment ne pas l&#039;implémenter</title>
 <link>http://www.numabilis.com/blog/2006-10-09-inversion_de_controle_en_php_comment_ne_pas_limplementer</link>
 <description>&lt;div class=&quot;portfolio&quot;&gt;&lt;a href=&quot;http://www.sxc.hu/photo/460791/&quot; title=&quot;Voir la présentation de l&#039;image&quot;&gt;&lt;img width=&quot;105&quot; height=&quot;79&quot; src=&quot;/files/pictures/ioc_remote_control.png&quot; alt=&quot;&quot; class=&quot;portfolio&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;
L&#039;&lt;a href=&quot;http://fr.wikipedia.org/wiki/Inversion_de_contr%C3%B4le&quot; title=&quot;Lire l&#039;article Inversion de contrôle sur Wikipédia&quot; hreflang=&quot;fr&quot;&gt;inversion de contrôle&lt;/a&gt; (&lt;a href=&quot;http://www.martinfowler.com/articles/injection.html&quot; title=&quot;Lire l&#039;article de Martin Fowler&quot; hreflang=&quot;en&quot;&gt;&lt;em&gt;Inversion of Control&lt;/em&gt;&lt;/a&gt;, &lt;em&gt;IoC&lt;/em&gt;) est un &lt;a href=&quot;http://fr.wikipedia.org/wiki/Motif_de_conception&quot; title=&quot;Lire l&#039;article Motif de conception sur Wikipédia&quot; hreflang=&quot;fr&quot;&gt;motif de conception&lt;/a&gt; (&lt;em&gt;design pattern&lt;/em&gt;) devenu populaire, ces dernières années, avec l&#039;adoption des conteneurs légers comme &lt;a href=&quot;http://www.springframework.org&quot; title=&quot;Visiter le site de SpringFramework&quot; hreflang=&quot;en&quot;&gt;SpringFramework&lt;/a&gt;. Entendant leurs mérites tant vantés par les développeurs Java, des adeptes de PHP se sont fait un devoir d&#039;implémenter un tel conteneur dans leur langage de prédilection. On trouve ainsi&amp;nbsp;: &lt;a href=&quot;http://drip.tigris.org/&quot; title=&quot;Visiter le site du projet Drip&quot; hreflang=&quot;en&quot;&gt;Drip&lt;/a&gt;, &lt;a href=&quot;http://garden.tigris.org/&quot; title=&quot;Visiter le site du projet Garden&quot; hreflang=&quot;en&quot;&gt;Garden&lt;/a&gt;, &lt;a href=&quot;http://solarphp.com/index.php/docs/read/Solar/dependency()&quot; title=&quot;Visiter la page IoC du projet Solar&quot; hreflang=&quot;en&quot;&gt;Solar&lt;/a&gt;, &lt;a href=&quot;http://sourceforge.net/projects/phemto/&quot; title=&quot;Visiter le site du projet Phemto&quot; hreflang=&quot;en&quot;&gt;Phemto&lt;/a&gt;, &lt;a href=&quot;http://www.seasar.org/en/&quot; title=&quot;Visiter le site du projet Seasar&quot; hreflang=&quot;en&quot;&gt;Seasar&lt;/a&gt;, &lt;a href=&quot;http://garden.clawphp.org/&quot; title=&quot;Visiter le site du projet ClawPHP&quot; hreflang=&quot;en&quot;&gt;ClawPHP&lt;/a&gt; et même &lt;a href=&quot;http://www.phpwact.org/roadmap#modularization_and_dependency_injection_support&quot; title=&quot;Visiter la page évoquant l&#039;IoC du projet WACT&quot; hreflang=&quot;en&quot;&gt;WACT&lt;/a&gt;. C&#039;est à mon avis alourdir considérablement le développement pour faire quelque chose que PHP sait faire naturellement. Je vous propose donc de &lt;strong&gt;découvrir ce qu&#039;est l&#039;inversion de controle et comment la mettre en place en PHP sans même l&#039;implémenter concrètement.&lt;/strong&gt;
&lt;/p&gt;
</description>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/PHP">PHP</category>
 <pubDate>Mon, 09 Oct 2006 00:29:59 +0200</pubDate>
</item>
<item>
 <title>Mise en cache d&#039;applet (applet caching)</title>
 <link>http://www.numabilis.com/blog/2006-09-29-mise_en_cache_dapplet_applet_caching</link>
 <description>&lt;p&gt;&amp;laquo;&amp;nbsp;&lt;em&gt;Que c&#039;est lent&amp;nbsp;!&lt;/em&gt;&amp;nbsp;&amp;raquo; C&#039;est vrai que le chargement d&#039;applet java peut prendre beaucoup de temps. Ce temps de chargement dépend de la taille du code principal (typiquement le .jar constituant l&#039;applet) mais aussi des librairies dont elle dépend et qui sont téléchargées à chaque appel de la page. Au dela de deux seconde, l&#039;utilisateur s&#039;impatiente. Ce billet explique comment éviter le chargement des applet à chaque appel de la page.&lt;/p&gt;
&lt;p&gt;Il existe deux solutions : &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/guide/extensions/&quot; title=&quot;Lire la documentation officielle&quot; hreflang=&quot;en&quot;&gt;le mécanisme des extensions Java&lt;/a&gt; et la &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/guide/plugin/developer_guide/applet_caching.html&quot; title=&quot;Lire la documentation officielle&quot; hreflang=&quot;en&quot;&gt;mise en cache des applets&lt;/a&gt;. Les extensions sont des jar définis comme tels dans le manifest du jar de l&#039;applet, indiquant à la JVM que ces jar sont nécessaires à l&#039;exécution de l&#039;applet. La JVM les télécharge et les stocke dans le répertoire &lt;code&gt;lib/ext&lt;/code&gt; du JRE et en charge les classes via le ClassLoader de plus haut niveau. Si une version plus récente du jar est disponible, la JVM se chargera de le télécharger pour remplacer le précedent. Bien que cela soit assez simple à mettre en oeuvre, cette technoloqie présente des inconvénients&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Des conflits peuvent apparaître entre des applets utilisant différentes version d&#039;une même librairie tierce (une version 1.1 téléchargée depuis le site de la première applet et une version 1.2 téléchargée depuis le site de la seconde applet).&lt;/li&gt;
&lt;li&gt;Si une librairie fait appel à des librairies natives, des conflits encore pus aigüs peuvent se révéler...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le mécanisme de mise en cache des applet est tout aussi simple et pose beaucoup moins de problème car les jars sont téléchargés via un ClassLoader spécifique à chaque applet. Il suffit d&#039;ajouter les paramètres suivants dans la balise object&amp;nbsp;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;object ...&amp;gt;
  &amp;lt;param name=&quot;archive&quot; value=&quot;...&quot; /&amp;gt;
  ...
  &amp;lt;param name=&quot;cache_option&quot; value=&quot;...&quot; /&amp;gt;
  &amp;lt;param name=&quot;cache_archive&quot; value=&quot;...&quot; /&amp;gt;
  &amp;lt;param name=&quot;cache_version&quot; value=&quot;...&quot; /&amp;gt;
&amp;lt;/object&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cache_option&lt;/code&gt; indique le mécanisme à utiliser pour gérer le cache (&quot;&lt;code&gt;No&lt;/code&gt;&quot;, &quot;&lt;code&gt;Browser&lt;/code&gt;&quot; ou &quot;&lt;code&gt;Plugin&lt;/code&gt;&quot;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cache_archive&lt;/code&gt; contient la liste des jar à mettre en cache&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cache_version&lt;/code&gt; est un paramètre optionnel permettant de gérer les versions des jar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&#039;&lt;a href=&quot;/files/demos/applet-object-embed/exemple-5.0.html&quot; title=&quot;Exécuter l&#039;exemple&quot;&gt;exemple 5&lt;/a&gt; reprend l&#039;ensemble des techniques décrites dans cette série de billets&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;blog/2006-08-28-les_commentaires_conditionnels_dinternet_explorer&quot; title=&quot;Lire le billet&quot;&gt;IE et les commentaires conditionnels&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;blog/2006-09-05-applet_object_ou_embed&quot; title=&quot;Lire le billet&quot;&gt;Applet, Object ou Embed ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;blog/2006-09-13-applet_installation_automatique_de_la_jvm&quot; title=&quot;Lire le billet&quot;&gt;Applet : installation automatique de la JVM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;blog/2006-09-21-internet_explorer_et_java_activation_automatique_des_applets&quot; title=&quot;Lire le billet&quot;&gt;Internet Explorer et Java : activation automatique des applets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
 <category domain="http://www.numabilis.com/blog/HTML">HTML</category>
 <category domain="http://www.numabilis.com/blog/Ingenierie-web">Ingénierie web</category>
 <category domain="http://www.numabilis.com/blog/Java">Java</category>
 <pubDate>Fri, 29 Sep 2006 14:12:29 +0200</pubDate>
</item>
</channel>
</rss>
