06
mars 11jQuery mobile (et Django)
jQuery mobile est un framework Javascript orienté interface utilisateur permettant, suivant le fameux concept du "write less, do more", de mettre en place une version mobile pour son site web. L'ergonomie est au coeur de la problématique : comment proposer aux utilisateurs de terminaux mobiles une version de mon site rapide à charger et ergonomique sur petit écran ?
Dans cet article, vous verrez comment mettre en place jQuery mobile au sein d'une application Django, pour l'exemple. L'architecture de cette application n'a rien à voir avec jQuery mobile, donc n'hésitez pas à le suivre quel que soit votre framework préféré... La première partie sera plus généraliste et vous permettra de comprendre comment adapter jQuery mobile à n'importe quelle application.
Mise en place de jQuery mobile
jQuery mobile vous fournit toutes les données nécessaires (Javascript, AJAX et CSS) pour créer des interfaces orientées utilisateurs de terminaux mobiles. Pour un usage basique, vous n'aurez donc aucune ligne de code à écrire vous-même, simplement à copier / coller les exemples de la documentation.
Nous allons créer un nouveau set de templates, indépendant de notre application, qui sera dédié aux utilisateurs mobiles. L'utilisation du HTML5 est donc de rigueur ! Rendez-vous sur la documentation de jQuery mobile. Ce sera exactement le rendu que nous cherchons à avoir. Examinez donc le code source de la première page : vous devrez utiliser la même structure.
Template de base
Voici votre template de base :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Mon site | Version mobile</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.css" />
<link rel="stylesheet" href="/media/css/mobile.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js"></script>
</head>
<body>
<div data-role="page" data-theme="b">
<!-- Header, éventuellement -->
<!-- Contenu -->
<div data-role="content">
</div>
</div>
</body>
</html>
Vous constatez que vous n'avez aucun fichier à héberger sur votre serveur : nous chargeons le CSS et les images directement en ligne. En partant du principe que le serveur de jQuery est plus réactif que le votre (sans offense), cela vous permettra de gagner du temps sur la durée de chargement des médias.
Les listes
jQuery mobile fonctionne avec des listes HTML basiques. Là encore, vous n'avez qu'à copier coller le code de la documentation, et à tester pour voir le rendu.
Tout votre contenu devra se placer dans la div data-role "content". Créez une liste de la façon suivante :
<div data-role="content">
<ul data-role="listview" data-insert="true" data-theme="b" data-dividertheme="b">
<li data-role="list-divider">Titre de la liste</li>
<li><a href="page2/">Page 2</a></li>
<li><a href="page3/">Page 3</a></li>
</ul>
</div>
Vous aurez ainsi une liste déjà stylée grâce au CSS de jQuery mobile. Notez que vous pouvez modifier le thème de chaque élément possédant l'attribut "data-theme", en lui donnant une valeur de a à e. Voici la correspondance au niveau design.
Le fonctionnement
jQuery mobile va suivre les liens de votre templates en créant une requête AJAX afin de ne pas raffraîchir la page (= gain de performance), avec en prime une petite animation de slide (par défaut). Créez donc simpement les pages correspondant à vos liens, avec la même structure que votre template de base. Le contenu de la div data-role "content" sera ré-injecté dans votre page.
Vous pouvez également ajouter un header proposant un lien de retour :
<div data-role="header" data-theme="b">
<h1>Portfolio</h1>
<a href="../" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-right jqm-home">Accueil</a>
</div>
Personnalisation
Voilà pour le fonctionnement de base. Vous pouvez évidememnt personnaliser les composants de vos listes en suivant la documentation. Il en existe beaucoup de génériques. Si vous souhaitez modifier le CSS pour une personnalisation totale, il est également très facile d'écraser les règles de base dans votre propre CSS (mobile.css, que nous avons lié). Exemple :
.ui-li-divider {
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#0091b6),color-stop(1,#0289ab));
}
Firebug vous aidera à trouver la classe des élements que vous souhaitez personnaliser ! Pour plus d'informations sur jQuery mobile, je vous invite à regarder cet excellent tutoriel vidéo par Grafikart.
L'application Django
Voyons maintenant comment utiliser jQuery mobile au sein d'une application Django existante. Pour cela, nous allons créer un module (views + templates) dédié.
Le module mobile
Pourquoi ne pas modifier seulement les templates existants ? Plusieurs réponses :
- Les querysets effectuées dans le contrôleur d'une vue "non-mobile" ne seront pas forcément utilisées, vu qu'on n'affichera pas les mêmes données.
- Comme on recherche avant tout la performance, on préferera supprimer toute requête inutile.
- Pour avoir un code plus clair !
Créez donc le nouveau module :
$ manage.py startapp mobile
Comme d'habitude, ajoutez l'application à vos installations via settings.py :
INSTALLED_APPS = (
[...]
'myproject.mobile',
)
Et les URLs, dans urls.py :
urlpatterns = patterns('',
[...],
(r'^mobile/', include('myproject.mobile.urls')),
)
Les urls et vues
Dans mobile/views.py, créez une vue pour chacune des pages de votre application. Pour rester dans l'exemple : home, page1 et page2 :
from django.shortcuts import render_to_response
def home(request):
return render_to_response(
'mobile/home.html'
{},
context_instance=RequestContext(request)
)
def page1(request):
return render_to_response(
'mobile/page1.html'
{},
context_instance=RequestContext(request)
)
def page2(request):
return render_to_response(
'mobile/page2.html'
{},
context_instance=RequestContext(request)
)
Puis, reliez ces vues avec les URLs, dans mobile/urls.py :
from django.conf.urls.defaults import *
from myproject.apps.mobile.views import *
urlpatterns = patterns('',
url(r'^$', home, name='home'),
url(r'^page1/$', page1, name='page1'),
url(r'^page2/$', page2, name='page2'),
)
Les templates
Pour les templates, vous pouvez réutiliser la structure donnée au-dessus. Par exemple, templates/layout/base_mobile.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>{% block title %}Mon site | Version mobile{% endblock title %}</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.css" />
<link rel="stylesheet" href="/media/css/mobile.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js"></script>
</head>
<body>
<div data-role="page" data-theme="b">
{% block header %}{% endblock header %}
<div data-role="content">
{% block content %}{% endblock content %}
</div>
</div>
</body>
</html>
Et le template de la home (templates/mobile/home.html) :
{% extends "layout/base_mobile.html" %}
{% block header %}
<div data-role="header" data-theme="b">
<h1>Portfolio</h1>
<a href="../" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-right jqm-home">Accueil</a>
</div>
{% endblock header %}
{% block content %}
<ul data-role="listview" data-insert="true" data-theme="b" data-dividertheme="b">
<li data-role="list-divider">Titre de la liste</li>
<li><a href="page2/">Page 2</a></li>
<li><a href="page3/">Page 3</a></li>
</ul>
{% endblock content %}
Faites de même pour les différentes pages.
Rediriger l'utilisateur mobile
Vous devez maintenant pouvoir naviguer sur votre version mobile à l'adresse mobile/. Maintenant, on voudrait que l'utilisateur d'un terminal mobile soit automatiquement rédirigé vers cette URL. Pour cela, on va utiliser (et adapter) django-mobile.
Installer django-mobile
Téléchargez et installez l'archive en suivant la documentation. Vous devrez :
- Installer le package.
- Ajouter django-mobile à vos INSTALLED_APPS.
- Ajouter les middlewares dans le bon ordre.
- Ajouter le template loader et le context processor.
Utiliser un décorateur
Pour finir, nous allons décorer chacune des vues de l'application (non-mobile) pour rediriger automatiquement les utilisateurs mobiles. Pour ce faire, placez dans le répertoire mobile/ un nouveau fichier decorators.py :
from django.http import HttpResponseRedirect
from functools import wraps
from django_mobile import get_flavour
def mobile_redirection(url):
def decorator(func):
def inner_decorator(request, *args, **kwargs)
flavour = get_flavour()
if flavour == 'mobile':
return HttpResponseRedirect('mobile%s' % url)
else:
return func(request, *args, **kwargs)
return wraps(func)(inner_decorator)
return decorator
Ce décorateur s'utilise de la façon suivante. Dans les vues de votre application :
@mobile_redirection('/')
def home_page(request):
[...]
L'utilisateur mobile sera alors automatiquement redirigé vers /mobile/. Pour modifier cette URL, passez-le en paramètre du décorateur. Par exemple '/page1/' redirigera vers mobile/page1/.
Testez en appelant votre URL depuis un terminal mobile. Vous devriez être redirigé automatiquement (comme sur http://www.valentinbourgoin.net) !
Changer de version manuellement
Enfin, si vous souhaitez proposer un lien pour changer de version manuellement, il vous suffit d'utiliser une spécificité de django-mobile en appelant les URLs suivantes :
- /?flavour=mobile pour la version mobile.
- /?flavour=full pour la version complète.

