Keyword - Ajax

Entries feed - Comments feed

Sunday, March 16 2008

Amazon Web Services with PHP5 and jQuery

Back in 1999 I used to wrote some scripts using ASP and Javascript in order to automagicaly display books related to the topics of my articles. Nowadays this task is quite simple using Amazon's API. There is no more cache problems with outdated prices or products availability. I created an account on AWS and Amazon affiliates and started to code a set of scripts using Amazon's API for education purpose.


I came up with a nice search engine that is unfortunately not working with Internet Explorer. The script is far from perfect but, since I find it interesting I put it on my Workshop for all you to see and comment.


If you have any lead that can help me to make it functional in Internet Explorer your feedback will be gladly welcomed!

I finaly managed to get it functional in IE!



Monday, March 3 2008

Moteur de template Javascript, comparaison et benchmark

Comme déjà exprimé plus tôt j'ai longtemps souhaité déplacer mon code XHTML et CSS en dehors de mes librairies Javascript. J'ai donc récement entendu parler des moteurs de templates Javascript. Seule ou plugin de framework existant, ces outils sont la prochiane étape pour les developpeurs web.

Je ne parlerai que de trois d'entre eux :

J'ai choisis ceux là pour la simple raison qu'il correspondent tous a mes besoins en termes de traitement de données hiérarchisées JSON sous forme princiapelement de tableau. J'ai écrit ce benchmark pour ma propre information. comme je l'ai trouvé interressant j'ai décidé de le publier

Les résultats mis en évidence par ce script de mesure des performances ne sont pas conçut pour aider quiconque à choisir le "meilleur" moteur de templates, soyez conscient que la vitesse d'execution n'est pas la seul et encore moins le plus important des critères a prendre en compte dans le choix optimal d'un systeme de template pour votre application.
Cependant, si la vitesse et les performances globales sont importante pour votre projet, ce test pourra peut-être vous être utile.

Notez biens que ce script tourne entièrement  côté client, les résultats seront donc uniquement valide sur votre machine et a fortiori seront affectés par les programmes s'executant au moment du test. Ah oui, j'allais oublier, ces tests de performances ne fonctionnent pas sous internet explorer.

Le benchmark :
Ce script va executer les différente méthodes de transformation des librairies citées en introduction le même nombre de fois. Il va mesurer le temps d'execution pour chacune d'entre elle et les stockera afin d'afficher un graphique généré par un plugin jQuery nommé flot (http://code.google.com/p/flot/) de l'intégralité de l'execution ainsi qu'un résumé. Pour eviter tout gel de votre navigateur, les données JSON seront découpées et traitées par lot. Vous pourrez configurer combien de données devront être traitées ainsi que la taille des lots.

Pour finir, si vous constatez un quelconque illogisme dans les résultats, merci de me contacter !

Javascript template engines benchmarking






Javascript Template Engines comparison and benchmark

For a long time i wished to have the ability to move my XHTML or CSS  code/formatting out of my javascript libraries.  I lately heard about  javascript templates engines. Either standalone or plugged into existing frameworks these tools are the next step for web developpers.

I will only speak about tree of them :


Basicaly I choosed them because they have the functionality to process hierachical JSON data input, mainly arrays and evolved syntax. I originally wrote this benchmark script for my own knowledge, since i found it interresting i decided to release it to the public.

The results shown by the benchmark tool are not intended to guide anyone in choosing the "best" template engine, be aware that speed is not the only and further less the most important criteria in the process of choosing the right template engine for your application. However, it can help if the speed and overall performance is an important issue at some point.

Note that since the benchmark itself runs on client side, results shown will only be true on your computer and are heavily dependents of its load at the time your are running the test. Oh, a trivial thing, this benchmark is not running at all with internet explorer.

The benchmark:
This script, will run the different template transformation methods from the librairies the same amount of time for each. It will time every call to these method and stock them into an array. This array will then be processed to display plots using a jQuery plugin named flot (http://code.google.com/p/flot/) and summary informations about each of the tree mentioned librairies. To let the control to the browser, the data (JSON) will be splitted into small chunks. You can configure how much data is processed and the chunk's size.

As a last note, I would be glad if you contact me if you notice any discrepancy in the benchmark results.

Javascript template engines benchmarking






Wednesday, February 27 2008

jQuery et jTemplates

jTemplate (http://jtemplates.tpython.com) est un plugin pour jQuery (http://jquery.com/). Il ajoute la merveilleuse fonctionnalité qu'est le templating à la librairie jQuery. J'avais longtemps souhaiter cela ! C'est chose faite à présent et c'est à la fois extrêmement pratique et puissant.

Les développeurs, par soucis de relecture et maintenance, cherchent à dissocier au maximum le contenu de la partie code. Appliqué à PHP, Smarty (http://www.smarty.net/) fût une véritable révolution lors de sa sortie en 2003.  Aujourd'hui des dixaines de milliers de développeurs l'utilisent quotidiennement dans des projets de grande envergure.

Si vous êtes comme moi un familier de la syntaxe Smarty, vous ne serez pas dépaysé par jTemplates.

La mise en oeuvre est ultra simple :

   <script type="text/javascript" src="jquery.js"></script>
   <script type="text/javascript" src="jquery-jtemplate.js"></script>

La première chose à faire est d'ajouter un conteneur qui recevra le résultats de la "transformation":
   <p id="my_list"></p>

Une fois ceci fait il faut créer un element contenant un template :

      <textarea name="template" id="template">
      <![CDATA[
      {#template MAIN}
        <p>Pour rouler une {$T.title} vous aurez besoin des fournitures suivantes :</p>
        <ul>
         {#foreach $T.elements as record}
            <li>{$T.record.element} ({$T.record.quantite})</li>
         {#/for}
        </ul>
      {#/template MAIN}
      ]]></textarea>


Et définir nos données JSON de la même manière :

      <textarea name="item" id="item">
      {
         "title" : "Cigarette",
         "elements": [
         {"element": "tabac", "quantite":"un peu"},
         {"element": "feuille", "quantite":1},
         {"element": "filtre", "quantite":1},
         ]
      }</textarea>

Nous venons de mettre en place un combo formidable que nous allons activer avec les deux lignes de code suivantes (à affecter sur l'evenement onClick d'un element par exemple) :

      $('#my_list').setTemplateElement('template');
      var data = eval( '(' + $('#item').attr('value') + ')');
      $('#my_list').processTemplate(data);

Le seul truc à noter si  on ne travaille par directement avec des objets, c'est qu'il faut impérativement  évaluer  le JSON avant d'appliquer la transformation. Pour une raison mal définie, il faut wrapper la chaîne de caractères JSON dans des parenthèses afin que l'eval() fonctionne...

Vous pouvez aussi consulter cet exemple ainsi qu'un outil de benchmark sur le Workshop.

Pour ma part j'utilise les fonctions $.setTemplate() et $.setTemplateURL(). En effet, je ne trouve pas qu'il soit optimal d'avoir les templates dans des textarea cachés dans la page pour plusieurs raisons :
  • Cela oblige l'utilisateur à télécharger tous les templates au chargement de la page.
  • L'utilisateur peut éventuellement modifier le contenu des templates à l'aide de Firebug et cela peut poser problème si vous utilisez jTemplates pour générer des formulaires.
J'ai donc opté pour une solution plus adaptée à l'Ajax et au Web 2.0.

Quand un template doit être utilisé souvent sur une page, je le télécharge en utilisant la fonction $.get() de jQuery au chargement de la page et je le stocke dans une variable, il sera disponible tant que l'utilisateur n'aura pas besoin de changer de page.

Si le template est sensé être utilisé dans des cas plus rare je le télécharge uniquement "on demand". Biensur, rien n'empêche de dire à la fonction de téléchargement de mettre en cache le template au bout d'un certains nombre de téléchargements :D

Fonction de mise en cache d'un template au chargement de la page (jQuery) :

      var tpl_root = "/templates/jtpl/";
      var table_template = '';
       
      $(document).ready(function(){
         $.get(tpl_root + "table.html", function(data) {
            table_template = data;
         });
      });



Saturday, February 23 2008

Ajax, Json et compression Gzip

Dernièrement je me suis mis a utiliser intensivement le JSON (JavaScript Object Notation).

Le JSON est un mode léger d'échange de données que je trouve particulièrement adapté aux "XHR" (XmlHTTPRequest). Du coup les échanges avec les différents services ne se font plus en XML mais en JSON. Ce qui me fait poser la question : Dois-je maintenant parler de "JHR" (JsonHTTPRequest) ? Je ne sais pas, une chose est sûre ce format est beaucoup plus light que le XML.

De fait, les données sont aussi décrites comme en XML et on y gagne énormément en taille. Voici une comparaison :

En XML :
      <?xml version="1.0" encoding="UTF-8"?>
      <links>
         <link>
            <title>moBlur.org</title>
            <url>http://moblur.org/</url>
         </link>
         <link>
            <title>moBlur.org - RSS</title>
            <url>http://moblur.org/index.php?feed/rss2</url>
         </link>
      </links>
Le même message en JSON :
      {"links": {
         "link": [
            {"title":"moBlur.org","url":"http://moblur.org/"},
            {"title":"moBlur.org - RSS","url":"http://moblur.org/index.php?feed/rss2"}
            ]
         }
      }
Comparaison rapide de poids :
  • XML : 256 bytes
  • JSON : 168 bytes
Soit un gain sec d'environ 34% pour cet exemple précis. Après cette constatation, j'ai entamé tout de suite l'implémentation de ce format d'échange pour l'ensemble de mes nouveaux projets web. Il est aisé en PHP de transformer un tableau de données en JSON (encore plus avec l'addition à PHP 5 du couple json_encode() et json_ecode()) avec une simple fonction récursive, voici un exemple trouvé sur le site bin-co.com que je vous copie ici (Compte tenu de la volatilité du média, plusieurs sources valent mieux qu'une) :
      <?php
      function array2json($arr) {
          $parts = array();
          $is_list = false;
       
          //Find out if the given array is a numerical array
          $keys = array_keys($arr);
          $max_length = count($arr)-1;
         
          //See if the first key is 0 and last key is length - 1
          if(($keys[0] == 0) and ($keys[$max_length] == $max_length)) {
              $is_list = true;
              //See if each key correspondes to its position
              for($i=0; $i<count($keys); $i++) {
                  //A key fails at position check.
                  if($i != $keys[$i]) {
                      //It is an associative array.
                      $is_list = false;
                      break;

                  }
              }
          }
       
          foreach($arr as $key=>$value) {
               //Custom handling for arrays
              if(is_array($value)) {
                  /* :RECURSION: */
                  if($is_list) $parts[] = array2json($value);
                  /* :RECURSION: */
                  else $parts[] = '"' . $key . '":' . array2json($value);
              } else {
                  $str = '';
                  if(!$is_list) $str = '"' . $key . '":';
                  //Custom handling for multiple data types
                 
                  if(is_numeric($value)) $str .= $value; //Numbers
                  elseif($value === false) $str .= 'false'; //The booleans
                  elseif($value === true) $str .= 'true';
                  //All other things
                  else $str .= '"' . addslashes($value) . '"';
                 
                  $parts[] = $str;
              }
          }
          $json = implode(',',$parts);
         
          //Return numerical JSON
          if($is_list) return '[' . $json . ']';
         
          //Return associative JSON
          return '{' . $json . '}';
      }
      ?>
L'utilisation en combo du json et de cette fonction PHP nous facilite grandement la vie côté développement. J'utilise cette fonction de transformation en JSON uniquement dans mes fichiers web services, ceux qui s'occuppent de l'abstraction des données. Comme parfois il vaut mieux un petit dessin qu'un long discourt voici un diagramme de la solution structurelle que j'utilise dans tous mes développements dit "Web 2.0" : Ce diagramme représente assez bien la quasi majorité des applications Web 2.0 je présume. Après avoir lu pas mal d'informations sur le compactage des fichiers JavaScript notement ici (Cyril Durand) et (Damien Ravé) et encore (loogaroo.net), j'ai voulu enfoncer le clou et j'ai donc ajouté une compression Gzip avant d'envoyer le résultat JSON au client. Toutefois, pour des communications de faible taille, nous ne voudrons pas utiliser la compression Gzip car du principe même de la compression, si il y a trop peu de caractères le fait de compresser  les données  pourra éventuellement augmenter la taille de la transaction ! Voici une toute petite fonction PHP que j'utilise en conjonction Array2json() présentée plus haut :
      <?php
      $arr_json = array(
         'link' => array(
            array( 'link' => array(
                  'title' => 'moBlur.org',
                  'url' => 'http://moblur.org/'
               ),
            array( 'link' => array(
                  'title' => 'moBlur.org - RSS',
                  'url' => 'http://moblur.org/index.php?feed/rss2'
               )
            )
         )
      );
      print array2json($arr_json);
      ?>
Cette fonction compresse tout simplement les chaines de caractères avant de les renvoyer au client. Sur la durée on pourra voir une nette diminution de la bande passante consommée et un accroissement de la vitesse de communication entre votre serveur et vos clients Web. Tout le monde sera ravis, j'en suis sûr :) Pour finir voici le diagramme final de notre architecture :