Des templates Scriban pour rendre des SXA variantes complexes

This article in english

Lors de la création de mes propres variantes de rendu dans SXA, j’étais souvent frustré par la rigidité des éléments disponibles pour créer la structure HTML du composant. Par exemple, il était presque impossible de rendre facilement la valeur d’une liste déroulante ou de récupérer des paramètres de rendu (rendering parameters). Créer des variantes de rendu complexes, avec des classes CSS définies dans les paramètres, a entraîné une surutilisation des définitions de règles et, je dois l’avouer, la duplication de nombreux éléments.

Désormais à partir de Sitecore 9.3, nous avons accès à un object appelé “Scriban”, qui peut facilement remplacer toute ou partie la variante de rendu d’un composant.

Un exemple simple pour commencer

Notre premier exemple consiste à créer une nouvelle variante de rendu pour le composant Promo. Il contient 6 champs: Promotext, promoIcon, PromoLink, PromoText2, PromoText3 et PromoIcon2.

Sa variante de rendu par défaut est également très simple, elle visualise les champs PromoIcon, PromoText et PromoLink et construit une structure HTML

Le resultat est le suivant :

<div><img href="PromoIcon"/></div>
<div class="promo-text">
	<div>PromoText</div>
	<div><a href="PromoLink">PromoLinkText</a></div>
</div>

Je souhaite créer un rendu pour mes objects Promo, où je pourrais voir les 6 champs du modèle. Le HTML résultant doit être comme suit:

<div><img href="PromoIcon"/></div>
<div class="promo-text">
	<div>PromoText</div>
	<div><a href="PromoLink">PromoLinkText</a></div>
</div>
<div class="small-text">PromoText2</div>
<div class="new-icon"><img href="PromoIcon2"/></div>
<div class="footer">PromoText3</div>

Pour faire cela, je créé une nouvelle définition de variante (variant definition) a l’adresse /sitecore/content/{TENANTFOLDER}/{TENANT}/{SITE}/Presentation/Rendering Variants/Promo et j’ajoute simplement un élément “Scriban” a cette définition:

Dans ce nouvel objet, dans le champ “Template”, j’écris le code suivant:

<div>{{ i_item.PromoIcon }}</div>
<div class="promo-text">
	<div>{{ i_item.PromoText }}</div>
	<div>{{ i_item.PromoLink }}</div>
</div>
<div class="small-text">{{ i_item.PromoText2 }}</div>
<div class="new-icon">{{ i_item.PromoIcon2 }}</div>
<div class="footer">{{ i_item.PromoText3 }}</div>

Comme vous pouvez le voir, le modèle suit la structure HTML, et chaque champ d’élément est rendu en l’appelant simplement, qu’il s’agisse d’un texte, d’un lien ou d’une image.

i_item est l’objet que l’on rend, et nous utilisons simplement le nom du champs pour récupérer sa valeur.

Un example plus complexe

Ecrire un modèle Scriban est très simple et plus rapide que d’utiliser les éléments de définition de variante pour créer une structure HTML. Nous avons également un bon contrôle de l’apparence du HTML du composant.

Sitecore a étendu scriban afin d’obtenir certains objets, éléments et fonctions spécifiques à Sitecore dans le script.

Embedded itemTypeValue
i_homeSitecore.Data.Items.ItemHome page item of the site for which the rendering process is performed.
i_datasourceSitecore.Data.Items.ItemThe item that was specified as the data source for the component.
i_itemSitecore.Data.Items.ItemThe current item within the rendering variant context. Often, this is an equivalent to the i_datasource.If your Scriban template was embedded within a Query or Reference rendering variant field, i_item will be exactly the item that other rendering variant fields would use for their rendering process.
i_siteSitecore.Data.Items.ItemThe root item of your site. In most cases, this item is the parent of your home page.
i_pageSitecore.Data.Items.ItemThe item that represents the page that is currently rendered.
source: https://doc.sitecore.com/developers/sxa/93/sitecore-experience-accelerator/en/the-embedded-items-and-objects-in-the-scriban-context.html
Context objectTypeValue
o_languageLanguageThe language of the current page.
o_modelObjectThe model that is passed to your MVC Controller rendering
o_geospatialSitecore.XA.Foundation.Search.Models.GeospatialLocation information for the currently rendered item with geospatial properties.
o_contextSitecore.XA.Foundation.Abstractions.IContextContext information for the currently rendered page.
o_pagemodeSitecore.XA.Foundation.Abstractions.IPageModeContext information for the currently rendered page.
Source; https://doc.sitecore.com/developers/sxa/93/sitecore-experience-accelerator/en/the-embedded-items-and-objects-in-the-scriban-context.html

Sitecore a également créé des fonctions spécifiques, dont certaines sont répertoriées ci-dessous. Plus d’informations sur ces fonctions sont disponibles dans la documentation Sitecore

sc_decorateReturns component decoration with styles, grid classes, and attributes required by Creative Exchange.
sc_editframe
sc_editendframe
Renders the edit frame around an area of HTML and lets you specify a set of Experience buttons that help users edit the content within that area.
sc_placeholderRenders a dynamic placeholder with optional context switch.
sc_executeExecutes a rendering variant field located beneath the Scriban template.
sc_evaluateEvaluates the rendering variant rule stored beneath the Scriban template and returns the evaluated value (true or false) based on the result of the rule execution.
sc_rawRetrieves the raw value of a field from an item.
sc_fieldRenders a Sitecore field that allows fall back when a field is empty and allows you to add parameters to tags for, for example, images or links.
sc_parameterRetrieves the rendering parameter values.

Créons une variante de rendu pour notre objet Promo, avec les spécifications supplémentaires suivantes

  • L’utilisateur peut changer la couleur de fond de l’ensemble du composant, grâce à un paramètre de rendu avec une DropList avec toutes les couleurs disponibles (en classe css)
  • L’utilisateur peut avoir une bordure autour du composant grâce à une case à cocher dans les paramètres de rendu
  • L’image PromoIcon2 peut être placée à gauche ou à droite du texte PromoText2, en fonction d’un choix fait par l’utilisateur dans les paramètres de rendu.
  • L’image PromoIcon sera placée dans un style d’image d’arrière-plan dans un div (juste pour montrer comment récupérer l’URL d’un élément multimédia)

Afin de montrer la syntaxe if/else de Scriban, je veux que le HTML résultant soit légèrement différent en fonction de la position de PromoIcon2

(Image on the right, with borders)
<div class="BackgroundColor BorderClass" style="background-image: url(PromoIconUrl)">
<div class="promo-text">
	<div>PromoText</div>
	<div><a href="PromoLink">PromoLinkText</a></div>
</div>
</div>
<div class="small-text half">PromoText2</div>
<div class="new-icon half"><img href="PromoIcon2"/></div>
<div class="footer">PromoText3</div>
(Image on the left, without borders)
<div class="BackgroundColor NoBorderClass" style="background-image: url(PromoIconUrl)">
<div class="promo-text">
	<div>PromoText</div>
	<div><a href="PromoLink">PromoLinkText</a></div>
</div>
</div>
<div class="new-icon half"><img href="PromoIcon2"/></div>
<div class="small-text half">PromoText2</div>
<div class="footer">PromoText3</div>

Je crée un nouveau modèle avec les champs nécessaires pour les paramètres de rendu:

Ce nouveau template est ajouté aux paramètres du rendu (rendering parameters) pour le template Promo

Dans l’Experience Editor, dans mon composant Promo, je peux maintenant accèder a mes nouveaux paramètres

Dans le script Scriban, j’utiliserai la fonction sc_parameter de Sitecore afin de récupérer leur valeur. Une certaine logique sera nécessaire pour créer le code HTML basé sur la valeur de ces paramètres. Voici le script final:

{{
	classBorder = "NoBorderClass"
	if sc_parameter 'UseMarginBottom'
		classMargin = "BorderClass"
	end
	classBC = sc_parameter 'BackgroundColor'
	imagePosition = sc_parameter 'Position'
}}
{{ if imagePosition == "Left" }}
<div class="{{ classBC }} {{ classBorder }}" 
    style="background-image: url(' {{ i_item.PromoIcon.media_url }}');">
<div class="promo-text">
	<div>{{ i_item.PromoText }}</div>
	<div>{{ i_item.PromoLink }}</div>
</div>
</div>
<div class="new-icon half">{{ i_item.PromoIcon2 }}</div>
<div class="small-text half">{{ i_item.PromoText2 }}</div>
<div class="footer">{{ i_item.PromoText3 }}</div>
{{ else }}
<div class="{{ classBC }} {{ classBorder }}" 
    style="background-image: url(' {{ i_item.PromoIcon.media_url }}');">
<div class="promo-text">
	<div>{{ i_item.PromoText }}</div>
	<div>{{ i_item.PromoLink }}</div>
</div>
</div>
<div class="small-text half">{{ i_item.PromoText2 }}</div>
<div class="new-icon half">{{ i_item.PromoIcon2 }}</div>
<div class="footer">{{ i_item.PromoText3 }}</div>
{{ end }}

Nous lisons d’abord les paramètres de rendu et les sauvegardons dans certaines variables (lignes 1-8). Lorsqu’il aura une DropList, la fonction sc_parameters obtiendra la valeur de l’élément sélectionné. Lorsque nous avons une case à cocher (ligne 3), la fonction retournera un booléen si la case est cochée ou non. Très pratique !

En fonction de la valeur de la variable imagePosition (ligne 9), le script rendra le HTML choisi.

i_item.PromoIcon rend l’intégralité du code HTML de l’élément multimédia. Afin d’obtenir simplement l’URL de l’élément multimédia, nous demandons i_item.PromoIcon.media_url (lignes 11 et 22).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: