#306

Développer pour les plateformes mobiles avec jQuery Mobile 1ère partie

Je me suis remis à Rails voici quelque temps en développant un projet de carnet d’adresses. La version « classique » fonctionnait relativement bien, mais j’avais envie de proposer également un rendu spécifique pour les plateformes mobiles. Utilisant déjà jQuery dans mon application, je suis allé voir ce qu’ils proposaient pour « mobilifier » une application Web.

Dans un premier temps, alléché par le screencast de Ryan Bates sur le sujet, je me suis tourné vers jQTouch, qui ciblait les appareils iOS. Mis à part quelques petits soucis au niveau des boutons « Back », ce plugin remplissait correctement son rôle.

Mais voici quelques semaines, je suis tombé sur jQuery Mobile, le plugin « officiel » qui remplissait la même fonction tout en étant plus complet en ce qui concerne les plateformes supportées. Cela se fait au détriment d’une apparence moins centrée sur l’iPhone/iPad, mais le jeu en vaut la chandelle.

Structure d’une page

Je ne reviens pas sur la mise en place d’une application mobile, consultez le screencast de Ryan Bates pour plus d’information. La mise en place de jQuery Mobile est assez similaire à celle de jQTouch ; on modifie le markup des fichiers  mobile.erb, en commençant par le layout principal :

<!DOCTYPE html>
<html>
<head>
  <title><%= t(:"general.title") %></title>

  <%= stylesheet_link_tag "/jquery.mobile/jquery.mobile-1.0b2.min.css" %>
  <%= javascript_include_tag 'jquery-1.6.2.min.js' , :charset => "utf-8" %>
  <%= javascript_include_tag '/jquery.mobile/jquery.mobile-1.0b2.min.js' , :charset => "utf-8" %>
  <%= javascript_include_tag 'jquery.scrollExtend.min' %> 	

  <%= csrf_meta_tag %>
  <%= yield(:head) %>
</head>
 <body>
  <div data-role="page"  >
    <div data-role="header" data-theme="b" >
      <%= yield :back %>
      <h1><%= yield :title %></h1>
      <%= yield :button %>
    </div>
    <div data-role="content">
      <% unless flash.empty? %>
        <div>
          <%- flash.each do |name, msg| -%>
            <%= content_tag :div, msg, :id => "flash_#{name}" %>
          <%- end -%>
        </div>
      <% end %>
      <%= yield %>
    </div>
<div style="text-align:center;font-size:12px;color:grey;" ><%= t(:"general.title") %> <%= "v"+APPLICATION_VERSION %> - <%= raw t(:"general.copyright") %></div>
  </div>
 </body>
</html>

J’ai choisi pour des raisons de commodité de développement d’insérer les fichiers .js de jQuery Mobile directement dans mon projet, mais vous pouvez bien sûr les laisser pointer vers les adresses officielles.

La structure d’une page jQM est relativement simple :

<div data-role="page"  >
  <div data-role="header" data-theme="b" >
  </div>
  <div data-role="content">
  </div>
  <div data-role="footer">
  </div>
</div>

Une « page » contient un en-tête (header), du contenu (content) et un pied de page (footer). Je ne me suis servi que du header et du content pour ce projet, comme vous le constatez dans mon code. Il est également possible d’avoir plusieurs pages dans le même fichier, en leur donnant des ids différents, mais celà ne cadre pas avec la philosophie de Rails.

Un en-tête variable pour vos pages avec yield

Sur la plupart des plateformes mobiles, l’en-tête de la page est réservée à la navigation et aux actions de l’application. Cette partie est hautement variable, puisqu’elle va dépendre de l’action que l’utilisateur est en train de réaliser.

Choix du filtrePar catégories

Comme vous le voyez ci-dessus, sur la page de choix du filtre , le bouton déconnexion est affiché ; sur la page suivante, c’est le bouton Retour.

Le problème, c’est que pour des raisons de simplicité et de maintenabilité, nous avons inséré la structure de la page jQM dans le layout principal, et non dans chaque vue  de l’application Rails. Heureusement, notre framework favori nous offre une solution élégante grâce à la fonction yield.

Vous avez forcément déjà utilisé yield pour passer au layout principal le code html de votre vue ; mais cette fonction permet de passer plusieurs élément de la vue vers un layout en nommant chaque yield. Si nous revenons sur le code de l’en-tête :

<div data-role="header" data-theme="b" >
  <%= yield :back %>
  <h1><%= yield :title %></h1>
  <%= yield :button %>
</div>
Nous allons pouvoir passer au layout trois éléments distincts :
  • Le bouton « back » ou autre élément sur la gauche de la barre d’en-tête
  • Le titre de la page
  • Un bouton « button » affiché à droite de la barre d’en-tête
Pour insérer notre titre et le bouton retour tel que vu sur la page d’affichage des catégories, il suffit d’insérer en haut de votre fichier de vue les codes suivants :
<% content_for :back do %><%= link_to "Retour", nil, :'data-rel'=>"back",:'data-icon'=>"arrow-l" %><% end %>
<% content_for :title do %><%= "Catégories" %><% end %>
La première ligne va afficher le bouton Back, avec une icône prédéfinie de  jQM (arrow left). La seconde va renvoyer un texte qui sera affiché comme titre de la fenêtre.
Dans le prochain article, nous parlerons des listes et de leur gestion avec Rails et JQuery Mobile.

Rails 3 + Paperclip sous Windows

Pour insérer et manipuler des images dans Rails, il existe de nombreux gems permettant de s’affranchir d’une bonne partie de la complexité des transferts de fichiers. Parmi ceux-ci, j’ai retenu Paperclip.

Autant la gestion des transferts de fichiers s’est faite sans problème, autant le redimensionnement de ceux-ci m’a amené à m’arracher quelques cheveux ; je tombais systématiquement sur l’erreur suivante :

Photo C:/xxx/xxx/xxx/Temp/stream,2568,0.jpg is not recognized by the 'identify' command

Pour régler ce problème, trois étapes importantes :

1. Installer ImageMagick
Eh oui, Paperclip repose sur ImageMagick pour le redimensionnement des images ! Il faut donc télécharger cet outil pour Windows à l’adresse suivante :

http://www.imagemagick.org/download/binaries/ImageMagick-6.6.4-9-Q16-windows-dll.exe

Installez le programme à l’adresse par défaut, puis vérifiez que tout fonctionne bien en ouvrant un terminal (invite de commande) et en tapant : identify chemin/vers/une/image.jpg. Si tout est OK, ImageMagick vous répondra en affichant le format du fichier que vous lui avez fourni.

2.  Ajouter un initialiseur à Rails

Ajoutez dans le répertoire config/initializers de votre application un fichier paperclip.rb dans lequel vous collerez le code suivant :

require "paperclip"
Paperclip.options[:command_path] = 'C:\PROGRA~1\ImageMagick-6.6.4-Q16'
Paperclip.options[:swallow_stderr] = false

Bien sûr, la première ligne d’option est à modifier en fonction de la localisation et de la version de ImageMagick installée à l’étape précédente. Il est très important de mettre le chemin Windows au format DOS 8.3 (PROGRA~1 en lieu et place de Program Files, dont l’espace cause problème à Paperclip).

3. Modifier les sources de Paperclip

Il faut également aller modifier la ligne de commande d’ImageMagick dans Paperclip, en éditant le fichier suivant paperclib.rb qui se trouve dans le répertoire lib du gem Paperclip. Sur mon poste, le fichier se trouve ici :

C:\Ruby\lib\ruby\gems\1.9.1\gems\paperclip-2.3.3\lib

Dans la fonction run, qui se trouve vers la ligne 100, trouvez la ligne suivante :

command = %Q[#{path_for_command(cmd)} #{params}]

et remplacez-la par la ligne ci-dessous :

command = %Q[#{path_for_command(cmd)} #{params.gsub("'",'"')}]

Cela remplacera les quotes simples par des quotes doubles.

Voilà, normalement, vous devriez accéder aux joies de Paperclip sous Windows !

Sources : Un commentaire du Railscast dédié à Paperpclip

MezzoAutomator v0.3

MezzoAutomator

J’ai terminé la première phase de développement de MezzoAutomator.Cet outil permet de gérer le transfert de fichiers vers Mezzoteam, pour traiter des cas d’emploi du genre remontée automatique dans Mezzoteam de courrier entrant scanné.
Dans cette première version, vous trouverez les fonctionnalités suivantes :

  • Connecteur d’entrée
    • Scan périodique d’un répertoire
  • Connecteurs de sortie
    • Transfert du fichier vers un dossier Mezzoteam
    • Transfert du fichier vers un document existant
    • Création « statique » d’un nouveau document et transfert du fichier (même paramétrage pour tous les fichiers)
    • Création « dynamique » d’un nouveau document et transfert du fichier (paramétrage variable d’un document à l’autre)

Le paramétrage de MezzoAutomator s’effectue au travers d’un fichier de configuration au format XML, facilement éditable. La description du format et des exemples de fichier de configuration sont disponibles dans l’archive du produit ; reportez-vous au fichier readme.txt.

Je reste à l’écoute de vos remarques et suggestions !

Télécharger MezzoAutomator

MezzoAutomator, un projet OpenSource pour Mezzoteam

GitHubJe commence ces jours-ci un projet Open Source dont l’objet est d’automatiser le dépôt de fichiers / la création de documents dans Mezzoteam, à partir de sources diverses (par exemple des fichiers déposés dans un répertoire).

Ce projet est constitué de deux sous-projets :

  • MezzoAutomator, qui comprend la partie fonctionnelle du projet
  • MezzoObject, qui est une bibliothèque d’accès aux API Web Services de Mezzoteam.

Le tout est à consulter sur github.com, à l’adresse suivante : github.com/enetter

Pour l’instant, rien n’est fonctionnel ;-). Gardez un oeil sur ce blog, je vous préviendrai quand il y aura quelque chose de concret à se mettre sous la dent !

PS : ce sera aussi pour certains l’occasion de se mettre sur git. En deux mots, c’est svn mais où chaque copie serait un repository indépendant… Brillant, et de plus développé par Linus Torvalds !

Récupérer la liste des espaces de travail

recupwsPour ce nouvel épisode de notre série sur l’utilisation des services Web dans Mezzoteam, nous allons apprendre comment récupérer la liste des espaces de travail de Mezzoteam auxquels l’utilisateur courant a accès. En effet, Mezzoteam fonde les principes de sa gestion de la sécurité et le calcul des droits des utilisateurs à l’intérieur d’un espace de travail. Toute action (récupération de liste de documents, création de document, attachement de fichiers, workflows…) s’effectue une fois que l’utilisateur a changé d’espace de travail et que Mezzoteam a pu calculer ses droits spécifiques.

La plupart clients riches Mezzoteam affichent donc, une fois la connexion établie, la liste des espaces de travail de l’utilisateur, afin que celui-ci puisse ensuite naviguer vers l’espace de travail souhaité.

Pour cet exercice, nous allons partir de l’exemple que nous avions créé à l’épisode précédent. Comme nous l’avions vu alors, après la connexion de l’utilisateur, Mezzoteam calcule une clé de session (SessionKey) qui va nous servir pour identifier la session de l’utilisateur courant dans toutes ses actions sur Mezzoteam.

Nous allons utiliser cette clé de session pour initialiser un nouveau service web, le service directory.

Le service web Directory
Le service web Directory permet au développeur de manipuler les objets suivants dans Mezzoteam :

  • Espace de travail (objet Worksapce)
  • Utilisateur (objet User)
  • Groupe (objet Group)
  • Organisation (objet Organization)

Pour chacun de ces objets, on trouve des méthodes pour en récupérer la liste, créer de nouveaux objets, en supprimer, etc.

Créons donc notre nouveau service web :

// Création d'un objet Directory
directory myDirectoryWs = new directory();

// On passe la clé de sécurité calculée lors de la connexion
myDirectoryWs.CredentialSoapHeaderValue = new CredentialSoapHeader();
myDirectoryWs.CredentialSoapHeaderValue.SecurityKey = myLogon.SecurityKey;

Pour récupérer la liste des espaces de travail, nous utiliserons la méthode WorkspaceGetList, qui récupère la collection d’espaces de travail de l’utilisateur dont on passe l’identifiant en paramètre.

// Création d'un objet Workspace[] pour récupérer la liste des espaces de travail
Workspace[] myWorkspaceList;
// La méthode de récupération de la liste des espaces de travail prend comme paramètre
// le login de l'utilisateur
myWorkspaceList = myDirectoryWs.WorkspaceGetList(myDirectoryWs.UserGetFromLogin(textBox1.Text));

Il existe d’autres méthodes pour récupérer une liste d’espaces de travail, et en particulier des méthodes retournant des objets DataSet plutôt qu’une collection d’objets Workspace. Ces méthodes sont à priori moins coûteuses lors de l’exécution, et ej vous encourage à les utiliser plutôt que celles qui retournent les objets métier de Mezzoteam. Néanmoins, pour ce premier exemple, nous irons à la facilité !

Nous afficherons ensuite certaines des propriétés des epsaces de travail sur les 5 premiers espaces de travail de l’utilisateur, en procédant de la manière suivante :

// On calcule le nombre d'espaces de travail récupérés
int rowCount = myWorkspaceList.Count();
// On limite a au plus 5
if (rowCount > 5)
{
rowCount = 5;
}
// On affiche les informations de titre et de volume des 5 premiers
// espaces de travail
for (int iCounter = 0; iCounter < rowCount - 1; iCounter++)
{
MessageBox.Show("Titre : " + myWorkspaceList[iCounter].Title + " Volume de fichiers :" + myWorkspaceList[iCounter].TotalFileSize.ToString());
}

Je vous encourage à explorer les propriétés d’un espace de travail en utilisant le mode pas à pas de Visual Studio. Dans le prochain épisode, nous verrons comment naviguer vers un espace de travail, et en récupérer la liste des documents.

Le code de cet épisode est disponible ici.