Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

SOLVED

How can I pull the Tags out of a Custom Component using the List SuperType?

SocialTaylor
Level 3
Level 3

Hello!

 

I am working on a component that can pull pages out from underneath a path and have decided to use the List Core Component to extend into a component and change the front end for this. The only thing I am stuck on is finding a way to pull out the Tags from the post. I only need to return one and, I noticed that in the models used for the List Component, the list it is returning is using the core Page api, which I assumed will give us access to the getTags(); function in the model, but I'm unsure of how to implement it in the Models I am sharing below. Any help would be appreciated on understanding and pulling those out to display on the frontend!

 

LayoutRelatedBlogs Model

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ Copyright 2017 Adobe
 ~
 ~ Licensed under the Apache License, Version 2.0 (the "License");
 ~ you may not use this file except in compliance with the License.
 ~ You may obtain a copy of the License at
 ~
 ~     http://www.apache.org/licenses/LICENSE-2.0
 ~
 ~ Unless required by applicable law or agreed to in writing, software
 ~ distributed under the License is distributed on an "AS IS" BASIS,
 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ~ See the License for the specific language governing permissions and
 ~ limitations under the License.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 package com.movementmortgage.core.models;

 import java.util.Collection;
 import java.util.Collections;
 
 import org.osgi.annotation.versioning.ConsumerType;

import com.adobe.cq.wcm.core.components.models.Component;
import com.movementmortgage.core.models.items.LayoutRelatedBlogsItem;
import com.day.cq.wcm.api.Page;
 
 /**
  * Defines the {@code List} Sling Model used for the {@code /apps/core/wcm/components/list} component. This component
  * currently only supports page lists.
  *
  * @since com.adobe.cq.wcm.core.components.models 11.0.0
  */
 @ConsumerType
 public interface LayoutRelatedBlogs extends Component {
 
     /**
      * Name of the resource property indicating how the list will be built. Possible values are:
      *
      * <ul>
      *     <li><code>children</code> - the list will be built from the child pages of the page identified by {@link #PN_PARENT_PAGE}</li>
      *     <li><code>static</code> - the list will be built from a custom set of pages, stored by the {@link #PN_PAGES} property</li>
      *     <li><code>search</code> - the list will be built from the result of a search query</li>
      *     <li><code>tags</code> - the list will be built from the sub-pages of the page identified by {@link #PN_TAGS_PARENT_PAGE}
      *     which are tagged with the tags stored by the {@link #PN_TAGS} property</li>
      * </ul>
      *
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_SOURCE = "listFrom";
 
     /**
      * Name of the resource property storing the list of pages to be rendered if the source of the list is <code>static</code>.
      *
      * @SEE #PN_SOURCE
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_PAGES = "pages";
 
     /**
      * Name of the resource property storing the root page from which to build the list if the source of the list is <code>children</code>.
      *
      * @SEE #PN_SOURCE
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_PARENT_PAGE = "parentPage";
 
     /**
      * Name of the resource property storing the root from where the tag search is performed.
      *
      * @SEE #PN_SOURCE
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_TAGS_PARENT_PAGE = "tagsSearchRoot";
 
     /**
      * Name of the resource property storing the tags that will be used for building the list if the source of the list is
      * <code>tags</code>.
      *
      * @SEE #PN_SOURCE
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_TAGS = "tags";
 
     /**
      * Name of the resource property indicating if the matching against tags can accept any tag from the tag list. The accepted value is
      * <code>any</code>.
      *
      * @SEE #PN_SOURCE
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_TAGS_MATCH = "tagsMatch";
 
     /**
      * Name of the boolean resource property indicating if the list items should render a description.
      *
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_SHOW_DESCRIPTION = "showDescription";
 
     /**
      * Name of the boolean resource property indicating if the list items should render the modification date of each item.
      *
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_SHOW_MODIFICATION_DATE = "showModificationDate";
 
     /**
      * Name of the boolean resource property indication if the items should render a link to the page they represent.
      *
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_LINK_ITEMS = "linkItems";
 
     /**
      * Name of the boolean resource property indication if the items should render a link to the page they represent.
      *
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_DISPLAY_ITEM_AS_TEASER = "displayItemAsTeaser";
 
     /**
      * Name of the resource property storing where a search should be performed if the source of the list is <code>search</code>.
      *
      * @SEE #PN_SOURCE
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_SEARCH_IN = "searchIn";
 
     /**
      * Name of the resource property indicating how the list items should be sorted. Possible values: <code>asc</code>, <code>desc</code>.
      *
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_SORT_ORDER = "sortOrder";
 
     /**
      * Name of the resource property indicating by which criterion the sort is performed. Possible value: <code>title</code>,
      * <code>modified</code>.
      *
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_ORDER_BY = "orderBy";
 
     /**
      * Name of the resource property indicating which date format should be used when the list items render their modification date.
      *
      * @since com.adobe.cq.wcm.core.components.models 11.0.0
      */
     String PN_DATE_FORMAT = "dateFormat";
 
     /**
      * Name of the component property indicating to which teaser component the list items should be delegated.
      *
      * @since com.adobe.cq.wcm.core.components.models 12.21.0
      */
     String PN_TEASER_DELEGATE = "teaserDelegate";
 
     /**
      * Returns the list's items collection, as {@link Page} elements.
      *
      * @Return {@link Collection} of {@link Page}s
      * @since com.adobe.cq.wcm.core.components.models 11.0.0; marked <code>default</code> in 12.1.0
      * @deprecated since 12.1.0: use {@link List#getListItems} instead
      */
     @deprecated
     default Collection<Page> getItems() {
         return null;
     }
 
     /**
      * Returns the list's items collection, as {@link ListItem}s elements.
      *
      * @Return {@link Collection} of {@link ListItem}s
      * @since com.adobe.cq.wcm.core.components.models 12.2.0
      */
     @COM.drew.lang.annotations.NotNull
     default Collection<LayoutRelatedBlogsItem> getListItems() {
         return Collections.emptyList();
     }
 
     /**
      * Returns {@code true} if the list's items should be displayed as teasers.
      *
      * @Return {@code true} if the items should be displayed as teasers, {@code false} otherwise
      * @since com.adobe.cq.wcm.core.components.models 12.21.0
      */
     default boolean displayItemAsTeaser() {
         return false;
     }
 
     /**
      * Returns {@code true} if the list's items should link to the corresponding {@link Page}s they represent.
      *
      * @Return {@code true} if the pages should be linked, {@code false} otherwise
      * @since com.adobe.cq.wcm.core.components.models 11.0.0; marked <code>default</code> in 12.1.0
      */
     default boolean linkItems() {
         return false;
     }
 
     /**
      * Returns {@code true} if the list's items should render their description.
      *
      * @Return {@code true} if page description should be shown, {@code false} otherwise
      * @since com.adobe.cq.wcm.core.components.models 11.0.0; marked <code>default</code> in 12.1.0
      */
     default boolean showDescription() {
         return false;
     }
 
     /**
      * Returns {@code true} if the list's items should render their last modification date.
      *
      * @Return {@code true} if modification date should be shown, {@code false} otherwise
      * @since com.adobe.cq.wcm.core.components.models 11.0.0; marked <code>default</code> in 12.1.0
      */
     default boolean showModificationDate() {
         return false;
     }
 
     /**
      * Returns the date format used to display the last modification date of the list's items.
      *
      * @Return format to use for the display of the last modification date.
      * @SEE #showModificationDate()
      * @since com.adobe.cq.wcm.core.components.models 11.0.0; marked <code>default</code> in 12.1.0
      */
     default String getDateFormatString() {
         return null;
     }
 
 }

 

 

 

LayoutRelatedBlogsItem Model referenced above 

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ Copyright 2017 Adobe
 ~
 ~ Licensed under the Apache License, Version 2.0 (the "License");
 ~ you may not use this file except in compliance with the License.
 ~ You may obtain a copy of the License at
 ~
 ~     http://www.apache.org/licenses/LICENSE-2.0
 ~
 ~ Unless required by applicable law or agreed to in writing, software
 ~ distributed under the License is distributed on an "AS IS" BASIS,
 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ~ See the License for the specific language governing permissions and
 ~ limitations under the License.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 package com.movementmortgage.core.models.items;

 import java.util.Calendar;

import com.adobe.cq.wcm.core.components.models.Component;
import com.adobe.reef.siren.Link;
import com.drew.lang.annotations.Nullable;

import org.apache.sling.api.resource.Resource;
 import org.osgi.annotation.versioning.ConsumerType;
 
 /**
  * Interface for a generic list item, used by the {@link List} and {@link Search} models.
  *
  * @since com.adobe.cq.wcm.core.components.models 12.2.0
  */
 @ConsumerType
 public interface LayoutRelatedBlogsItem extends Component {
 
     /**
      * Returns the link of this {@code ListItem}.
      *
      * @Return the link of this list item.
      * @since com.adobe.cq.wcm.core.components.models 12.20.0
      */
     @nullable
     default Link getLink() {
         return null;
     }
 
     /**
      * Returns the URL of this {@code ListItem}.
      *
      * @Return the URL of this list item or {@code null}
      * @since com.adobe.cq.wcm.core.components.models 12.2.0
      * @deprecated Please use {@link #getLink()}
      */
     @deprecated
     @nullable
     default String getURL() {
         return null;
     }
 
     /**
      * Returns the title of this {@code ListItem}.
      *
      * @Return the title of this list item or {@code null}
      * @since com.adobe.cq.wcm.core.components.models 12.2.0
      */
     @nullable
     default String getTitle() {
         return null;
     }
 
     /**
      * Returns the description of this {@code ListItem}.
      *
      * @Return the description of this list item or {@code null}
      * @since com.adobe.cq.wcm.core.components.models 12.2.0
      */
     @nullable
     default String getDescription() {
         return null;
     }
 
     /**
      * Returns the date when this {@code ListItem} was last modified.
      *
      * @Return the last modified date of this list item or {@code null}
      * @since com.adobe.cq.wcm.core.components.models 12.2.0
      */
     @nullable
     default Calendar getLastModified() {
         return null;
     }
 
     /**
      * Returns the path of this {@code ListItem}.
      *
      * @Return the list item path or {@code null}
      * @since com.adobe.cq.wcm.core.components.models 12.2.0
      */
     @nullable
     default String getPath() {
         return null;
     }
 
     /**
      * Returns the name of this {@code ListItem}.
      *
      * @Return the list item name or {@code null}
      * @since com.adobe.cq.wcm.core.components.models 12.6.0
      */
     @nullable
     default String getName() {
         return null;
     }
 
     /**
      * Returns a wrapped resource of the item which is used to render the item as a Teaser component.
      *
      * The wrapped resource is either:
      * - the featured image of the item page, if it exists
      * - the content node of the item page, if it exists
      * - null otherwise
      *
      * @Return wrapped resource of the item which can be rendered as a Teaser component
      * @since com.adobe.cq.wcm.core.components.models 12.21.0
      */
     @nullable
     default Resource getTeaserResource() { return null;}
 
 }

 Before, I had tried adding something similar to the Nullable getTitle(); functions, but it kept asking me to define Tag and I wasn't sure what to pull in for that or how to grab like, the first item of that function to return to the frontend

1 Accepted Solution
Lavanya_Pejjayi
Correct answer by
Level 3
Level 3
HiSocialTaylor, 

You can use below code to fetch the list of tags of the page.
@Inject
@Named("cq:tags")
private String[] tags;

 

protected void init() {

String[] eventTags = this.tags;
List<String> topicTags = new ArrayList<>();
final TagManager tagManager = resourceResolver.adaptTo(TagManager.class);
if (tagManager != null && eventTags != null) {
String[] values = new String[eventTags.length];
for (int i = 0; i < eventTags.length; i++) {
String eventTag = eventTags[i];
Tag tag = tagManager.resolve(eventTag);
if (tag != null) {
if (eventTag.contains(PAGE_TOPICS)) {
topicTags.add(tag.getTitle());
}
values[i] = tag.getTitle();
}
}
this.tagValues = values;

}

 

 

  <sly data-sly-use.objectOfModelClass="Modelclasspath"></sly>


       <div """>${objectOfModelClass.tagValues}</div>

 

View solution in original post

4 Replies
Lavanya_Pejjayi
Correct answer by
Level 3
Level 3
HiSocialTaylor, 

You can use below code to fetch the list of tags of the page.
@Inject
@Named("cq:tags")
private String[] tags;

 

protected void init() {

String[] eventTags = this.tags;
List<String> topicTags = new ArrayList<>();
final TagManager tagManager = resourceResolver.adaptTo(TagManager.class);
if (tagManager != null && eventTags != null) {
String[] values = new String[eventTags.length];
for (int i = 0; i < eventTags.length; i++) {
String eventTag = eventTags[i];
Tag tag = tagManager.resolve(eventTag);
if (tag != null) {
if (eventTag.contains(PAGE_TOPICS)) {
topicTags.add(tag.getTitle());
}
values[i] = tag.getTitle();
}
}
this.tagValues = values;

}

 

 

  <sly data-sly-use.objectOfModelClass="Modelclasspath"></sly>


       <div """>${objectOfModelClass.tagValues}</div>

 

View solution in original post

SocialTaylor
Level 3
Level 3

Hey!

 

I tried what you have above in a new Model, but that didn't seem to work. This is what I got below:

 

package com.movementmortgage.core.models;

import javax.inject.Inject;
import javax.inject.Named;

import com.day.cq.tagging.Tag;
import com.day.cq.tagging.TagManager;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;

@Model(adaptables = Resource.class)
public class BlogTags {

    @Inject
    @Named("cq:tags")
    private String[] tags;
    
    @SlingObject
    private ResourceResolver resourceResolver;

    protected void init() {

        String[] eventTags = this.tags;

        // List<String> topicTags = new ArrayList<>();

        final TagManager tagManager = resourceResolver.adaptTo(TagManager.class);

        if (tagManager != null && eventTags != null) {
            String[] values = new String[eventTags.length];

            for (int i = 0; i < eventTags.length; i++) {
                String eventTag = eventTags[i];
                Tag tag = tagManager.resolve(eventTag);

                if (tag != null) {

                    // if (eventTag.contains(PAGE_TOPICS)) {
                    //     topicTags.add(tag.getTitle());
                    // }

                    values[i] = tag.getTitle();
                }
            }

            this.tags = values;
        }
    }
}
<template data-sly-template.item="${@ list, item}">
    <article class="blog-card">
        <a href="${item.URL}">
            <div class="blog-image">
                <img src="${item.path}.thumb.700.900.png" alt="">
                <div class="tag"><p class="p-lg color-white">movement news</p></div>
                <sly data-sly-use.tagItems="com.movementmortgage.core.models.BlogTags">
                    <div>${objectOfModelClass.tagValues}</div>
                </sly>
            </div>
            <div class="blog-content">
                <p class="date p-sm">${list.dateFormatString @format=item.lastModified}</p>
                <h4 class="h6 body">${item.title @ context='text'}</h4>
            </div>
        </a>
    </article>
</template>

It just didn't return anything. I wonder if I need to past the List item Page to that? Or do I need to create a new function within the model I was creating above?

Lavanya_Pejjayi
Level 3
Level 3

Kindly correct/update the code as per your requirement. 

1.Object reference is misplaced.

2.Component path is missing from the Model

3.create a model class with component reference path and fetch the page details 

 

 



<sly data-sly-use.tagItems="com.movementmortgage.core.models.BlogTags"> <div>${objectOfModelClass.tagValues}</div> </sly>

 

<sly data-sly-use.tagItems="com.movementmortgage.core.models.BlogTags">
                    <div>${tagItems.tagValues}</div>
                </sly>

1. You should create a model class to fetch the list of tags

2. update the below lines 

@Model(adaptables = Resource.class,
resourceType = {"pass your component path"},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)

  

@ValueMapValue
String yourPagePath;

@PostConstruct 
if (StringUtils.isNotBlank(yourPagePath) && Objects.nonNull(pageManager)) {
Page yourPage = pageManager.getPage(yourPagePath);
if (Objects.nonNull(yourPage)) {
YourPageModelClass =yourPage.getContentResource().adaptTo(YourPageModelClass.class);
}
}

 

 

I hope this will help.

kishorekumar14
Level 10
Level 10

Hi @SocialTaylor ,

 

Could you please check if this works.

 

//Sling model

 

@ScriptVariable
private Page currentPage;

public List<String> getPageTags() {
	if(currentPage.getTags().length > 0) {
		List<String> tagsList = new ArrayList<>();			
		Tag[] tags = currentPage.getTags();
		for(Tag tag: tags) {
			tagsList.add(tag.getTitle());				
		}
		return tagsList;
	} else {
		return Collections.emptyList();
	}
}

In HTL

 

<sly data-sly-use.tagsTestModel="com.sample.TagsTestModel"></sly>
<sly data-sly-test.pageTags="${tagsTestModel.pageTags}"/>

<p>${pageTags}</p>