Expand my Community achievements bar.

Submissions are now open for the 2026 Adobe Experience Maker Awards.
SOLVED

byline.html HTL Code

Avatar

Level 3

Hi all,

 

I am following WKND tutorial, chapter-6: Custom Component.

 

The HTL code shows:

 

<!--/* byline.html */-->
<div data-sly-use.byline="com.adobe.aem.guides.wknd.core.models.Byline"
data-sly-use.placeholderTemplate="core/wcm/components/commons/v1/templates.html"
data-sly-test.hasContent="${!byline.empty}"
class="cmp-byline">
<div class="cmp-byline__image"
data-sly-resource="${ '.' @ resourceType = 'core/wcm/components/image/v2/image' }">
</div>
<h2 class="cmp-byline__name">${byline.name}</h2>
<p class="cmp-byline__occupations">${byline.occupations @ join=', '}</p>
</div>
<sly data-sly-call="${placeholderTemplate.placeholder @ isEmpty=!hasContent}"></sly>

 

I did not understand placeholder paradigm.

I am aware of invoking a Model using data-sly-use, but not invoking template.

 

Is it like:

     If data-sly-test.hasContent="${!byline.empty}" is true, 

           "core/wcm/components/commons/v1/templates.html" is displayed?

 

And "core/wcm/components/commons/v1/templates.html" is a BOX?

 

Appreciate all your responses.

 

Thanks,

RK.

 

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@Rama_KrishnaNy 

You're right to analyze how the data-sly-test.hasContent="${!byline.empty}" applies.

Let me clarify:

data-sly-test.hasContent="${!byline.empty}" is applied on the entire wrapping <div class="cmp-byline">.

This means:

  • If byline.empty == false (i.e., model has content), the entire block inside this div will be rendered:

    • <div class="cmp-byline__image"> - image

    • <h2 class="cmp-byline__name"> - name

    • <p class="cmp-byline__occupations"> - occupations

  • If byline.empty == true (i.e., model has no content), then this entire div block is skipped from rendering.

So yes - it applies to all three fields together, because they're all inside the <div data-sly-test...> block.

The class="cmp-byline" itself doesn’t control the logic. It's just a CSS class. The real conditional rendering is driven by data-sly-test.

Think of it this way: AEM will evaluate the data-sly-test, and either render everything inside the tag or skip it entirely.

If byline.empty returns true, you won't see any of:

  • Image

  • Name

  • Occupations

Instead, the <sly data-sly-call="${placeholderTemplate.placeholder @ isEmpty=!hasContent}"> line will kick in and display the visual placeholder.


Santosh Sai

AEM BlogsLinkedIn


View solution in original post

3 Replies

Avatar

Community Advisor

Hi @Rama_KrishnaNy,

Let me explain you by passing WKND Byline Component

<div data-sly-use.byline="com.adobe.aem.guides.wknd.core.models.Byline"
     data-sly-use.placeholderTemplate="core/wcm/components/commons/v1/templates.html"
     data-sly-test.hasContent="${!byline.empty}"
     class="cmp-byline">

    <div class="cmp-byline__image"
         data-sly-resource="${ '.' @ resourceType = 'core/wcm/components/image/v2/image' }">
    </div>

    <h2 class="cmp-byline__name">${byline.name}</h2>
    <p class="cmp-byline__occupations">${byline.occupations @ join=', '}</p>

</div>

<!-- placeholder for when no content is present -->
<sly data-sly-call="${placeholderTemplate.placeholder @ isEmpty=!hasContent}"></sly>

1. data-sly-use.byline=...

This imports the Java model Byline. Now you can use byline.name, byline.occupations, etc.

2. data-sly-use.placeholderTemplate="core/wcm/components/commons/v1/templates.html"

This imports a reusable HTL template from Adobe Core Components. Specifically:

core/wcm/components/commons/v1/templates.html contains reusable templates, including:

<template data-sly-template.placeholder="${@ isEmpty}">
    <div class="cq-placeholder" data-emptytext="Enter some content"></div>
</template>

This is a visual placeholder (like a grey box) that shows up in the AEM editor when the component has no content.

To answer your question:

3. data-sly-test.hasContent="${!byline.empty}"

This only renders the actual HTML (<div class="cmp-byline">...</div>) if the model is not empty.

So:

  • If the model has data: it renders the real content

  • If it's empty: it skips this block

4. data-sly-call="${placeholderTemplate.placeholder @ isEmpty=!hasContent}"

This calls the imported placeholder template and passes a parameter to it:

  • If hasContent is false (i.e., model is empty), then isEmpty will be true

  • So it renders a placeholder saying: “Drag components here” or “Enter some content”

You can try this yourself:

templates.html:

<template data-sly-template.placeholder="${@ isEmpty}">
    <div class="cq-placeholder" data-emptytext="This component is empty"></div>
</template>

yourComponent.html:

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

<sly data-sly-use.templates="path/to/templates.html" />
<sly data-sly-call="${templates.placeholder @ isEmpty=!hasContent}" />

If title is missing, the placeholder will appear.

Hope this helps!


Santosh Sai

AEM BlogsLinkedIn


Avatar

Level 3

Thanks @SantoshSai .

 

3. "data-sly-test.hasContent="${!byline.empty}"

This only renders the actual HTML (<div class="cmp-byline">...</div>) if the model is not empty."

 

But the actual HTML does not exit for a specific field.

 

All we have are:

         class="cmp-byline" in the encompassing div tag and  

        <div class="cmp-byline__image", "cmp-byline__name" and "cmp-byline__occupations"

 

So, this functionality applies to all three elements (name, image and occupations)?

Is it because of class="cmp-byline" being in the encompassing div tag ?

 

Thanks,

RK.

                 

Avatar

Correct answer by
Community Advisor

@Rama_KrishnaNy 

You're right to analyze how the data-sly-test.hasContent="${!byline.empty}" applies.

Let me clarify:

data-sly-test.hasContent="${!byline.empty}" is applied on the entire wrapping <div class="cmp-byline">.

This means:

  • If byline.empty == false (i.e., model has content), the entire block inside this div will be rendered:

    • <div class="cmp-byline__image"> - image

    • <h2 class="cmp-byline__name"> - name

    • <p class="cmp-byline__occupations"> - occupations

  • If byline.empty == true (i.e., model has no content), then this entire div block is skipped from rendering.

So yes - it applies to all three fields together, because they're all inside the <div data-sly-test...> block.

The class="cmp-byline" itself doesn’t control the logic. It's just a CSS class. The real conditional rendering is driven by data-sly-test.

Think of it this way: AEM will evaluate the data-sly-test, and either render everything inside the tag or skip it entirely.

If byline.empty returns true, you won't see any of:

  • Image

  • Name

  • Occupations

Instead, the <sly data-sly-call="${placeholderTemplate.placeholder @ isEmpty=!hasContent}"> line will kick in and display the visual placeholder.


Santosh Sai

AEM BlogsLinkedIn