Modifier le fichier

Gestion des Liens en Front

Table des matières

  1. Vue d'ensemble
  2. Architecture du système de liens
  3. LinkRule - Règles de traitement des liens
  4. Types de liens prédéfinis
  5. Affichage en front-office
  6. Surcharge et personnalisation côté projet
  7. Configuration

Vue d'ensemble

Le système de gestion des liens dans KSUP permet de :

  • Préparer et formater automatiquement les liens selon leur type (externe, interne, etc.)
  • Appliquer des règles métier sur les attributs des liens (target, rel, class, title)
  • Surcharger les comportements par défaut au niveau du projet
  • Gérer les liens multilingues (hreflang)

Architecture du système de liens

Composants principaux

LinkBuilderFactory
    ↓ utilise
LinkRule (abstract)
    ↓ implémente
[ExternalLinkRule, NotSameSiteLinkRule, HrefLangLinkRule, ...]
    ↓ applique sur
ILink (interface)

Fichiers clés

  • Core : core/koreparent/webapp-front/src/main/java/com/kosmos/link/

    • LinkBuilderFactory.java : Fabrique de liens avec injection des règles
    • LinkContext.java : Contexte de calcul contenant les données
    • LinkUtils.java : Utilitaires (détection liens externes, etc.)
    • rules/LinkRule.java : Classe abstraite de base
    • rules/ExternalLinkRule.java : Règle pour liens externes
    • rules/NotSameSiteLinkRule.java : Règle pour liens vers autres sites
    • rules/HrefLangLinkRule.java : Règle pour attributs hreflang
  • Configuration : core/koreparent/webapp-front/src/main/resources/core-front-link.xml


LinkRule - Règles de traitement des liens

Classe abstraite LinkRule

package com.kosmos.link.rules;

import org.springframework.core.Ordered;
import com.kosmos.link.LinkContext;
import fr.kosmos.web.kore.attributes.interfaces.ILink;

public abstract class LinkRule implements Ordered {

    protected String type;
    protected LinkUtils linkUtils;
    private int order;

    /**
     * Vérifie si la règle est applicable pour le contexte donné.
     * @param context le contexte de calcul du lien
     * @return true si la règle est applicable, false sinon
     */
    public boolean accept(final LinkContext context) {
        return !context.getOrElse(type, Boolean.class, Boolean.FALSE);
    }

    /**
     * Applique la règle au lien donné et indique dans le contexte
     * que la règle a été appliquée.
     * @param context le contexte de calcul du lien
     * @param link le lien à calculer
     */
    public void apply(final LinkContext context, final ILink link) {
        context.setValue(type, Boolean.TRUE);
    }

    // getters/setters...
}

Méthodes clés

MéthodeDescriptionUsage
accept(LinkContext)Détermine si la règle s'applique au contexteOverride pour ajouter des conditions
apply(LinkContext, ILink)Applique les modifications au lienOverride pour modifier les attributs du lien
getOrder()Ordre d'exécution (implements Ordered)Définit la priorité d'application

Types de liens prédéfinis

1. ExternalLinkRule

Fichier : com.kosmos.link.rules.ExternalLinkRule

Détection : Liens externes (domaine différent du site courant)

Attributs appliqués :

  • target : _blank (configurable)
  • title : Message i18n FO.LINK.EXTERNAL_SITE.TITLE
  • rel : noopener noreferrer (configurable)
  • class : Classes CSS personnalisables

Code :

public class ExternalLinkRule extends LinkRule {

    protected String target;
    protected String title;
    protected String relation;
    protected String classes;

    public ExternalLinkRule() {
        this.type = "externalLinkRule";
    }

    @Override
    public boolean accept(final LinkContext context) {
        return super.accept(context)
            && linkUtils.isExternal(context.getUrl());
    }

    @Override
    public void apply(final LinkContext context, final ILink link) {
        super.apply(context, link);
        link.setTarget(target);
        link.setTitle(MessageHelper.getCoreMessage(title));
        link.setRelation(relation);
        link.setClasses(classes);
    }

    // setters...
}

2. NotSameSiteLinkRule

Fichier : com.kosmos.link.rules.NotSameSiteLinkRule

Détection : Liens vers d'autres sites de la même plateforme

Attributs appliqués :

  • target : _blank (configurable)
  • title : Message i18n FO.LINK.NOT_SAME_SITE.TITLE
  • class : Classes CSS personnalisables

3. HrefLangLinkRule

Fichier : com.kosmos.link.rules.HrefLangLinkRule

Détection : Liens multilingues

Attributs appliqués :

  • hreflang : Code langue du lien cible

Variantes :

  • RelativeUrlHrefLangLinkRule : Pour URLs relatives
  • AbsoluteUrlHrefLangLinkRule : Pour URLs absolues

Affichage en front-office

L'affichage de lien en front-office est géré par la composant kuik:link.

Exemple d'utilisation du composant :

<kuik:link link="${userItem.link}" class="menu-list__link">
    <c:if test="${not empty userItem.icon}">
        <kuik:icon-content icon="${userItem.icon}" class="icon-content--centered" iconTitle="">
            <c:out value="${userItem.title}"/>
        </kuik:icon-content>
    </c:if>
</kuik:link>

Le composant prend en paramètre un objet fr.kosmos.web.kore.attributes.interfaces.ILink et peut contenir un body.

Voir la documentation du composant link.


Surcharge et personnalisation côté projet

Surcharge d'une règle existante

Exemple : Personnalisation de ExternalLinkRule pour le menu QuickAccess

Création d'un preparer spacifique pour le menu dans le projet pour indiquer dans le context que l'on prépare le menu QuickAccess :

package com.kosmos;

import java.util.Map;

import com.kosmos.context.front.FrontContext;
import com.kosmos.menu.quickaccess.QuickAccessViewModel;
import com.kosmos.menu.quickaccess.QuickAccessViewPreparer;
import com.univ.objetspartages.bean.RubriqueBean;

import fr.kosmos.web.kore.attributes.interfaces.QuickAccessMenu;

public class DevQuickAccessViewPreparer extends QuickAccessViewPreparer {

  @Override
  public QuickAccessViewModel prepare(final FrontContext context, final Map preparers) {
    context.setValue("menu", "quickaccess");
    return super.prepare(context, preparers);
  }

  @Override
  protected QuickAccessMenu populateQuickAccessMenu(final RubriqueBean section, final FrontContext context) {
    context.setValue("menuItem", section);
    return super.populateQuickAccessMenu(section, context);
  }
}

Création de la règle de calcul du lien externe qui étend ExternalLinkRule pour les quickAccess :

package com.kosmos;

import com.kosmos.link.LinkContext;
import com.kosmos.link.rules.ExternalLinkRule;
import com.univ.objetspartages.bean.RubriqueBean;

/**
 * Règle personnalisée pour les liens externes du menu "Quick Access"
 * avec un item spécifique "yolo".
 */
public class QuickAccessExternalLinkRule extends ExternalLinkRule {

    @Override
    public boolean accept(final LinkContext context) {
        // Applique la règle parent ET les conditions spécifiques
        return super.accept(context)
            && context.get("menu", String.class).equals("quickaccess")
            && context.get("menuItem", RubriqueBean.class).getIntitule().equals("yolo");
    }

    @Override
    public void apply(final LinkContext context, final ILink link) {
        super.apply(context, link);

        // Personnalisations supplémentaires
        link.setClasses(link.getClasses() + " quick-access-external");
    }
}

Déclaration de la règle :

<bean id="quickAccessExternalLinkRule"
      class="com.kosmos.QuickAccessExternalLinkRule"
      parent="linkRule">
    <property name="target" value="_blank" />
    <property name="title" value="CUSTOM.LINK.QUICK_ACCESS.TITLE" />
    <property name="relation" value="noopener noreferrer" />
    <property name="classes" value="external-link quick-access" />
    <property name="order" value="-1000" />
</bean>

Méthode 2 : Création d'une nouvelle règle

Exemple : Règle pour liens PDF

Création d'un nouvelle classe de règle qui étend LinkRule :

package com.kosmos;

import com.kosmos.link.LinkContext;
import com.kosmos.link.rules.LinkRule;
import fr.kosmos.web.kore.attributes.interfaces.ILink;
import org.apache.commons.lang3.StringUtils;

/**
 * Règle pour les liens vers fichiers PDF.
 * Ajoute des attributs spécifiques : icône, tracking, download.
 */
public class PdfLinkRule extends LinkRule {

    private String pdfIcon;
    private boolean forceDownload;

    public PdfLinkRule() {
        this.type = "pdfLinkRule";
    }

    @Override
    public boolean accept(final LinkContext context) {
        return super.accept(context)
            && context.getUrl() != null
            && context.getUrl().toLowerCase().endsWith(".pdf");
    }

    @Override
    public void apply(final LinkContext context, final ILink link) {
        super.apply(context, link);

        // Ajout d'une classe CSS spécifique
        String currentClasses = link.getClasses();
        link.setClasses(StringUtils.isNotBlank(currentClasses) ? currentClasses + " pdf-link" : "pdf-link");


        // Title personnalisé
        String title = link.getTitle();
        link.setTitle(StringUtils.isNotBlank(title) ? title + " (PDF)" : "Document PDF");
    }

    private String extractFileName(String url) {
        return url.substring(url.lastIndexOf('/') + 1);
    }
}

Déclaration de la règle :

<bean id="pdfLinkRule"
      class="com.kosmos.PdfLinkRule"
      parent="linkRule">
    <property name="order" value="-1000" />
</bean>

Configuration

Configuration Spring

Fichier : core-front-link.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- Factory principale -->
    <bean id="linkBuilderFactory" class="com.kosmos.link.LinkBuilderFactory">
        <property name="rules">
            <bean class="com.kosmos.factory.CoreBeanListFactoryBean">
                <property name="beanType" value="com.kosmos.link.rules.LinkRule"/>
            </bean>
        </property>
    </bean>

    <!-- Utilitaires -->
    <bean id="linkUtils" class="com.kosmos.link.LinkUtils">
        <property name="serviceInfosSite" ref="serviceInfosSiteProcessus" />
    </bean>

    <!-- Bean parent abstrait -->
    <bean id="linkRule" class="com.kosmos.link.rules.LinkRule" abstract="true">
        <property name="linkUtils" ref="linkUtils" />
    </bean>

    <!-- Règles prédéfinies -->
    <bean id="notSameSiteLinkRule"
          class="com.kosmos.link.rules.NotSameSiteLinkRule"
          parent="linkRule">
        <property name="target" value="${link.not_same_site.target}" />
        <property name="title" value="FO.LINK.NOT_SAME_SITE.TITLE" />
        <property name="classes" value="${link.not_same_site.classes}" />
    </bean>

    <bean id="externalLinkRule"
          class="com.kosmos.link.rules.ExternalLinkRule"
          parent="linkRule">
        <property name="target" value="${link.external_site.target}" />
        <property name="title" value="FO.LINK.EXTERNAL_SITE.TITLE" />
        <property name="relation" value="${link.external_site.relation}" />
        <property name="classes" value="${link.external_site.classes}" />
    </bean>

    <bean id="relativeUrlHrefLangLinkRule"
          class="com.kosmos.link.rules.RelativeUrlHrefLangLinkRule"
          parent="hrefLangLinkRule" />

    <bean id="absoluteUrlHrefLangLinkRule"
          class="com.kosmos.link.rules.AbsoluteUrlHrefLangLinkRule"
          parent="hrefLangLinkRule" />
</beans>

Configuration properties

Fichier : application_core.properties

# Liens externes
link.external_site.target=_blank
link.external_site.relation=noopener noreferrer
link.external_site.classes=external-link

# Liens vers autres sites
link.not_same_site.target=_blank
link.not_same_site.classes=same-platform-link

Messages i18n

Fichier : Message_fr_FR.properties

FO.LINK.EXTERNAL_SITE.TITLE=Lien externe - Nouvelle fenêtre
FO.LINK.NOT_SAME_SITE.TITLE=Lien vers un autre site - Nouvelle fenêtre
LINK_TYPE.EXTERNAL.LABEL=URL du lien externe
LINK_TYPE.EXTERNAL.TIP=Saisissez l'URL complète (ex: https://example.com)
LINK_STYLE.GENERAL.LINK.LABEL=Style du lien
LINK_TYPE.GENERAL.LINK.LABEL=Texte du lien

Ordre d'application des règles

Les règles sont appliquées selon leur propriété order (Ordered interface) :

Plus le order est bas, plus la règle est prioritaire.


Bonnes pratiques

  1. Toujours appeler super.accept() et super.apply() dans les surcharges
  2. Utiliser des noms de type uniques pour éviter les conflits
  3. Définir un ordre approprié selon la spécificité de la règle