29-11-2011 : Remettre dans le débat politique les principes du Conseil National de la Résistance
29-01-2012 : Parce que nous sommes un peuple debout, agissons pour rester dignes et responsables !
Logo de mon site
Logo de mon site
Faire un don

Luxpopuli / eZ Publish / Trucs & astuces / eZ Publish : créer une galerie d'images avec la librairie highSlide





Right menu

Logo du site ez.no  Logo XHTML 1.O du W3C  Logo XHTML 1.O du W3C  Site francophone officiel de Firefox

eZ Publish : créer une galerie d'images avec la librairie highSlide

Date de publication: le lundi 27 avril 2009 à 13h33
Dernière modification: par Pascal BOYER le vendredi 25 septembre 2009 à 18h57
« Article précédent: eZ Publish : système de gestion des mails - page « Contact » II
» Article suivant: eZ Publish : créer une page de contact avec la librairie highSlide

highSlide

Cet article présente la mise en oeuvre d'une galerie d'image réalisée à partir de l'excellent travail de développement de la librairie javascript highSlide du novégien Torstein Hønsidans .

Sur la page d'accueil du site highslide.com on trouve cette description:

Highslide JS is an open source image, media and gallery viewer written in JavaScript. These are some of it's advantages:
Highslide JS est un afficheur javaScript open source d'images, de fichiers média et de galeries dont voici quelques uns de ses avantages:

  • Quick and elegant looking.
    Rapide et élégant.
  • No plugins like Flash or Java required.
    Aucun plugin Flash ou Java requis.
  • Popup blockers are no problem. The content opens within the active browser window.
    Les bloqueurs de popup ne posent pas de problème. Le contenu s'ouvre dans la fenêtre active du navigateur.
  • Single click. After opening the image or HTML popup, the user can scroll further down or leave the page without closing it.
    Clic unique. Après avoir ouvert la popup image ou HTML, l'utilisateur peut faire défiler ou quitter la page web sans devoir préalablement fermer la popup.
  • Lots of configuration options and scalability without compromizing on simplicity. A component system lets you strip away unused features down to a filesize of 10kB.
    Nombreuses options de configuration et d'évolution sans compromission de la simplicité d'utilisation. Un système de composants vous permet de supprimer les fonctionnalités non utilisées pour obtenir un fichier ne faisant pas plus 10 Ko.
  • Outstanding, unconditional and free user support for both commercial and non-commercial users.
    Support utilisateur remarquable, libre et sans condition pour une utilisation commerciale et non commerciale.
  • Compatibility and safe degrading. If the user has disabled JavaScript or is using an old browser, the browser redirects directly to the image itself or to a given HTML page.
    Compatibilité et préservation du mode dégradé. Si l'utilisateur désactive JavaScript ou s'il utilise un vieux navigateur, ce dernier redirige directement vers l'image ou vers une page HTML.

Par ailleurs, highSlide est compatible avec tous les navigateurs récents (IE5 à IE7 compris). Seul IE8 beta 1 pose quelques problèmes.

Objectif

La satisfaction des clients, et particulièrement celle des éditeurs/rédacteurs de contenus de sites web, passe souvent par leurs désirs de posséder un outil combinant deux vertus assez antinomiques: la puissance et la simplicité. C'est donc sans perdre de vue ce double objectif que j'ai réalisé cette galerie d'image basée sur la librairie highslide.

Au final, l'utilisateur n'aura à créer/instancier que des dossiers et à importer les images de chacune des galeries, le système réalisant automatiquement toute la mise en page.

Exemples de galerie photos

Le lien ci-dessous présente le résultat que je vous propose de mettre en oeuvre à travers cet article:

De nombreux autres exemples sont disponibles sur le site highslide.com:

L'exemple développé par le présent article repose sur la mise en oeuvre suivante de highSlide:

Comme vous le verrez par la suite, aucune limite du nombre de galeries par page n'est imposée dans la solution détaillée ci-après.

Prérequis

Voici l'environnement logiciel dans lequel s'est déroulé le développement de cette galerie photos:

  • Un serveur Debian
  • Un environnement PHP 5.2.9
  • Un serveur web Apache 2.2.11-2
  • eZ Publish 4.1.0

I - Création des classes d'objet

Avant d'installer highSlide JS et les autres éléments nécessaires au bon fonctionnement de la galerie photo, nous allons nous concentrer sur la réalisation de l'arborescence de contenu liée aux galeries photos.

Voici tout d'abord ce que nous souhaitons obtenir:

Img. 1: En violet pâle, l'arborescence à obtenir

Cette arborescence est obtenue à partir de trois classes d'objets différentes:

  • La classe par défaut Folder : c'est le dossier Photos.
  • La classe Dossier Galerie de photos : ce sont les dossiers:
    • Les bantous de la Capitale
    • Jazz
  • La classe Image music : ceux sont toutes les images

La classe Folder existant par défaut, voici à quoi ressemblent les deux nouvelles classes Dossier Galerie de photos et Image music :

La classe Dossier Galerie de photos

Pour créer une classe d'objet, cliquez sur l'onglet Administration de l'interface d'administration puis sur le lien Classes du menu gauche puis sur le lien Content du cadre Groupes de classes et enfin sur le bouton Nouvelle classe du cadre Classes dans <Content>.

:
Toutes les informations nécessaires à la compréhension du système de classes d'objets de eZ Publish se trouvent dans les 4 premiers articles de la section Gestion de contenu .

L'image ci-dessous illustre la structure de la classe d'objet Dossier Galerie de photos que j'ai créée:

La classe Image music

Cliquez sur l'onglet Administration de l'interface d'administration puis sur le lien Classes du menu gauche puis sur le lien Media du cadre Groupes de classes et enfin sur le bouton Nouvelle classe du cadre Classes dans <Media>.

L'image ci-dessous illustre la structure de la classe d'objet Image music que j'ai créée:

Le fichier de surcharge contentstruture.ini.append.php

Chaque fois qu'une nouvelle classe d'objet est créée, il est nécessaire d'ajouter son identifiant à la liste du tableau ShowClasses[] de la section [TreeMenu] du fichier de surcharge contentstruture.ini.append.php du siteaccess d'administration. Sans cela, la nouvelle classe ne sera pas visible dans le menu contextuel de l'onglet Contenus et ses instances ne seront pas affichées dans l'arborescence de contenu.

[TreeMenu]
Dynamic=enabled
ShowClasses[]
ShowClasses[]=article
ShowClasses[]=dossier_video
ShowClasses[]=folder
ShowClasses[]=gallery_photos  <==== CETTE LIGNE
ShowClasses[]=image_music    <==== CETTE LIGNE
ShowClasses[]=link
ShowClasses[]=user_group

Configuration du fichier de surcharge contentstruture.ini.append.php

Pensez à vider les caches chaque fois que vous modifiez un fichier de surcharge.

Ces deux classes créées, vous pouvez à présent reproduire l'arborescence comme illustrée par l'image 1.

II - Importer les fichiers javascript, CSS et autres

Ci-dessous, nous allons voir dans le détail l'ensemble des fichiers et répertoires propres à la galerie photo highSlide et nécessaires à son fonctionnement.

:
L'ensemble des éléments à installer (voir détails ci-dessous) sont intégrés à une archive que vous pouvez télécharger à partir de la page http://highslide.com/download.php . Cliquez sur le bouton Download now ! puis, au bas de la page qui s'affiche alors, sur le bouton Yes.

Le fichier highslide-with-gallery.js

Ce fichier, présent dans l'archive, peut également être téléchargé à partir de la page http://highslide.com/download.php . Vous prendrez au choix:

Placez ensuite ce fichier dans le sous-répertoire javascript/ du design du siteaccess public de votre site. Par exemple:

design/plain_site/javascript/highslide-with-gallery.js

:
Ce sous-répertoire n'existe peut-être pas par défaut sur votre installation. Créez-le puis affectez-lui les bons droits (en accord avec les valeurs des deux directives User et Group du fichier de configuration de votre serveur Apache).

Une méthode pour appeler ce nouveau fichier à partir du template pagelayout.tpl consiste à utiliser, dans l'en-tête de ce dernier, la syntaxe suivante:

{section name=JavaScript loop=ezini( 'JavaScriptSettings', 'JavaScriptList', 'design.ini' ) }
     <script language="JavaScript" type="text/javascript" src={concat( 'javascript/',$:item )|ezdesign}></script>
{/section}

...ce qui nécessite de modifier ainsi le tableau JavaScriptList[] de la section [JavaScriptSettings] du fichier de surcharge design.ini.append.php du siteaccess public:

[JavaScriptSettings]
JavaScriptList[]=highslide-with-gallery.js

En observant le code source de la page http://highslide.com/examples/mini-galleries.html on apprend qu'il faut par ailleurs ajouter dans l'en-tête du template pagelayout.tpl un certain nombre de lignes de javascript qui ne sont rien d'autre que des paramètres de surcharge permettant de régler à sa convenance le fonctionnement de la galerie photo.

Les lignes ci-dessous sont un copier/coller de celles présentes dans le code source de la page http://highslide.com/examples/mini-galleries.html :

{literal}
        <script type="text/javascript">
            hs.graphicsDir = '/design/plain_site/images/graphics/';  <= PENSEZ À BIEN PARAMÉTRER CE CHEMIN (VOIR PLUS BAS)
            hs.align = 'center';
            hs.transitions = ['expand', 'crossfade'];
            hs.outlineType = 'rounded-white';
            hs.fadeInOut = true;
            hs.numberPosition = 'caption';
            hs.dimmingOpacity = 0.75;
 
            // Add the controlbar
            if (hs.addSlideshow) hs.addSlideshow({
                //slideshowGroup: 'group1',
                interval: 5000,
                repeat: false,
                useControls: true,
                fixedControls: 'fit',
                overlayOptions: {
                    opacity: .75,
                    position: 'bottom center',
                    hideOnMouseOut: false
                }
            });
        </script>
    {/literal}

C'est tout en ce qui concerne javascript.

:
Si vous réalisez vos tests avec une version de eZ Publish installée dans un sous-répertoire du répertoire racine de votre serveur web (Voir valeur de la directive DocumentRoot du fichier de configuration de Apache), modifiez en conséquence, dans les lignes ci-dessus, la valeur du paramètre hs.graphicsDir = qui devra alors intégrer le nom du sous-répertoire.

Le fichier highslide.css

Cette feuille de styles, présente dans l'archive (une version de compatibilité avec IE6 est également incluse), contient les règles CSS relatives à différents fonctionnements de highSlide. Supprimer celles dont vous ne vous servirez pas.

Placez hightslide.css dans le sous-répertoire stylesheetst/ du design du siteaccess public de votre site. Par exemple:

design/plain_site/stylesheets/highslide.css

Une méthode pour appeler cette nouvelle feuille de styles à partir du template pagelayout.tpl consiste à utiliser, dans l'en-tête de ce dernier, la syntaxe suivante:

{section var=css_file loop=ezini( 'StylesheetSettings', 'CSSFileList', 'design.ini' )}
     <link rel="stylesheet" href={concat( 'stylesheets/', $css_file )|ezdesign} type="text/css" media="screen">
{/section}

...ce qui nécessite de modifier ainsi le tableau CSSFileList[] de la section [StylesheetSettings] du fichier de surcharge design.ini.append.php du siteaccess public:

[StylesheetSettings]
CSSFileList[]=core.css
CSSFileList[]=site.css
CSSFileList[]=classes.css
CSSFileList[]=debug.css
CSSFileList[]=highslide.css  <= CETTE LIGNE
CSSFileList[]=femoca.css

:
De nombreuses images du répertoire graphics/ (voir ci-dessous) sont insérées directement à partir de la feuille de style highslide.css. Pensez à adapter/modifier les chemins en accord avec votre configuration personnelle.

Le répertoire graphics

Ce répertoire, également présent dans l'archive, contient l'ensemble des éléments graphiques de l'afficheur.

Un emplacement possible de ce répertoire est:

design/plain_site/images/graphics/

En conséquence de quoi, tous les chemins présents par défaut dans la feuille de style highslide.css devront être de la forme:

../images/graphics/xxx.gif

III - Le template highSlide.tpl

Le template highSlide.tpl est bien sûr celui qui va afficher les galeries photos.

Règle de surcharge

La première chose à faire est la règle de surcharge indiquant au système d'utiliser le template highSlide.tpl lors de l'affichage du noeud Photos. Ce dernier étant une instance de la classe Folder, le template utilisé par défaut pour l'afficher est design/base/override/templates/node/view/ full.tpl. L'usage de ce template est lié à la régle de surcharge suivante:

[full_folder]
Source=node/view/full.tpl
MatchFile=full/folder.tpl
Subdir=templates
Match[class_identifier]=folder

...présente par défaut dans le fichier de surcharge override.ini.append.php du siteaccess public de votre site.

Vous devez donc créer au sommet du fichier override.ini.append.php une nouvelle surcharge ressemblant à ceci:

[gallery_highSlide]
Source=node/view/full.tpl
MatchFile=photos/highSlide.tpl
Subdir=templates
Match[node]=67

...où 67 reprensente le numéro de ID du noeud Photos (survolez le noeud avec le curseur de la souris pour en afficher le N°ID). Par ailleurs, les troisième et quatrième lignes indiquent au système de rechercher le template de surcharge highSlide.tpl dans le répertoire:

design/plain_site/override/templates/photos/

Le sous-répertoire photos/ n'existant pas par défaut il faudra bien sûr le créer.

Code du template highSlide.tpl

Pour connaître le code HTML que doit générer le code de ce template, le plus simple consiste à afficher le code source de la page d'exemple, c'est à dire de la page http://highslide.com/examples/mini-galleries.html .

Voici donc le code HTML que devra reproduire le template:

<!-- PREMIERE GALERIE -->
<div class="highslide-gallery">
     <a id="thumb1" href="../images/gallery1.jpg" class="highslide" onclick="return hs.expand(this, { slideshowGroup: 1 } )">
          <img src="../images/gallery1.thumb.jpg" alt="Highslide JS" title="Click to enlarge" />
     </a>
     <div class="highslide-caption">
          Caption for the first image. This caption can be styled using CSS.
     </div>
     <div class="hidden-container">
          <a href="../images/gallery2.jpg" class="highslide" onclick="return hs.expand(this, { thumbnailId: 'thumb1', slideshowGroup: 1 })"></a>
          <div class="highslide-caption">
               Caption for the second image in the first group.
          </div>
 
          <a href="../images/gallery3.jpg" class="highslide" onclick="return hs.expand(this, { thumbnailId: 'thumb1', slideshowGroup: 1 })"></a>
          <div class="highslide-caption">
               Caption for the third image in the first group.
          </div>
     </div>
</div>
 
<!-- DEUXIEME GALERIE -->
<div class="highslide-gallery">
     <a id="thumb2" href="../images/gallery1.jpg" class="highslide" onclick="return hs.expand(this, { slideshowGroup: 2} )">
          <img src="../images/gallery1.thumb.jpg" alt="Highslide JS" title="Click to enlarge" />
     </a>
     <div class="highslide-caption">
          Caption for the first image in the second group. This caption can be styled using CSS.
     </div>
     <div class="hidden-container">
          <a href="../images/gallery2.jpg" class="highslide" onclick="return hs.expand(this, { thumbnailId: 'thumb2', slideshowGroup: 2 })"></a>
          <div class="highslide-caption">
               Caption for the second image in the second group.
          </div>
 
          <a href="../images/gallery3.jpg" class="highslide" onclick="return hs.expand(this, { thumbnailId: 'thumb2', slideshowGroup: 2 })"></a>
          <div class="highslide-caption">
               Caption for the third image in the second group.
          </div>
     </div>
</div>

Et maintenant le code, agrémenté de nombreux commentaires, à insérer dans le template highSlide.tpl:

1 {* CE TEMPLATE PERMET DE CREER UNE GALERIE D'IMAGES highSlide *}
  2
  3 {*  $liste_galeries CONTIENT LA LISTE DES DOSSIERS INSTANCIES A PARTIR DE LA CLASSE gallery_photos *}
  4 {def    $liste_galeries=fetch_alias(    children,
  5                                         hash( 'parent_node_id', $node.node_id,
  6                                         depth, 1,
  7                                         class_filter_type, include,
  8                                         class_filter_array, array( 'gallery_photos' )))
  9         $i='1'}
 10 {* POUR CHAQUE DOSSIER DE LA CLASSE gallery_photos *}
 11 {foreach $liste_galeries as $gallery}
 12  <div class="highslide-gallery">
 13   {* SI LE DOSSIER CONTIENT DES IMAGES C'EST À DIRE S'IL CONTIENT DES OBJETS DE LA CLASSE image_music *}
 14   {if gt($gallery.children_count,0)}
 15    {* ALORS ON RECUPÈRE LE PREMIER OBJET image_music DANS LA VAIRIABLE $liste_images - CE PREMIER OBJET EST LA PREMIÈRE IMAGE DE LA GALERIE *}
 16    {def $liste_images=fetch_alias(  children,
 17                                     hash( 'parent_node_id', $gallery.node_id,
 18                                     depth, 1,
 19                                     limit, 1,
 20                                     class_filter_type, include,
 21                                     class_filter_array, array( 'image_music' )))}
 22    {* ET ON ECRIT LE CODE HTML QUI AFFICHERA LA VIGNETTE DE LA GALERIE TRAITÉE - C'EST LA PREMIÈRE IMAGE DE LA GALERIE *}
 23    <a id="thumb1" href={$liste_images.0.data_map.image.content.original.url|ezroot} class="highslide" {literal}onclick="return hs.expand(this, { slideshowGroup:{/literal} {$i} {literal}} )"{/literal}><img src={$liste_images.0.data_map.image.content.original.url|ezroot} alt="Highslide JS" title="Click to enlarge" /></a>
 24    {* PUIS ON ECRIT LE COMMENTAIRE LIÉ À CETTE PREMIÈRE VIGNETTE *}
 25    <div class="highslide-caption">{attribute_view_gui attribute=$liste_images.0.data_map.commentaire_image}</div>
 26    {* PUIS ON REGARDE S'IL EXISTE D'AUTRE IMAGES DANS LA GALERIE *}
 27    {if gt($gallery.children_count,1)}
 28     <div class="hidden-container">
 29      {* AUQUEL CAS ON RECUPÈRE LA LISTE DE CES AUTRES IMAGES - ON DECALE LE DÉBUT DE LA RECHERCHE À LA DEUXIÈME IMAGE: offset, 1 *}
 30      {def $liste_images1=fetch_alias(   children,
 31           hash( 'parent_node_id', $gallery.node_id,
 32           offset, 1,
 33           depth, 1,
 34           class_filter_type, include,
 35           class_filter_array, array( 'image_music' )))}
 36      {* ET POUR CHACUNE DE CES AUTRES IMAGES *}
 37      {foreach $liste_images1 as $image1}
 38       {* ON ÉCRIT LE CODE HTML NECESSAIRE À LEUR AFFICHAGE *}
 39       <a href={$image1.data_map.image.content.original.url|ezroot} class="highslide" {literal}onclick="return hs.expand(this, { thumbnailId: 'thumb1', slideshowGroup:{/literal} {$i} {literal} } )"{/literal} ></a>
 40       {* AINSI QUE LE COMMENTAIRE AFFÉRENT *}
 41       <div class="highslide-caption">{attribute_view_gui attribute=$image1.data_map.commentaire_image}</div>
 42      {/foreach}
 43     </div>
 44    {/if}
 45   {/if}
 46   {* ON ECRIT ICI LE TITRE DE LA GALERIE = LE NOM DU DOSSIER gallery_photos *}
 47   <div class="titreGalerie">{$gallery.data_map.nom_dossier.content}</div>
 48  </div>
 49  {* ON INCRÉMENTE LA VARIABLE $i DE UNE UNITÉ *}
 50  {set $i=inc( $i )}
 51 {/foreach}

IV - Vider les caches

Pour que tout fonctionne correctement, il ne reste plus qu'à vider les caches.

V - Suggestions

Si certains d'entre vous sont en mesure de proposer un code plus optimisé, n'hésitez pas à en faire profiter les lecteurs en laissant un commentaire sous l'article.

Commentaires

  • Merci

    Merci pour ce post, je m'en suis inspiré pour le site http://www.teline.fr/.
    Mathieu

    Merci !

    Bonjour

    Merci pour cette page qui m'a été d'une grande aide.
    J'ai intégré d'une façon un peu différente et je pense un peu plus "souple" :
    Je place les galleries dans la partie média.
    Ensuite là ou j'ai besoin d'une galerie (par exemple dans un article), j'insers l'objet galerie en mode full (avec le trombone)
    J'ai fait un override de type content/view/full.tpl au lieu de node/view/full.tpl
    Du coup le texte le template est un peu différent (je ne boucle pas sur les galleries du dossier car je suis déjà sur une gallerie et j'utilise $object au lieu de $node)

    Du coup je peux mettre des galeries ou je veux par simple insertion et je n'ai pas de références à des noeuds dans mon fichier d'override, donc mon client a la main pour ajouter librement du contenu dans son site.

    Par contre j'ai un petit pb la barre d'outils se trouve en plein milieu de mon image,... moyen mais je vais regarder.

    Voici le texte de mon template pour exemple :

    {* CE TEMPLATE PERMET DE CREER UNE GALERIE D'IMAGES highSlide *}

    <div class="highslide-gallery">

    {* SI LE DOSSIER CONTIENT DES IMAGES C'EST À DIRE S'IL CONTIENT DES OBJETS DE LA CLASSE image_music *}
    {def $i='1'}

    {if gt($object.main_node.children_count,0)}
    {* ALORS ON RECUPÈRE LE PREMIER OBJET image_music DANS LA VAIRIABLE $liste_images - CE PREMIER OBJET EST LA PREMIÈRE IMAGE DE LA GALERIE *}
    {def $liste_images=fetch_alias( children,
    hash( 'parent_node_id', $object.main_node.node_id,
    depth, 1,
    limit, 1,
    class_filter_type, include,
    class_filter_array, array( 'photo' )))}
    {* ET ON ECRIT LE CODE HTML QUI AFFICHERA LA VIGNETTE DE LA GALERIE TRAITÉE - C'EST LA PREMIÈRE IMAGE DE LA GALERIE *}
    <a id="thumb1" href={$liste_images.0.data_map.image.content.original.url|ezroot} class="highslide" {literal}onclick="return hs.expand(this, { slideshowGroup:{/literal} {$i} {literal}} )"{/literal}><img src={$liste_images.0.data_map.image.content.original.url|ezroot} alt="Highslide JS" title="Click to enlarge" /></a>
    {* PUIS ON ECRIT LE COMMENTAIRE LIÉ À CETTE PREMIÈRE VIGNETTE *}
    <div class="highslide-caption">{attribute_view_gui attribute=$liste_images.0.data_map.commentaire_image}</div>
    {* PUIS ON REGARDE S'IL EXISTE D'AUTRE IMAGES DANS LA GALERIE *}
    {if gt($object.main_node.children_count,1)}
    <div class="hidden-container">
    {* AUQUEL CAS ON RECUPÈRE LA LISTE DE CES AUTRES IMAGES - ON DECALE LE DÉBUT DE LA RECHERCHE À LA DEUXIÈME IMAGE: offset, 1 *}
    {def $liste_images1=fetch_alias( children,
    hash( 'parent_node_id', $object.main_node.node_id,
    offset, 1,
    depth, 1,
    class_filter_type, include,
    class_filter_array, array( 'photo' )))}
    {* ET POUR CHACUNE DE CES AUTRES IMAGES *}
    {foreach $liste_images1 as $image1}
    {* ON ÉCRIT LE CODE HTML NECESSAIRE À LEUR AFFICHAGE *}
    <a href={$image1.data_map.image.content.original.url|ezroot} class="highslide" {literal}onclick="return hs.expand(this, { thumbnailId: 'thumb1', slideshowGroup:{/literal} {$i} {literal} } )"{/literal} ></a>
    {* AINSI QUE LE COMMENTAIRE AFFÉRENT *}
    <div class="highslide-caption">{attribute_view_gui attribute=$image1.data_map.commentaire_image}</div>
    {/foreach}
    </div>
    {/if}
    {/if}
    {* ON ECRIT ICI LE TITRE DE LA GALERIE = LE NOM DU DOSSIER gallery_photos *}
    <div class="titreGalerie">{$object.main_node.data_map.nom_dossier.content}</div>
    </div>