Modifier le fichier

Tutoriel : Mise en place d'une personnalisation projet d'un affichage d'une fiche

K-Sup est conçu pour servir de socle commun à différents projets clients, chacun ayant ses propres besoins fonctionnels. Pour éviter toute duplication ou modification du produit, des mécanismes de surcharge permettent aux projets de personnaliser ou d’enrichir le socle sans le modifier.

Plusieurs approches sont possibles pour adapter l’affichage ou le comportement.

Pendant ce tutoriel, nous allons prendre l'exemple de l'extension Pagelibre, dont un projet va souhaiter personnaliser différents aspects.

1. Mécanismes de surcharge dans K-Sup

Le socle K-Sup repose sur une architecture modulaire avec des extensions et des contextes Spring isolés. Il offre plusieurs mécanismes de surcharge permettant aux projets de personnaliser leur comportement ou leur interface :

  • Surcharge de la configuration Spring
  • Surcharge de beans, notamment les ViewPreparer (ou le modèle) et les CardViewBuilder
  • Surcharge des vues JSP Ces mécanismes permettent aux projets d’intervenir uniquement sur les points nécessaires sans impacter les autres extensions ou le cœur du produit.

2. Surcharge de la configuration Spring

2.1 Description de la fonctionnalité

Chaque extension dispose de son propre contexte Spring, isolé. Les projets peuvent surcharger les beans en déclarant leur propre configuration XML, sans impacter le produit ou les autres extensions.

Ce mécanisme permet de modifier la valeur d’un ou plusieurs attributs d’un bean, ou de le redéfinir totalement.

2.2 Architecture générale

Prenons l’exemple du bean pagelibreContentViewPreparer :

<bean id="pagelibreContentViewPreparer" class="com.kosmos.pagelibre.PagelibreContentViewPreparer" parent="contentViewPreparer">
    <property name="type" value="content"/>
    <property name="view" value="/extensions/pagelibre/WEB-INF/jsp/pagelibre-content.jsp"/>
    <property name="expectedViewTypes">
        <value>contentBox</value>
    </property>
</bean>
  • type : permet à un autre viewPreparer, comme un preparer de template, de demander à ce que soit préparé un certain type de bean.

  • view : correspond au chemin vers la JSP du modèle à afficher.

  • expectedViewTypes : liste les types de vues qui seront préparés via AbstractViewPreparer.prepareExpectedViews(). Ce mécanisme permet notamment à un template d’utiliser des sous-vues (header, body, content…) sans connaître leur implémentation exacte. Il existe également d'autres paramètres communs:

  • includedSiteTemplate : indique la liste des template ou ce preparer doit être utilisé

  • excludedSiteTemplate : indique la liste des template ou ce preparer NE doit Pêtre utilisé

  • order : priorise le bean lors de la recherche de beans.

2.3 Procédure

Pour surcharger ce bean, il suffit de créer un fichier XML dans le dossier resources/spring du projet.

Ce fichier doit être explicitement importé par le fichier de contexte de l’extension concernée. Par exemple, dans l’extension Pagelibre :

<!-- Ouverture à la surcharge projet -->
<import resource="classpath*:spring/pagelibre-override.xml"/>

On place alors dans resources/spring/pagelibre-override.xml une redéfinition partielle ou totale du bean concerné, selon les besoins du projet.

3. Cas d’usage : surcharge d’un ViewPreparer

La surcharge de configuration Spring est souvent utilisée pour injecter des beans spécifiques dans le projet. Un cas fréquent est celui des ViewPreparer, introduits dans le cadre de la refonte des vues dynamiques.

3.1 Fonctionnement général des ViewPreparer

Chaque ViewPreparer fournit un modèle (ViewModel) associé à une vue, utilisable dans une JSP.

Lorsqu’un contrôleur est appelé, il demande une vue adaptée à son contexte. Le système parcourt les ViewPreparer déclarés en tant que beans Spring et sélectionne le premier qui accepte de préparer la vue (via la méthode accept()).

3.2 Surcharge via Spring : injection du nouveau bean

Un projet peut vouloir injecter son propre ViewPreparer, plus prioritaire que celui du socle. Il suffit pour cela :

  1. De créer un bean dans un fichier -override.xml
  2. De le rendre prioritaire via la propriété order
  3. D’utiliser un parent pour hériter de la configuration existante

Exemple : Ajout de la date en haut des pages libres

<!-- Pagelibre avec affichage de la date de mise à jour -->
<bean id="datedPagelibreContentViewPreparer" class="com.kosmos.pagelibre.DatedPagelibreContentViewPreparer" parent="pagelibreContentViewPreparer">
    <property name="order" ref="ORDRE_CRITIQUE"/>
    <property name="view" value="/WEB-INF/jsp/pagelibre/pagelibre-content.jsp"/>
</bean>

Définir un order plus prioritaire que celui du bean par défaut est indispensable pour que ce nouveau bean soit sélectionné.

Bonne pratique : utiliser la constante Spring suivante pour avoir la priorité la plus haute possible :

<util:constant id="ORDRE_CRITIQUE" static-field="org.springframework.core.Ordered.HIGHEST_PRECEDENCE"/>

3.3 Surcharge via Java : redéfinition du comportement prepare()

Dans la classe Java associée au nouveau bean, on peut redéfinir le comportement métier, tout en conservant celui du bean parent.

Exemple Java

public class DatedPagelibreContentViewPreparer extends PagelibreContentViewPreparer<PagelibreContentViewModel> {

    @Override
    public PagelibreContentViewModel prepare(final FrontContext frontContext, final Map<String, List<IViewPreparer>> preparers) {
        final PagelibreContentViewModel pagelibreContentViewModel = super.prepare(frontContext, preparers);
        final ContentContext contentContext = ContentContext.of(frontContext);
        final PagelibreBean bean = contentContext.getContent();
        pagelibreContentViewModel.setPublicationDate(PublicationDateProcessor.process(
            contentContext.getMetatag().getMetaDateMiseEnLigne(),
            bean.getDateModification()
        ));
        return pagelibreContentViewModel;
    }
}

Ce mécanisme permet de personnaliser complètement la donnée injectée dans la JSP sans perturber les autres composants.

3.4 Surcharge du ViewModel (optionnel)

Il est également possible d’utiliser un ViewModel différent pour y injecter des attributs supplémentaires spécifiques au projet. Il faut alors :

  • Définir un nouveau modèle Java
  • Adapter la JSP en conséquence (voir section suivante)

4. Surcharge de JSP

4.1 Description de la fonctionnalité

L’interface peut être adaptée en redéfinissant les fragments JSP utilisés. Deux approches principales sont possibles :

  • Surcharge par redéfinition à l'identique
  • Surcharge par modification du chemin dans le bean

4.2 Surcharge par redéfinition du fichier à l'identique

Il s’agit de redéfinir un fichier JSP à l’identique dans le projet.

Le fichier du projet, s’il est trouvé à un chemin identique, sera utilisé à la place de celui du socle.

Exemple : surcharge de la JSP Pagelibre

Le bean pagelibreContentViewPreparer utilise la JSP suivante :

/WEB-INF/jsp/pagelibre/pagelibre-content.jsp

Pour la surcharger, il faut créer dans le projet le fichier suivant :

src/main/webapp/WEB-INF/jsp/pagelibre/pagelibre-content.jsp

Le moteur de rendu utilisera automatiquement la version projet s’il la trouve à cet emplacement.

4.3 Surcharge par changement de chemin de vue

Une autre solution consiste à ne pas surcharger par overlay, mais à déclarer un nouveau chemin de JSP dans un bean surchargé. Cela permet d’avoir un fichier au nom différent, plus clair, et de coexister avec la version produit sans la masquer.

Exemple dans le bean projet :

<property name="view" value="/WEB-INF/jsp/pagelibre/pagelibre-content-projet.jsp"/>

Cette méthode est particulièrement utile pour éviter toute ambiguïté ou écrasement involontaire.

Attention, il n'est parfois pas nécessaire de surcharger une vue entièrement pour modifier l'affichage. Si l'élément à modifier est défini par une propriété (comme il est courant pour les messages), il suffit de surcharger cette propriété via un fichier properties.