Expand my Community achievements bar.

SOLVED

How to add a conditional style class to top element in HTL

Avatar

Level 2

I'm very new to HTL and AEM in general.

 

I have a component, where the top level element in HTL is <sly>:

 

<sly
data-sly-test.empty="${!properties.title}"
data-sly-use.template="core/wcm/components/commons/v1/templates.html"
data-sly-call="${template.placeholder @ isEmpty=empty}"
>
</sly>
<sly
data-sly-use.cardModel="com.cisco.dcloud.core.models.CardModel"
data-sly-test="${cardModel.compareUserAccessLevel==true}"
>
<div
data-sly-test="${wcmmode.edit && !wcmmode.preview}"
class="aem-helper configure__container"
>
${cardModel.entitlement}
</div>
<sly data-sly-test="${properties.variation == 'cardwithimage'}">
<sly data-sly-include="cardwithimage.html" data-sly-unwrap></sly>
</sly>
<sly data-sly-test="${properties.variation == 'cardwithlabel'}">
<sly data-sly-include="cardwithlabel.html" data-sly-unwrap></sly>
</sly>
<sly data-sly-test="${properties.variation == 'manualcard'}">
<sly data-sly-include="manualcard.html" data-sly-unwrap></sly>
</sly>
</sly>

 

It renders like this:

<div class="card">
<div class="card-component height-full">
...

 

Is there a way I can add a conditional style to that top element? The one with the class="card"? I just want the style to appear in preview/publish, but not the editor.

 

Thanks.

1 Accepted Solution

Avatar

Correct answer by
Level 10

Hi @kbsniquer ,

To conditionally add a style class to the top-level <div> element with the class "card" in your HTL code, you can leverage the class attribute with a dynamic expression. Here's how you can achieve this while ensuring the style appears in preview/publish mode but not in the editor mode:

 

<sly
    data-sly-test.empty="${!properties.title}"
    data-sly-use.template="core/wcm/components/commons/v1/templates.html"
    data-sly-call="${template.placeholder @ isEmpty=empty}"
>
</sly>
<sly
    data-sly-use.cardModel="com.cisco.dcloud.core.models.CardModel"
    data-sly-test="${cardModel.compareUserAccessLevel==true}"
>
    <div
        data-sly-test="${wcmmode.preview || wcmmode.edit}"
        class="card ${wcmmode.preview ? 'your-preview-class' : ''}"
    >
        <div
            data-sly-test="${wcmmode.edit && !wcmmode.preview}"
            class="aem-helper configure__container"
        >
            ${cardModel.entitlement}
        </div>
        <sly data-sly-test="${properties.variation == 'cardwithimage'}">
            <sly data-sly-include="cardwithimage.html" data-sly-unwrap></sly>
        </sly>
        <sly data-sly-test="${properties.variation == 'cardwithlabel'}">
            <sly data-sly-include="cardwithlabel.html" data-sly-unwrap></sly>
        </sly>
        <sly data-sly-test="${properties.variation == 'manualcard'}">
            <sly data-sly-include="manualcard.html" data-sly-unwrap></sly>
        </sly>
    </div>
</sly>

 

In this code:

  • I've added a conditional check within the class attribute of the top-level <div> element using HTL expressions.
  • If wcmmode.preview is true, indicating the preview mode, it will add the class "your-preview-class".
  • If wcmmode.edit is true, indicating the edit mode, the class won't be added. This ensures the style only appears in preview/publish mode, not in the editor mode.
  • class="card ${wcmmode.preview ? 'your-preview-class' : ''}" is a ternary expression. If wcmmode.preview is true, it adds "your-preview-class" to the class attribute, otherwise, it adds an empty string, effectively not adding any extra class.

Make sure to replace "your-preview-class" with the actual class name you want to add for preview/publish mode.
Reference:https://experienceleague.adobe.com/en/docs/experience-manager-htl/content/overview

 

View solution in original post

3 Replies

Avatar

Level 4

Hi @kbsniquer 

To conditionally render an html element, data-sly-test is the correct attribute. For example

<h1 data-sly-test="${properties.jcr:title}">
    ${properties.jcr:title}
</h1>

this will render h1 only when jcr:title is populated

 

Similarly if you want to conditionally RENDER card div, you do as  

<div class="card" data-sly-test="${wcmmode.edit && !wcmmode.preview}"> //your card </div>

This card will render in edit mode and not in preview

 

To further extend, if you want to conditional STYLE this card element, you can conditionally add a class, like this

<div class="card ${wcmmode.edit && !wcmmode.preview ? 'editstyle' : ''}"> //your card </div>

This will render <div class="card editstyle"> in edit mode. And you add required styles from your css. 

 

Note: For editor mode styles, dont merge clientlibs into site css. Create new clientlib under .authoring categories and make it apply only in author. Publisher site doesnt require these styles. 

Avatar

Level 9
To correct a small nuance from above code from @sarav_prakash  if you want the style to appear in preview/publish, but not the editor.
 

 

<div class="card" data-sly-test="${!wcmmode.edit}">

 

 
 

Avatar

Correct answer by
Level 10

Hi @kbsniquer ,

To conditionally add a style class to the top-level <div> element with the class "card" in your HTL code, you can leverage the class attribute with a dynamic expression. Here's how you can achieve this while ensuring the style appears in preview/publish mode but not in the editor mode:

 

<sly
    data-sly-test.empty="${!properties.title}"
    data-sly-use.template="core/wcm/components/commons/v1/templates.html"
    data-sly-call="${template.placeholder @ isEmpty=empty}"
>
</sly>
<sly
    data-sly-use.cardModel="com.cisco.dcloud.core.models.CardModel"
    data-sly-test="${cardModel.compareUserAccessLevel==true}"
>
    <div
        data-sly-test="${wcmmode.preview || wcmmode.edit}"
        class="card ${wcmmode.preview ? 'your-preview-class' : ''}"
    >
        <div
            data-sly-test="${wcmmode.edit && !wcmmode.preview}"
            class="aem-helper configure__container"
        >
            ${cardModel.entitlement}
        </div>
        <sly data-sly-test="${properties.variation == 'cardwithimage'}">
            <sly data-sly-include="cardwithimage.html" data-sly-unwrap></sly>
        </sly>
        <sly data-sly-test="${properties.variation == 'cardwithlabel'}">
            <sly data-sly-include="cardwithlabel.html" data-sly-unwrap></sly>
        </sly>
        <sly data-sly-test="${properties.variation == 'manualcard'}">
            <sly data-sly-include="manualcard.html" data-sly-unwrap></sly>
        </sly>
    </div>
</sly>

 

In this code:

  • I've added a conditional check within the class attribute of the top-level <div> element using HTL expressions.
  • If wcmmode.preview is true, indicating the preview mode, it will add the class "your-preview-class".
  • If wcmmode.edit is true, indicating the edit mode, the class won't be added. This ensures the style only appears in preview/publish mode, not in the editor mode.
  • class="card ${wcmmode.preview ? 'your-preview-class' : ''}" is a ternary expression. If wcmmode.preview is true, it adds "your-preview-class" to the class attribute, otherwise, it adds an empty string, effectively not adding any extra class.

Make sure to replace "your-preview-class" with the actual class name you want to add for preview/publish mode.
Reference:https://experienceleague.adobe.com/en/docs/experience-manager-htl/content/overview