2
votes

How can I utilise the WCM Parsys component to create an unordered list of multiple instances of another specific component in AEM 6?

I need to ensure that the list is wrapped by a ul tag, that each inner component is an li tag, that no extra div tags are wrapped around the ul or lis and ensure the properties of each inner component can be edited in author mode.

(My attempts so far either have loads of extra div tags, ruining the already built layout and semantics, or if using decorationTagName='li' the editor-boxes for the components all sit on top of each other in author mode so you can only edit the topmost control).

4

4 Answers

3
votes

Check out Sightly when you are working with AEM 6. It provides a nice way to add parameters to child resources, when iterating over them ... this allows you to add resources types. This is a nice way for aggregating components. Feike Visser wrote a nice five page long tutorial.

Listing children via Sightly is not obviously easy.

<ul>
  <!--/* for example jcr:content */-->
  <div data-sly-list.par="${resource.listChildren}"
       data-sly-unwrap>
    <!--/* for example a parsys */-->
    <div data-sly-list.item="${par.listChildren}"
         data-sly-unwrap>
      <!--/* all children of the parsys rendered with an li tag */-->
        <div data-sly-resource="${item.path @ wcmmode='disabled'}"
             data-sly-unwrap></div>
      </div>
    </div>
  </div>
</ul>

This will render the children of a content reosource's parsys. A elegantly way would be using a model provided via JavaScript, WCMUse or a SlingModel. But this way you can skip the programming for easy iterations. Checks for resource names work as well, so you can add a bit more of complexity, although you will want to use an appropriate model in complex scenarios.

2
votes

The OOTB parsys component uses divs to wrap around the inner components, so if you need a completely different structure you need to go for a custom parsys that extends from the existing one and uses a different wrapping markup.

1
votes

What I do usually is to create an own container component where I have a switch between author mode and publish/preview mode. E.g. in Author mode just display the child components in a normal parsys with divs and only render the correct markup in the preview/publish mode:

<c:choose>
    <c:when test="${isEditMode}">
        <cq:include path="par" resourceType="foundation/components/parsys" />
    </c:when>
    <c:otherwise>
        <ul>
            <c:forEach items="${m.components}" var="comp">
                <li><cq:include path="${comp.path}" resourceType="${comp.resourceType}" /></li>
            </c:forEach>
        </ul>
    </c:otherwise>
</c:choose>

Whereas m is a controller and components is a list of child Resource's.

1
votes

Assuming the components inside the parsys are list-item components (and only used that way), you can override the element wrapping your component with the cq:htmlTag/cq:tagName property, and making your parsys render the <ul> elements.

For more information, see ComponentDiv