2
votes

In Liferay DXP, I am using an Asset Publisher Portlet to display a list of Web Content Structure entries (staff members in this case.) When I created the Staff Member web content structure it was necessary to create a web content template to go with it.

However, my web content template is currently just an empty template, because I do not know how to access it from the Application Display Template being used by the Asset Publisher portlet to display my list of staff members.

My Application Display Template currently looks like this:

<#if entries?has_content>
    <div class="staff-members">
        <div class="container">
            <h3>Our staff</h3>
            <div class="row offs">
                <#list entries as curEntry>
                    <#assign docXml = saxReaderUtil.read(curEntry.getAssetRenderer().getArticle().getContent()) />
                    <#assign name  = docXml.valueOf("//dynamic-element[@name='name']/dynamic-content/text()") />
                    <#assign photo  = docXml.valueOf("//dynamic-element[@name='photo']/dynamic-content/text()") />
                    <#assign bio  = docXml.valueOf("//dynamic-element[@name='bio']/dynamic-content/node()") />
                    <div class="col-md-3 col-sm-6 wow fadeIn animated" data-wow-duration="2s" data-wow-delay="0.2s" style="visibility: visible; animation-duration: 2s; animation-delay: 0.2s; animation-name: fadeIn;">
                        <div class="thumbnail">
                            <img src="${photo}" alt="${name}">
                            <div class="caption">
                                <h5>
                                    <a href="#">${name}</a>
                                </h5>
                                <p>${bio}</p>
                            </div>
                        </div>
                    </div>
                </#list>
            </div>
        </div>
    </div>
</#if>

As you can see, I need to wrap the staff member markup blocks with additional markup; which is why I'm using an Asset Publisher to display my Application Display Template.

As I mentioned, this setup requires adding an empty Web Content Template (for Staff member structure) to Liferay, which seems silly. What I'd like to do is define the repeatable markup inside that Web Content template and refer to the template from the ADT. Like so:

<#if entries?has_content>
    <div class="staff-members">
        <div class="container">
            <h3>Our staff</h3>
            <div class="row offs">
                <#list entries as curEntry>
                    <#assign docXml = saxReaderUtil.read(curEntry.getAssetRenderer().getArticle().getContent()) />
                    <#assign name  = docXml.valueOf("//dynamic-element[@name='name']/dynamic-content/text()") />
                    <#assign photo  = docXml.valueOf("//dynamic-element[@name='photo']/dynamic-content/text()") />
                    <#assign bio  = docXml.valueOf("//dynamic-element[@name='bio']/dynamic-content/node()") />

                     <!-- 
                          CALL WEB CONTENT TEMPLATE HERE PASSING IN DATA
                          FOR THIS PARTICULAR WEB CONTENT ITEM.
                      -->
                </#list>
            </div>
        </div>
    </div>
</#if>

How can this be achieved?

2

2 Answers

2
votes

In that case you described you don't even need to extract the data with SAX. Take a look to that working example:

<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")>

<#if entries?has_content>
    <#list entries as curEntry>
        <#assign article = curEntry.getAssetRenderer().getArticle() />
        ${journalArticleLocalService.getArticleContent(article, article.getDDMTemplateKey(), "VIEW", locale, objectUtil("com.liferay.portal.kernel.portlet.PortletRequestModel", renderRequest, renderResponse), themeDisplay)}
    </#list>
</#if>

As you can see, we are using a couple of reserved variables (serviceLocator and objectUtil) so you will have to activate them in the server before using that snippet.

I am not working in DXP but Liferay 7 Community, it should work anyway.

2
votes

Thanks @gonzalezalo, but I was able to find a solution elsewhere that does not involve any special server configurations.

I am posting it here, in case anyone else is looking for an answer to this question.

If we use Liferay's liferay_ui tag (calling the asset-display module) and pass into it a reference to the AssetRenderer and the article we want to publish (curEntry), then Liferay will do the heavy lifting of finding the template associated with the content, populating it with the current article and rendering it back to the page:

<#if entries?has_content>
    <div class="staff-members">
        <div class="container">
            <h3>Our staff</h3>
            <div class="row offs">
                <#list entries as curEntry>
                    <#assign assetRenderer = curEntry.getAssetRenderer() />

                    <@liferay_ui["asset-display"]
                        assetEntry=curEntry
                        assetRenderer=assetRenderer
                        showExtraInfo=false />
                </#list>
            </div>
        </div>
    </div>
</#if>