Expand my Community achievements bar.

SOLVED

How do I implement the tagging in the component using Java Model Class?

Avatar

Level 4

Actually, I trying to implement tagging in the component as a list of values to choose and store in the node.  I don't have any idea about doing this. All I know is to use the java model class to get the tagging value and save it in the node.

Kindly help me to achieve this. I really appreciate the help.

1 Accepted Solution

Avatar

Correct answer by
Level 7

You must use the TagManager API to solve your problem.

TagManager allows for resolving and creating tags by paths and names. This interface is generic, but there is a JCR-based reference implementation which can be obtained by the JcrTagManagerFactory - all you need is an existing JCR Session

 

TagManager tagManager = JcrTagManagerFactory.getTagManager(session);
 

In the typical Sling context you can also adapt to a TagManager from the ResourceResolver:

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

and then you can perform your actions.

Few examples you can refer - https://www.programcreek.com/java-api-examples/?api=com.day.cq.tagging.TagManager 

https://github.com/AdobeDocs/experience-manager-64.en/blob/main/help/sites-developing/framework.md 

 

View solution in original post

4 Replies

Avatar

Correct answer by
Level 7

You must use the TagManager API to solve your problem.

TagManager allows for resolving and creating tags by paths and names. This interface is generic, but there is a JCR-based reference implementation which can be obtained by the JcrTagManagerFactory - all you need is an existing JCR Session

 

TagManager tagManager = JcrTagManagerFactory.getTagManager(session);
 

In the typical Sling context you can also adapt to a TagManager from the ResourceResolver:

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

and then you can perform your actions.

Few examples you can refer - https://www.programcreek.com/java-api-examples/?api=com.day.cq.tagging.TagManager 

https://github.com/AdobeDocs/experience-manager-64.en/blob/main/help/sites-developing/framework.md 

 

Avatar

Community Advisor

@Ameen_Dev If it is about custom property on the resource, then it is an usual way of retrieving properties from a resource which is via ValueMap.

Then the value retrieved can be resolved as a tag object. 

 

@Model(adaptable=Resource.class)

public class myClass {

@Self

Resource resource;

@PostConstruct

public void init() {

  PageManager pm = resource.getResourceResolver().adaptTo(PageManager.class);

  Page containingPage = pm.getContainingPage (resource);

  ValueMap pageProperties = containingPage.getProperties();
String tagStr = pageProperties .get("custom-property-name", String.class);
if(null != tagStr){    
Tag actualTag =  tagManager.resolve(tagStr);

//after this you can add your custom business logic, what you want to do with your tag i.e. read tag title, etc.
} }

Another way: 

Tag[] getTags(Resource resource)
Retrieves the tags set on the given resource. Will return tag objects representing the whole repository.
Code Snippet :

 

public List<String> getTagIds(Resource resource) {
  final TagManager tagManager = resourceResolver.adaptTo(TagManager.class);
  final List<String> tagIds = new ArrayList<String>();
  for (Tag tag : tagManager.getTags(resource)) {
    tagIds.add(tag.getTagID());
  }
  return tagIds;
}

 

Thanks

 

Avatar

Level 4

Thanks, @Shailesh_Bassi_

I have written a piece of code to get my scenario. Right now, I am able to get only the particular tag by giving the array number but actually, I need to get all the tags and show them as a dropdown so that the author can choose whatever he wants. Here is the code below. Kindly help.

 

package com.project.core.models.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
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.Optional;
import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.tagging.Tag;
import com.day.cq.tagging.TagManager;
import com.project.core.models.PlanCards;

@Model(adaptables = {Resource.class, SlingHttpServletRequest.class},
		 adapters = { PlanCards.class}, 
		 resourceType = {PlanCardsImpl.RESOURCE_TYPE})

public class PlanCardsImpl implements PlanCards {
	private static final Logger LOG = LoggerFactory.getLogger(PlanCardsImpl.class);

    /**
     * The resource type.
     */
    protected static final String RESOURCE_TYPE = "project/components/nwt/slider";

    @SlingObject
    @Optional
    private Resource currentRes;

    @Self
    @Optional
    private SlingHttpServletRequest request;

    @SlingObject
    private ResourceResolver resourceResolver;
    
    @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
	private String dataUses;
   
    @Override
	public String getDataUses() {
		return dataUses;
	}

	public void setDataUses(String dataUses) {
		this.dataUses = dataUses;
	}

	@PostConstruct
	  protected void init() {
		String plancardTag = "/content/cq:tags/project/plan-cards/data-uses";
		LOG.info("int() --> Plan cards default value");
		final TagManager tagManager = currentRes.getResourceResolver().adaptTo(TagManager.class);
	    final List<String> filterTagList = new ArrayList<>();
	    LOG.info("Product Details Filter tag path:: {}", plancardTag);
	    if (StringUtils.isNotBlank(plancardTag)) {
	      final Tag tag = tagManager.resolve(plancardTag);
	      if (null != tag) {
	        tag.listChildren().forEachRemaining(childtag -> {
	          filterTagList.add(childtag.getTitle());
	          LOG.info("childtag.getName():: {}", childtag.getName());
	        });
	      }
	    }
	    LOG.info("filterTagList:: {}", filterTagList.toString());
	    if (StringUtils.isBlank(dataUses)) {
	    	this.dataUses = filterTagList.get(1);
	    }

	  }
}

Avatar

Community Advisor

Hi @Ameen_Dev ,

You can use ValueMap for tags that are authored on a custom component and InheritanceValueMap for tags authored on Page Properties in Sling Model as below :

Model Class for Custom Component :

@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TagModel {

@Inject
private ValueMap valueMap;

@Self
private SlingHttpServletRequest request;

@PostConstruct
protected void init() {
//Getting all Tags from ValueMap
String[] allTags = valueMap.get("customTagName", String[].class);
TagManager tagManager = request.getResourceResolver().adaptTo(TagManager.class);
for (String tags : allTags) {
Tag tag = tagManager.resolve(tags);
//Custom Code using custom Tags
}
}
}

 Model Class for Page Properties Tags:

@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TagModel {

@Inject
private InheritanceValueMap pageProperties;

@Self
private SlingHttpServletRequest request;

@PostConstruct
protected void init() {
//Getting all Tags from InheritanceValueMap
String[] allTags = pageProperties.get("cq:Tags", String[].class);
TagManager tagManager = request.getResourceResolver().adaptTo(TagManager.class);
for (String tags : allTags) {
Tag tag = tagManager.resolve(tags);
//Custom Code using Page Properties Tags
}
}

In the above Model class, you can set up a getter as per your need.

Also, you can call Sling Model in Sightly as 

<sly data-sly-use.modelObject="${'com.adobe.learning.core.models.TagModel'}">

Hope this will help you!!!

Regards,

Shiv

Shiv Prakash