jMaki : exemple d'utilisation avec NetBeans 6.5 sous Mac OS X
C'est l'un des frameworks intéressants pour créer des mashups Ajax et plus si affinités. Passage en revue.
Ce tutorial est inspiré par celui de Ludovic Champenois sur le même sujet. Il m'a fallu procéder à quelques ajustements et éclaircissements et le tester sur une autre plate-forme (Mac OS X au lieu d'OpenSolaris). Les utilisateurs d'Unix / Linux feront l'adaptation sans trop de problèmes. J'ai en outre utilisé NetBeans 6.5.
jMaki, ça sert à quoi ?
Nous allons voir comment jMaki (voir la la page d'accueil du site) permet de créer une application simple qui offre à l'utilisateur un formulaire de saisie de données pour insertion dans une table, et l'affichage consécutif des résultats dans une autre section de la page.
Nous supposons qu'une connaissance minimale de Javascript, de php, du html, du SQL et de NetBeans est acquise. Si vous n'avez pas encore installé cet IDE, vous pouvez le télécharger sur le site de NetBeans. Savoir lancer quelques lignes de commande dans le terminal sous Mac OS X sera un plus également (personnellement, j'utilise encore tcsh sous Mac OS 10.4.quelque chose).
Jusque là, rien de bien compliqué. L'intérêt du dispositif est d'accélérer le travail de développement, de simplifier le code et la structure de l'application, tout en offrant les derniers widgets un peu intéressants sortis des différents projets actuels, dont Yahoo, Dojo, Google, etc. Et si vous le souhaitez, vous pouvez même créer vos propres widgets.
NetBeans à la rescousse
NetBeans permet certes de gérer les projets, mais si on le configure correctement, il peut aussi faciliter le développement de projets jMaki. Il faut pour cela le configurer à savoir, dans le menu Outils > Plugins, ajouter jMaki Core Ajax Support et jMaki for JavaEE Web Applications. Vous n'avez plus ensuite qu'à redémarrer NetBeans et c'est tout bon. Lorsque vous afficherez la palette une fois les plug-ins installés, vous verrez apparaître les balises HTML traditionnelles, mais aussi tous les widgets jMaki. Et comme NetBeans supporte également les projets PHP depuis quelque temps, c'est de ce côté-là que nous allons nous orienter, sans avoir à gérer un serveur d'application Java. Ça fonctionne très bien, mais c'est plus compliqué.
jMaki : ça colle
jMaki offre un dispositif appelé "glue" (comme "colle"), sous forme d'un fichier glue.js. Il fonctionne sur un mécanisme de publication / abonnement (publish / subscribe) qui gère l'ensemble de l'échange des données entre deux ou plusieurs widgets. C'est relativement pratique (les données sont structurées en JSON), simple à comprendre et pour l'instant, je n'ai pas repéré de bugs. Nous le verrons plus en détails lors de l'examen du fichier lui-même dans la création du processus de développement. C'est principalement à ce niveau qu'il faudra faire attention à ce qu'on écrit et bien comprendre la logique du mécanisme.
configuration et lancement d'Apache
Avant d'aller plus loin, rappelons que nous allons utiliser MAMP dans toute sa splendeur : Mac OS X, Apache, MySQL et PHP. Il faut donc qu'Apache soit configuré avec PHP (personnellement, j'en suis encore à la version 4 sur ma machine et ça n'a pas posé de problème) et démarré :
sudo apachectl startdans le terminal ou dans les Préférences Systèmes, à la section Partage, cocher "Partager Web personnel". Pour plus de facilité, nous installerons les fichiers à servir dans /Users/monlogin/Sites/jMaki_PHP_1/ (ou ~/Sites/jMaki_PHP_1), accessibles depuis l'URL : http://localhost/~monlogin/jMaki_PHP_1/index.php (inutile si vous avez configuré Apache pour servir index.php par défaut). Au cas où tout ça ne vous paraît pas clair, reportez-vous aux instructions sur le site d'Apache.
démarrage de MySQL
Il faut ensuite ne pas oublier de démarrer MySQL, ce qui se fait avec trois lignes de commande :
cd /usr/local/mysql/bin/ sudo echo bonjour sudo ./mysqld_safe &puis taper un "Enter" pour revenir à la ligne suivante du terminal. Vous trouverez des informations plus complètes ici.
création du projet dans NetBeans
Nous allons maintenant lancer NetBeans, qui doit être installé. Je crée un nouveau projet (Fichiers > Nouveau Projet) et je choisis "PHP" et "PHP Application".

Je vais ensuite le nommer jMaki_PHP_1 pour plus de commodités.

Je choisis de le placer directement dans le dossier Sites de mon espace personnel. On verra plus bas qu'il y a un bug quand on lance la commande "Run" et qu'il faut en fait copier à la main les fichiers. Pas bien compliqué, mais bon, on aurait aimé plus de souplesse. Je ne me rappelle plus lorsque j'avais testé le tout sous Leopard et NetBeans 6.7 si cela fonctionnait. Il faudra retester.

Je choisis Fichier > Nouveau Fichier et je sélectionne PHP File (PHP est déjà choisi par défaut, normal, c'est un projet du même type). Je le nomme index.php et je vais pouvoir commencer à travailler. Tant que j'y suis, j'en crée quatre autres de la même manière qui me serviront aux autres fonctionnalités du projet : add.php, setup.php, listProducts.php et dbname.php.

les différents fichiers
Commençons avec le fichier dbname.php :
<?php
$username="root";
$password="rmonpassword";
$database="phpwebstacksample";
$dbhost="localhost";
$mysql_connection = mysql_connect($dbhost, $username, $password);
if (!$mysql_connection)
{
die('Could not connect: ' . mysql_error());
}
?>
qui ne comporte rien de bien particulier, si ce n'est le renvoi intégré d'un message d'erreur en plus de la variable de connexion ($mysql_connection). On remarque qu'il s'agit d'une écriture "préhistorique" type php4. Si vous le souhaitez, vous pouvez réécrire le tout avec mysqli par exemple, spécialement développé pour php5.
Nous continuons avec le fichier setup.php, que vous pouvez tout à fait éviter (en réécrivant un peu du fichier index.php) si vous avec configuré à la main la base de données et la table :
<?php
include("dbname.php");
// create database
if (mysql_query("CREATE DATABASE phpwebstacksample",$mysql_connection))
{
echo "database created";
}
else
{
echo "error creating database: " . mysql_error();
}
// create table in my_db database
mysql_select_db($database, $mysql_connection);
$query="CREATE TABLE products (
id int(6) NOT NULL auto_increment,
name varchar(15) NOT NULL,
category varchar(20) NOT NULL,
price varchar(20) NOT NULL,
PRIMARY KEY (id),
UNIQUE id (id),
KEY id_2 (id))";
mysql_query($query,$mysql_connection);
mysql_close($mysql_connection);
echo "<p>Retour à la page index <a href=\"index.php\">envoyez l'applicatif ...</a></p>";
?>
Ce fichier crée une base de données (phpwebstacksample) puis une table (products) dont la structure est simplissime, et permet ensuite de revenir à la page d'index. Rien de bien difficile.
Suit le fichier listProducts.php :
<?php
require_once("dbname.php");
if (!mysql_select_db($database, $mysql_connection) ) {
?>
<p>La base de données pour cet exemple n'existe pas.</p>
<p>Activez la <a href="setup.php>page de configuration.</a></p>
<?php
exit();
}
@mysql_select_db($database);
$query="SELECT * FROM products";
$result=mysql_query($query);
$num=mysql_numrows($result);
mysql_close();
?>
<?php
$i=0;
echo "{'rows' : [";
while ($i < $num) {
$name=mysql_result($result,$i,"name");
$category=mysql_result($result,$i,"category");
$price=mysql_result($result,$i,"price");
echo "{ name: '".$name ."' , category :'".$category."', price :'".$price ."'}";
if ($i != $num -1)
echo ",";
++$i;
}
echo "]}";
?>
La principale fonctionnalité de ce fichier, comme son titre l'indique, est de lister les produits dans la base. On remarque quelque chose de très important au passage, à savoir que les données retournées sont formatées en JSON. Il y a en outre deux ou trois subtilités dans le code (dont une pré-incrémentation) que je vous laisse apprécier. C'est cette page, nous le verrons qui est appelée pour rafraîchir la page d'index avec la magie d'Ajax.
Nous avons donc créé une page de configuration générale, une page de création de notre environnement du modèle de données et une page qui permet de lire les enregistrements dans la table.
Nous terminons donc par le fichier add.php qui nous permet d'ajouter un enregistrement :
<?php
include("dbname.php");
mysql_connect($dbhost,$username,$password);
mysql_select_db($database) or die( "Unable to select database");
$name=$_GET["name"];
$category=$_GET["category"];
$price=$_GET["price"];
$query = "INSERT INTO products VALUES ('','$name','$category','$price')";
mysql_query($query);
mysql_close();
echo "value added";
?>
Il n'y a rien là que de très classique : des requêtes SQL encapsulées dans les fonctions PHP.
le fichier : index.php
Nous allons ajouter par glisser-déposer les deux widgets qui font toute la saveur de jMaki. Il faut bien comprendre ici que vous allez devoir réécrire une partie du code, mais surtout, ne vous aventurez pas à un simple copier-coller. En gros, sous NetBeans, vous allez utiliser deux widgets : Yahoo Button et Yahoo DataTable. Faites en sorte après avoir effectué le glisser-déposer que le code ressemble à ceci :
<?php require_once "Jmaki.php"; ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>exemple d'application avec jMaki</title>
</head>
<body>
<?php
require_once("dbname.php");
if (!mysql_select_db($database, $mysql_connection) ) {
echo "La base de données pour cet exemple n'existe pas. <a href=\"setup.php\">Cliquez ici pour la créer</a>";
exit();
}
?>
<p>Avec ce formulaire, vous pouvez ajouter des produits qui seront insérés dans une base de données MySQL et publiés grâce à un widget jMaki.</p>
<form action="#" >
product name : <input id="name" name="name" type="text"><br>
product category :<input id="category" name="category" type="text"><br>
product price : <input id="price" name="price" type="text"><br>
</form>
<?php
addWidget( array("name" => "yahoo.button",
"value" => "{ label : 'add a product' }"
));
?>
<h4>this is my list of products</h4>
<?php
addWidget( array("name" => "yahoo.dataTable",
"args"=> "{columns : [
{ 'label' : 'name', 'id' : 'name'},
{ 'label':'category', 'id' : 'category'},
{ 'label': 'price ', 'id' : 'price'}
]}",
"service"=>"listProducts.php"
)
);
?>
</body>
</html>
Attardons-nous quelque peu sur les aspects intéressants de cette composition. Le premier widget, un bouton Yahoo, prend une valeur d'affichage (label) différente de la valeur par défaut. Mais c'est le second widget, une dataTable de Yahoo, qui va subir les plus grosses modifications. En effet, nous allons modifier à la fois les valeurs par défaut (values) mais aussi ajouter un service, qui est tout bonnement d'indiquer le fichier listProducts.php. À chaque étiquette (label) correspond une valeur identifiée par un… identifiant (id). Le widget se charge de peupler les lignes d'enregistrements (rows) qui étaient auparavant statiques.

on colle tout ça : glue.js
C'est le dernier point important. Le fichier permet comme nous l'avons vu de passer les données d'un widget à un autre, donnant ainsi tout son sens à de potentiels mashups. En voici le code, que nous allons commenter :
// uncomment to turn on the logger
jmaki.debug = false;
// uncomment to show publish/subscribe messages
jmaki.debugGlue = false;
// map topic for the add product button
jmaki.subscribe("/yahoo/button/onClick", function(args) {
// get the values of the 3 fields in the form:
var name= document.getElementById("name").value;
var category= document.getElementById("category").value;
var price= document.getElementById("price").value;
//do an ajax request to the add server side logic, with the correct params:
jmaki.doAjax({
url : "add.php", // call the add.php URL
method : "GET",
content : {
name : name,
category : category,
price : price
},
callback: function(req) {
//in this call back, we just add a new row to the local jMaki table
if (jmaki.trim(req.responseText) == "value added")
jmaki.publish ('/yahoo/dataTable/addRow',
{
value: {
name : name,
category : category,
price : price
}
}
);
else
alert ("error adding a row: "+req.responseText);
}
});
});
Ce code appelle quelques commentaires.
Premier point, jMaki se traduit par un objet JavaScript : jmaki, qui comprend tout un ensemble de méthodes dont certaines sont à l'œuvre ici. Pour plus d'informations sur la question, se plonger dans le script d'origine ne fait pas de mal.
Continuons avec l'option débugage. Si l'on change les valeurs de jmaki.debug et jmaki.debugGlue en true, on aura un terminal de logs en bas à droite de la fenêtre du navigateur permettant de voir ce que bricole le framework. Intéressant si l'on se retrouve avec des erreurs.
La méthode suivante, subscribe, constitue le premier point de la dynamique de transfert des données. Dans le jargon du framework, il s'agit ni plus ni moins que d'envoyer les données relatives au widget considéré (indiqué par un "/yahoo/button") suite à un événement donné (ici : /onClick). Que fait-on au juste ? Examinons pour cela la méthode doAjax dont la valeur du paramètre "url" est add.php. D'après ce script, il ne s'agit ni plus ni moins que d'envoyer des données dans la base, que l'on a au préalable collectées dans le formulaire, grâce aux instructions suivantes : document.getElementById("name").value (puis pour category, puis pour value).
Tout de suite après suit une fonction de callback (qui s'active lorsque la fonction précédente est terminée) et qui active le second volet de jMaki : publish. La boucle est bouclée. Dans la dataTable de Yahoo (indiquée par l'écriture /yahoo/dataTable) nous allons ajouter une ligne (/addRow) avec les valeurs suivantes (en format JSON). C'est le "value added" revoyé depuis le fichier add.php à la dernière ligne (si tout s'est bien passé donc) qui indique le fait que la valeur est publiable.
Nous résumons donc : d'un côté, l'on s'abonne à se que rentre l'utilisateur, de l'autre, on publie le résultat du process (ici insertion dans une base de données).
Voilà, il ne reste plus qu'à copier à la mimine les fichiers, le plus souvent à la racine de l'espace utilisateur dans le dossier NetBeansProjects ou quelque dans le genre, vers son espace ~/Sites. En effet, l'activation de la commande Run, même après spécification de l'endroit où copier les fichiers, n'a pas permis de faire tourner l'applicatif faute d'avoir copié tous les fichiers nécessaires. Vous pouvez donc tout envoyer (en mode graphique ou ligne de commande), sauf le dossier nbproject qui sert à l'IDE en interne.
Dans un prochain article nous essaierons d'autres combinaisons et nous ajouterons les liens qui vont bien. Apparemment, le projet jMaki suit son cours, même si la page d'accueil du site n'est pas trop à jour actuellement.
tags : jMaki, NetBeans, php, Mac OS X, Apache, Ajax
mis en ligne : Sat Aug 15 17:28:13 CEST 2009