Typo3 : Le CMS

Typo3 : un CMS puissant, ouvert et pas assez ergonomique

Typo3 est un outil de CMS très répandu. Je l'ai rencontré il y a déjà de nombreuses années.

Son interface d'administration est riche et permet d'atteindre les fonctionnalités poussées d'un CMS moderne :

  • Multisites
  • Templating graphique
  • Structure souple des pages
  • Ouverture avec des extensions (plusieurs milliers!!)

Avec toutes ces caractéristiques, la question que chacun se pose est "pourquoi n'est-il pas plus répandu?" La réponse est simple : Sans formation, un utilisateur non informaticien ne saura pas se débrouiller.

C'est bien dommage !

Néanmoins, je continue de l'utiliser pour maintenir ce site et ceux de mes projets personnels et je ne suis pas déçu. Limité un moment par l'hébergement de Free, le passage à SiteGround puis à ads-COM a bien changé les possibilités de Typo3 et donc de ce site. J'ai pu passer à la dernière version et l'utilisation d'ImageMagick offre une grand capacité de présentation des images et photos.

Utilisation de Bootstrap

Bootstrap est devenu incontournable pour les sites internet. Il offre une grande souplesse, des fonctionnalités riches et une gestion efficace du responsive : Vos mobiles peuvent lui dire merci!

Néanmoins, la mise en œuvre au sein d'un CMS n'est pas toujours évidente. Souvent, cela requiert des développements, une intégration complète, de la compilation Less et une bonne dose de maîtrise de l'ensemble.

Et bien, avec Typo3 et l'extension bootstrap_package, c'est tout le contraire. C'est super simple, sans pour autant devoir rester dans un carcan trop rigide.

J'ai ainsi pu migrer mon site du système classique de template de Typo3 à une intégration "fluid" basée sur Bootstrap 3. En attendant le 4...

Une extension pour intégrer mon site

Les bonnes pratiques Typo3 amènent à créer sa propre extension afin d'y faire figurer sa propre intégration. Sur la base de l'extension bootstrap_package, à coup de surcharges, il est aisé d'ajouter ou d'ajuster tel ou tel fonctionnement : C'est vraiment séduisant et souple.

Je suis parti de l'extension basetemplate8 que j'ai épurée et largement customisée. Cela m'a permis d'appréhender d'avantage le système d'extensions sous Typo3 8.x.

J'ai pu intégrer les éléments suivants :

  • Les classiques JS, CSS, images qui complètent ceux de l'extension bootstrap 
  • Quelques templates (navigation, template global,...) liés à des contenus ont été surchargés, c'est à dire simplement recopiés depuis l'extension bootstrap, placés dans mon extension au même endroit et enfin ces templates fluid peuvent être remaniés à façon.
  • Quelques lignes de typoscript pour ajuster quelques définitions pour la présentation mais aussi la contribution.
  • Configurer directement depuis typo3 les paramètres, nombreux, que propose l'extension bootstrap

Le menu de navigation

Le menu de navigation Bootstrap est bien un classique, mais il a comme un défaut. Il n'affiche que 2 niveaux de profondeur. Ce n'est pas très pratique à mon sens, car pour accéder à une page assez profonde, il faut alors passer de pages en pages : C'est trop long.

J'ai donc utilisé une surcharge du menu de navigation afin d'implémenter une partial récursif qui affiche le menu avec une profondeur potentiellement infinie.

{namespace emmguyot=Emmguyot\Persotemplate8\ViewHelpers}
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:if condition="{currentLevel} < {stopRecursionOnLevel}">
	<f:alias map="{ nextLevel : '{emmguyot:Increment(i : currentLevel)}' }">
		<f:if condition="{mainnavigationItem.spacer}">
           <f:then>
               </ul>
               <ul class="nav navbar-nav navbar-main">
           </f:then>
           <f:else>
               <li class="{f:if(condition: mainnavigationItem.active, then:'active')} {f:if(condition: mainnavigationItem.children, then:'dropdown')}">
                   <f:if condition="{mainnavigationItem.children}">
                       <f:then>
                           <a href="{mainnavigationItem.link}"{f:if(condition: mainnavigationItem.target, then: ' target="{mainnavigationItem.target}"')} title="{mainnavigationItem.title}" class="dropdown-link">
                               <f:if condition="{mainnavigationItem.icon}">
                                   <span class="navbar-item-icon">
                                       <f:image image="{mainnavigationItem.icon.0}" alt="{mainnavigationItem.icon.0.alternative}" title="{mainnavigationItem.icon.0.title}" width="{settings.navigation.icon.width}" height="{settings.navigation.icon.height}" />
                                   </span>
                               </f:if>
                               <span class="navbar-item-text">{mainnavigationItem.title}</span>
                               <b class="caret"></b>
                               <span class="bar"></span>
                           </a>
                           <ul class="dropdown-menu {f:if(condition: '{nextLevel} > 2', then:'.hidden-md .hidden-lg')}">
                               <f:for each="{mainnavigationItem.children}" as="child">
                               		<f:render partial="Navigation/MainRecursivePart" arguments="{
													mainnavigationItem : child,
													currentLevel : nextLevel,
													stopRecursionOnLevel : stopRecursionOnLevel}"
									/>
                               </f:for>
                           </ul>
                       </f:then>
                       <f:else>
                           <a href="{mainnavigationItem.link}"{f:if(condition: mainnavigationItem.target, then: ' target="{mainnavigationItem.target}"')} title="{mainnavigationItem.title}">
                               <f:if condition="{mainnavigationItem.icon}">
                                   <span class="navbar-item-icon">
                                       <f:image image="{mainnavigationItem.icon.0}" alt="{mainnavigationItem.icon.0.alternative}" title="{mainnavigationItem.icon.0.title}" width="{settings.navigation.icon.width}" height="{settings.navigation.icon.height}" />
                                   </span>
                               </f:if>
                               <span class="navbar-item-text">{mainnavigationItem.title}</span>
                               <span class="bar"></span>
                           </a>
                       </f:else>
                   </f:if>
               </li>
           </f:else>
       </f:if>
    </f:alias>
</f:if>

Et comment ça se met à jour?

Faire la première intégration est assez simple, mais lorsqu'il s'agit de mettre à jour l'extension bootstrap_package, ça se complique un peu.

En effet, comme j'avais fait différentes surcharges des templates initiaux, le passage de la version 9.1 à 10 de bootstrap_package est assez compliqué car les templates ont largement été réécrits. En l'occurrence, le menu de navigation a été totalement refait. Dans ce cas, il n'y a pas trop de choix : Il faut recommencer l'intégration.

Du coup, j'ai implémenté le menu SmartMenus basé sur JQuery. Hormis quelques retouches CSS, je devrais être tranquille pour la prochaine mise à jour.

Globalement, ces problèmes de mise à jour constituent la limite de cette solution basée sur une extension qui se doit d'évoluer mais dont le système de surcharge, même s'il est simple, n'est pas un optimum de maintenabilité.