Skip to content

Instantly share code, notes, and snippets.

@sammso
Last active August 10, 2021 18:21
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sammso/64f91cb4e1c2968f4fcd7a12fb7e8284 to your computer and use it in GitHub Desktop.
Save sammso/64f91cb4e1c2968f4fcd7a12fb7e8284 to your computer and use it in GitHub Desktop.

Display all renderRequest attribute names

    <ul>
    <#list renderRequest.getAttributeNames() as name >
        <li>${name}</li>
    </#list>
    </ul>

Display Audience Targeting User Segment ids

    <ul>
    <#if renderRequest.getAttribute("userSegmentIds")?? >
        <#list renderRequest.getAttribute("userSegmentIds") as userSegmentId>
            <li>${userSegmentId}</li>
        </#list>
    </#if>
    </ul>

Navigation to support UserSegments

Usage

If page has UserSegment categorization (or any this point) then page is not shown unless user has matching User Segment categorization. This modification has been done to the Macro level so it will work for all template's that are using that macro.

First you need to enable service locator for freemarker scripts.

Control panel -> Configuration -> System Settings-> Search word freemarker -> Edit: FreeMarker Engine and remove serviceLocator from Restricted variables list.

To add this functionality Go to -> Global scope -> Application Display Templates -> Edit : NAVIGATION-MACRO-FTL and replace with:

<#if serviceLocator.findService("com.liferay.content.targeting.service.UserSegmentLocalService")?? >
    <#assign userSegmentLocalService =serviceLocator.findService("com.liferay.content.targeting.service.UserSegmentLocalService")/>
</#if>

<#assign assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService")/>

<#macro buildNavigation
    branchNavItems
    cssClass
    displayDepth
    includeAllChildNavItems
    navItemLevel
    navItems
>

    <#if navItems?has_content && ((displayDepth == 0) || (navItemLevel <= displayDepth))>
        <ul class="${cssClass} level-${navItemLevel}">
            <#list navItems as navItem>
                <#assign nav_item_attr_selected = "" />
                <#assign nav_item_css_class = "lfr-nav-item" />
                <#assign isShowNavItem = true/>

                <#if includeAllChildNavItems || navItem.isInNavigation(branchNavItems)>
                    <#assign nav_item_css_class = "${nav_item_css_class} open" />
                </#if>

                <#if navItem.isSelected()>
                    <#assign nav_item_attr_selected = "aria-selected='true'" />
                    <#assign nav_item_css_class = "${nav_item_css_class} selected active" />
                </#if>


                <#if assetCategoryLocalService?? && userSegmentLocalService??>
                    <#assign currentPlid = navItem.getLayout().getPlid()/>
                    <#assign navItemCategoryIds = assetCategoryLocalService.getCategoryIds("com.liferay.portal.kernel.model.Layout", currentPlid) />

                    <#if navItemCategoryIds?has_content>
                        <#assign isShowNavItem=false/>

                        <#list navItemCategoryIds as navItemCategoryId>
                            <#if renderRequest.getAttribute("userSegmentIds")?? && userSegmentLocalService.fetchUserSegmentByAssetCategoryId(navItemCategoryId)??>
                                <#list renderRequest.getAttribute("userSegmentIds") as userSegmentId>
                                    <#assign userSegmentCategoryId = userSegmentLocalService.getUserSegment(userSegmentId).getAssetCategoryId()/>
                                    <#if userSegmentCategoryId==navItemCategoryId >
                                        <#assign isShowNavItem = true/>
                                        <#break/>
                                    </#if>
                                    </p>
                                </#list>
                            </#if>
                            <#if isShowNavItem>
                                 <#break/>
                            </#if>
                        </#list>
                    </#if>
                </#if>
                <#if isShowNavItem>
                    <li class="${nav_item_css_class}" ${nav_item_attr_selected}>
                        <#if navItem.isBrowsable()>
                            <a class="${nav_item_css_class}" href="${navItem.getRegularURL()!""}" ${navItem.getTarget()}>${htmlUtil.escape(navItem.getName())}</a>
                        <#else>
                            ${htmlUtil.escape(navItem.getName())}
                        </#if>
                        <#if includeAllChildNavItems || navItem.isInNavigation(branchNavItems)>
                            <@buildNavigation
                                branchNavItems=branchNavItems
                                cssClass=cssClass
                                displayDepth=displayDepth
                                includeAllChildNavItems=includeAllChildNavItems
                                navItemLevel=(navItemLevel + 1)
                                navItems=navItem.getChildren()
                            />
                        </#if>
                    </li>
                </#if>
            </#list>
        </ul>
    </#if>
</#macro>

TODO:

  • Optimize .. too much servicecalls at inside loop

How to display current user segments:

<#if serviceLocator.findService("com.liferay.content.targeting.service.UserSegmentLocalService")?? >
    <#assign userSegmentLocalService =serviceLocator.findService("com.liferay.content.targeting.service.UserSegmentLocalService")/>
</#if>

<#assign assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService")/>

<#assign navbarId = "navbar_" + portletDisplay.getId() />
<#assign noUserSegments= true />


<div id="${navbarId}">
		<ul aria-label="<@liferay.language key="site-pages" />" class="nav nav-justified nav-pills navbar-site" role="menubar">
	    <li class="lfr-nav-item" role="presentation">Current user segments:</li>	   
    
<#if renderRequest.getAttribute("userSegmentIds")?? >
    <#list renderRequest.getAttribute("userSegmentIds") as userSegmentId>
        <#assign userSegmentCategoryId = userSegmentLocalService.getUserSegment(userSegmentId).getAssetCategoryId()/>
        
        <#assign category= assetCategoryLocalService.fetchAssetCategory(userSegmentCategoryId) />
        <li class="lfr-nav-item" role="presentation">
            <#if noUserSegments==false>
                |
            </#if>
            <span><b>${category.getName()}</b></span>
        </li>

        <#assign noUserSegments= false />
    </#list>
		</ul>
</div>

</#if>

<#if noUserSegments>
    <b>No user segments</b>
</#if>
@m-tilab
Copy link

m-tilab commented May 14, 2021

Thank you for useful snippet codes!!!

@duracell80
Copy link

Hey Sampsa, these are really awesome examples.

Would you happen to know where the documentation for the <@buildNavigation macro is? I'm trying to get the link target. Where it says navItems=entries I was hoping to somehow get navItem.getTarget() there? Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment