Sitemesh : gérer son layout sans douleur
La gestion des layouts dans les applications web a toujours été pour moi un épine dans le pieds jusqu’à ce que je découvre Sitemesh. Et pourtant, une API de layouting permet d’éviter de copier/coller du code inutile pour décrire dans chaque page le header, la navigation, le footer, …
Avant Sitemesh, deux solutions:
– inclusion de JSP
– Tiles
L’inclusion de JSP est basique et trés trés limité car ne peut réellement tirer profit des framework MVC. Pour moi ce n’est pas une solution donc je ne vais pas en parler ici.
Trés longtemps j’ai utilisé Tiles qui a de nombreux avantages :
- Intégration à Struts et Spring
- Peut être utilisé comme framework MVC seul
- Configuration XML permettant l’héritage
- Orientation composant avec un controlleur par composant
Mais qui, hélas, comprend aussi de nombreux inconvénients :
- Fichier de configuration peu structuré vite complexe et brouillon
- Pas de possibilité de partage de layouts entre différents sites
- Pas de gestion spécifique des headers HTML (voir les possibilités de Sitemesh dans ce domaine)
- Trés vite, beaucoup d’héritage entre composants rendent le fichier de configuration trés peu lisible
- Trés verbeux en configuration
Sitemesh lui, a une approche forte différente: Sitemesh utilise le design pattern decorator (l’article de pcaboche sur developpez) pour ‘ajouter’ des briques à votre page. Concrétement, vous ne développez que l’intérieur des pages, puis vous définissez dans Sitemesh un layout à utiliser dans lequel vous donnez les différents decorator qui vont aller ajouter des parties d’HTML (donc vont aller décorer) vos pages.
La principale différence de Sitemesh se situe dans le fait que vos pages peuvent être crées avec n’importe quelle technologie. Par exemple, vous définissez une page /toto.do en Spring MVC (ou en Struts ou n’importe quel framework que vous aimez), vous utilisez ensuite le filtre Servlet de Sitemesh et vous lui dites d’intercepter les requête en *.do, Sitemesh, lorsque vous appelez /toto.do, va intercepter la requête et la décorer.
Dans Sitemesh, les décorateurs sont eux même des pages complète (donc, /footer.do, /header.do, /navigation.do ou /toto.do peuvent être vues indépendamment, en HTML et peuvent toutes êtres des controlleurs SpringMVC), ce qui permet de les déveloper et les tester indépendamment. Et en plus, Sitemesh peut décorer une page d’une site, par une page d’un autre site!
Dernière fonctionalité évoquée, la gestion des header. Comme les pages décorées et les décorateurs sont des pages HTML complète, elles contiennent toutes un titre, des CSS, … Sitemesh permet donc, au niveau de la décoration, de spécifier des header par défaut puis de les réécrire par l’objet décoré. En fait, Sitemesh parse les différentes pages HTML et nous donne accés aux éléments head et body de la page pour pouvoir aller puiser dedans les informations qui nous intéressent.
Bien sure, plein d’autres fonctionalités pour ce framework trés simple d’utilisation et de principe mais trés performant, allez voire sur le site … Je précise quand même que j’utilise Tiles depuis 3 ans et que je vient de découvrire Sitemesh que j’utilise pour un nouveau projets et j’en suis trés content.
Petit récapitulatif Sitemesh:
- Pattern decorator qui permet la separation entre le code et le layout, l’intégration du layout se fesant via un filtre en fin de requête
- Possibilité d’avoir les éléments du layout dans un site externe (donc de les partager entre plusieurs applications)
- Tout les éléments (éléments de layout et pages internes) sont des HTML complets et donc développable et testable indépendamment
- Agnostique par rapport à la technologie web JAVA utilisé
- Gestion intégré des différents header des pages et des décorateurs
Un exemple simple :
1. Définition du filtre de servlet :
<filter>
<filter-name>sitemesh</filter>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter>
</filter>
2. Définition du fichier de configuration de Sitemesh :
<?xml version="1.0" encoding="utf-8"?>
<decorators defaultdir="/view/decorator">
<decorator name="main" page="main.jsp">
<pattern>/*</pattern>
<excludes>
<pattern>/ErrorPage</pattern>
</excludes>
</decorator>
<decorator name="empty" page="empty.jsp"/>
</decorators>
Ici, on définit la JSP main.jsp comme description de layout et je lui dit d’appliquer ce layout à toutes les pages à l’exclusion de la page /ErrorPage. Le decorator empty servant à pouvoir définir des decorateur … qui ne décorent pas!
3. Voici enfin la page de layout :
< ?xml version="1.0" encoding="utf-8"?>
< %@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
< %@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %>
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title><decorator :title default="BELGACOM DEFAULT TITLE"/></decorator></title>
<decorator:head/>
<div><page:applyDecorator name="empty" page="/decorator/header"/></page></div>
<div><decorator:body /></div>
<div><page:applyDecorator name="empty" page="/decorator/footer"/></page></div>
</head>
</html>
Ici, on définit donc la pages HTML globale, on lui précise des éléments du header globaux qui pourront être redéfinit dans l’élément décoré, puis on as ensuite la pages HTML de layout elle même.
- <decorator:title/> : renvoit le titre de la page décorée
- <decorator:head/> : renvoit le header de la page décoré
- <decorator:body/> : renvoit le body de la page décoré
- <decorator name= »empty » page= »/decorator/footer »/> : applique le layout donné dans l’attribut ‘name’ sur la page donnée dans l’attribut ‘page’ et met le résultat ici. Grâce à cette ligne on décore la page interne par des morceaux d’autres pages, et on remarque que l’on peut chainer les decorateurs facilement.
Ce petit exemple est loin de montrer toutes les possibilités de Sitemesh mais qui permet d’en montrer la simplicité et le fonctionnement générale.
Site officiel de Sitemesh: http://www.opensymphony.com/sitemesh/
N’hésitez pas à faire vos remarques où à me poser des questions.
*** MISE A JOUR ***
Cet article sur developpez.com: http://loic-mathieu.developpez.com/java/tutoriel/sitemesh-intro/
*** MISE A JOUR ***
Un bug existe dans la version actuelle (corrigé dans la version 2.4) au niveau de la décoration d’une page d’erreur. Toutes les informations ici: Sitemesh : décoration d’une page d’erreur
One thought on “Sitemesh : gérer son layout sans douleur”
bonjour ,
j’ai suivi toute la demarche , le probleme c est que celle-ci marche juste pour les fichier qui se trouvent directement dans le dossier web , mais ne marche pas pour les fichiers qui se trouvent dans un dossier , par exemple web/mondossier/mapage.jsp , autre question comment quel est le nom que je dois donner au fichier de configuration , est ce que c’est sitemesh.xml ou decorator.xml …etc , et ou je dois declarer ce fichier , est ce que je le declare au web.xml ??
cordialement