Ce site met a disposition le build journalier de la traduction francaise du Maven: The Definitive Guide
Consultez :
  • Les documents de reference sur le projet original
  • Les sources de la traduction fr sur GitHub
  • maven


    10.7.2. Créer un modèle de site personnalisé

    Si la structure du site Maven par défaut ne vous convient pas, vous pouvez toujours personnaliser son modèle. Grâce à cela, il est possible de contrôler complètement le résultat du plugin Maven Site. Il est également possible de personnaliser le modèle du site de telle sorte que vous ne reconnaissiez pas la structure du modèle par défaut.

    Le plugin Maven Site utilise le moteur de rendu Doxia, qui utilise à son tour en interne un modèle Velocity pour effectuer le rendu de chaque page. Pour changer la structure d'une page, il est possible de configurer le plugin Site à partir du POM pour utiliser un modèle personnalisé. Comme le modèle du site est relativement complexe, il est préférable de disposer d'un bon point de départ pour effectuer votre personnalisation. Commencez par copier le modèle Velocity par défaut de Doxia, qui est disponible sur le dépôt Subversion de Doxia, default-site.vm dans le fichier src/site/site.vm. Ce fichier s'appuie donc une syntaxe Velocity. Velocity est un language simple pour écrire et appliquer des modèles. Il supporte la définition de macros et permet l'accès aux méthodes et propriétés des objets en utilisant un formalisme simple. Une présentation plus détaillée de la syntaxe de ce framework n'est pas l'objet de ce livre, aussi, pour plus d'informations sur Velocity, référez-vous au site officiel du projet à l'adresse suivante http://velocity.apache.org.

    Si le modèle default-site.xml est assez complexe, les modifications nécessaires à la personnalisation du menu gauche sont relativement simples. Si vous voulez modifier l'apparence d'un menuItem, rechercher la macro Velocity du même nom. Elle se trouve dans une section qui ressemble à cela :

    #macro ( menuItem $item )
    
      ...
      
    #end
    

    Si vous replacez la définition de la macro par celle présentée ci-dessous, vous injecterez du javascript dans chaque élément du menu pour fermer et ouvrir l'arbre sans avoir à recharger entièrement la page :

    #macro ( menuItem $item $listCount )
      #set ( $collapse = "none" )
      #set ( $currentItemHref = $PathTool.calculateLink( $item.href, 
                                                         $relativePath ) )
      #set ( $currentItemHref = $currentItemHref.replaceAll( "\\", "/" ) )
    
      #if ( $item && $item.items && $item.items.size() > 0 )
        #if ( $item.collapse == false )
          #set ( $collapse = "collapsed" )
        #else
          ## By default collapsed
          #set ( $collapse = "collapsed" )
        #end
    
        #set ( $display = false )
        #displayTree( $display $item )
    
        #if ( $alignedFileName == $currentItemHref || $display )
          #set ( $collapse = "expanded" )
        #end
      #end
      <li class="$collapse">
        #if ( $item.img )
          #if ( ! ( $item.img.toLowerCase().startsWith("http") || 
                    $item.img.toLowerCase().startsWith("https") ) )
            #set ( $src = $PathTool.calculateLink( $item.img, $relativePath ) )
            #set ( $src = $item.img.replaceAll( "\\", "/" ) )
            <img src="$src"/>
          #else
            <img src="$item.img" align="absbottom" style="border-width: 0"/>
          #end
        #end
        #if ( $alignedFileName == $currentItemHref )
          <strong>$item.name</strong>
        #else
          #if ( $item && $item.items && $item.items.size() > 0 )
          <a onclick="expand('list$listCount')" 
                style="cursor:pointer">$item.name</a>
          #else
          <a href="$currentItemHref">$item.name</a>
          #end
        #end
      #if ( $item && $item.items && $item.items.size() > 0 )
        #if ( $collapse == "expanded" )
        <ul id="list$listCount" style="display:block">
        #else
        <ul id="list$listCount" style="display:none">
          #end
          #foreach( $subitem in $item.items )
            #set ( $listCounter = $listCounter + 1 )
            #menuItem( $subitem $listCounter )
          #end
        </ul>
      #end
      </li>
    #end
    

    Cette modification rajoute un nouveau paramètre à la macro menuItem. Pour que cette modification fonctionne, vous devez donc mettre à jour toutes les références à cette macro; dans le cas contraire, le XHTML résultant sera incorrect ou incomplet. Pour effectuer ces mises à jour, apportez la même modification à la macro mainMenu. Trouvez cette macro en recherchant un bloc semblable à celui-là :

    #macro ( mainMenu $menus )
      ...
    #end
    

    Remplacez maintenant la macro mainMenu avec cette implémentation :

    #macro ( mainMenu $menus )
      #set ( $counter = 0 )
      #set ( $listCounter = 0 )
      #foreach( $menu in $menus )
        #if ( $menu.name )
        <h5 onclick="expand('menu$counter')">$menu.name</h5>
        #end
        <ul id="menu$counter" style="display:block">
          #foreach( $item in $menu.items )
            #menuItem( $item $listCounter )
            #set ( $listCounter = $listCounter + 1 )
          #end
        </ul>
        #set ( $counter = $counter + 1 )
      #end
    #end
    

    Cette nouvelle macro mainMenu est entièrement compatible avec la version précédente, elle fournit un support javascript aux éléments racines du menu. Un clic sur un de ces éléments racines permet aux utilisateurs d'afficher l'arbre complet dans devoir attendre le chargement de la page.

    La mise à jour de la macro menuItem rajoute un appel à une fonction javascript expand(). Cette fonction doit donc être ajoutée au template XHTML principal, par exemple en bas du modèle. Recherchez la section avec un contenu ressemblant à ceci :

      <head>
        ...
        <meta http-equiv="Content-Type" 
                 content="text/html; charset=${outputEncoding}" />
        ...
      </head>
    

    et remplacez-la avec ce contenu :

      <head>
        ...
        <meta http-equiv="Content-Type" 
                 content="text/html; charset=${outputEncoding}" />
        <script type="text/javascript">
          function expand( item ) {
            var expandIt = document.getElementById( item );
            if( expandIt.style.display == "block" ) {
              expandIt.style.display = "none";
              expandIt.parentNode.className = "collapsed";
            } else {
              expandIt.style.display = "block";
              expandIt.parentNode.className = "expanded";
            }
          }
        </script>
        #if ( $decoration.body.head )
          #foreach( $item in $decoration.body.head.getChildren() )
            #if ( $item.name == "script" )
              $item.toUnescapedString()
            #else
              $item.toString()
            #end
          #end
        #end
      </head>
    

    Après avoir modifié le modèle du site, vous devez mettre à jour le POM de votre projet pour qu'il utilise votre nouveau modèle. Pour personnaliser le modèle du site, vous devez utiliser la balise templateDirectory dans les propriétés de configuration du plugin Maven Site.

    Exemple 10.10. Personnaliser le modèle de page dans le POM du projet

    <project>
      ...
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-site-plugin</artifactId>
            <configuration>
              <templateDirectory>src/site</templateDirectory>
              <template>site.vm</template>
            </configuration>
          </plugin>
        </plugins>
      </build>
      ...
    </project>
    


    Vous devriez pouvoir maintenant regénérer le site de votre projet. En effectuant cela, vous pourrez remarquer que les ressources et CSS du site Maven manquent. Lorsqu'un projet Maven personnalise le template du site, le plugin Maven Site s'attend que le projet fournisse toutes les images et CSS. Pour obtenir les ressources initiales pour le site de votre projet, le plus simple reste de les copier à partir du dépot Subversion du projet de modèle par défaut de Doxia. Cela peut se faire en exécutant les commandes suivantes :

    $ svn co \
            http://svn.apache.org/repos/asf/maven/doxia/doxia-sitetools/\
             trunk/doxia-site-renderer
    $ rm \
            doxia-site-renderer/src/main/resources/org/apache/maven/\
              doxia/siterenderer/resources/css/maven-theme.css
    $ cp -rf \
          doxia-site-renderer/src/main/resources/org/apache/maven/\
            doxia/siterenderer/resources/* \
          sample-project/src/site/resources
    

    Récupérez le projet doxia-site-renderer et copiez toutes ses ressources dans le répertoire src/site/resources de votre projet.

    Lorsque vous regénérez un site, vous pouvez remarquer également que certains éléments du menu ne possédent pas de style CSS. Cela est dû à une mauvaise intégration entre la CSS du site et votre modèle personnalisé. Pour corriger cela, modifiez votre fichier site.css pour changer la couleur de vos liens dans le menu en ajoutant les lignes suivantes :

    li.collapsed, li.expanded, a:link {
      color:#36a;
    }
    

    Après avoir regénéré le site, la couleur du lien du menu devrait être réparée. Si vous appliquez le nouveau modèle au projet sample-project de ce chapitre, vous noterez que le menu s'affiche maintenant sous la forme d'un arbre. Un clic sur "Developer Resources" ne vous emmène plus sur la page du même nom ; à la place, son sous-menu est affiché. Du coup, suite à la modification de l'élément "Developer Resources" en un sous-menu dynamique, vous ne pouvez plus accéder à la page developer/index.apt. Le plus simple reste donc d'ajouter au sous-menu un élément "Overview" qui pointe sur cette même page :

    Exemple 10.11. Ajouter un élément du menu dans le descripteur de site

    <project name="Hello World">
      ...
      <menu name="Main Menu">
        ...
        <item name="Developer Resources" collapse="true">
          <item name="Overview" href="/developer/index.html"/>
          <item name="System Architecture" href="/developer/architecture.html"/>
          <item name="Embedder's Guide" href="/developer/embedding.html"/>
        </item>
      </menu>
      ...
    </project>