Get property name in sling model | Community
Skip to main content
Level 4
May 15, 2022
Solved

Get property name in sling model

  • May 15, 2022
  • 4 replies
  • 5986 views

I have added custom tab in Page component's dialog. In that tab there are three fields. I want to render those three fields in HTL. Is there a way that the fields' name can be dynamically get in the model. I know how to get those fields' value but don't know how to get there name (eg: ./description, ./title). I want to pass the field names to my HTL dynamically.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by DEBAL_DAS

Here is sample implementation -

 

I was targetting /apps/weretail/components/structure/page/cq:dialog/content/items/tabs/items/socialmedia as shown below -

I would like to read name property of inputgroup, fieldfacebookAppIdvariantpathsocialmedia_type

In my AEM instance inputgroup and field doesn't have name property.

 

Sample Sling model -

 

package com.aem.demo.core.models;

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

import javax.annotation.PostConstruct;

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

import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.components.ComponentManager;

@Model(adaptables = SlingHttpServletRequest.class)
public class PagePropertiesModel {

	
	private ValueMap componentPropertymap;

	
	private List<String> propertylist;
	private String namepropertyvalue;

	@SlingObject
	SlingHttpServletRequest slingHttpServletRequest;

	@PostConstruct
	protected void init() {

		String relativecomponentPath = slingHttpServletRequest.getResource().getResourceType();

		 propertylist = new ArrayList<String>();

		ComponentManager componentManager = slingHttpServletRequest.getResourceResolver()
				.adaptTo(ComponentManager.class);

		Component component = componentManager.getComponent(relativecomponentPath);
		Resource localResource = component.getLocalResource("cq:dialog");

		Resource childresource = localResource
				.getChild("content/items/tabs/items/socialmedia/items/column/items/section/items");
		
		for (Resource resource : childresource.getChildren()) {
			componentPropertymap = resource.getValueMap();
			namepropertyvalue = componentPropertymap.get("name", String.class);
			propertylist.add(namepropertyvalue);
			
		}

		

	}

	/**
	 * @return the propertylist
	 */
	public List<String> getPropertylist() {
		return propertylist;
	}

	

}

HTL code -

<sly data-sly-use.compObj="com.aem.demo.core.models.PagePropertiesModel">
  <ul data-sly-list="${compObj.propertylist}">
    <li>${item}</li>
  </ul>
</sly>

 

Result -

 

Hope this will help. Please review.

 

 

 

 

4 replies

arunpatidar
Community Advisor
Community Advisor
May 15, 2022

Hi,

what name properties have you used for those dialog field. That should be the name you must used.

 

${pageProperties.customeProp1}

 

Or you can get the whole Page object inside Model and from there extract the property and expose via methods like

 

getCustomProperty1(){
return prop1

}

Arun Patidar
Level 4
May 15, 2022

Actually I'm extending teaser component for the list component. So, basically I have to add social links on the teaser which will be showing the links extracted from the child page's page properties.

I have created a tab Social in page properties and in that tab there are three fields, fbLink, twitterLink and LinkedIn link. Now I want that I can access any number of fields inside Social tab. Not specifically these three but code should be dynamic.

Vijayalakshmi_S
Level 10
May 17, 2022

@nikita24tailor 

You can make use of Composite multifield to retrieve social media links where each multifield item/fieldset is 

  • Social Media Name/Label 
  • Social Media Link

By this way, it will just be the multifield fieldset name property + field name of socialmediaName and socialMediaLink that you need to use in the backend logic and can add any number of links in the future. 

 

Note :

Composite multifield node saves as node structure, so you can use either 

getContentResource(String relativePath) or getProperties(String relativePath) of Page object

MayurSatav
Community Advisor and Adobe Champion
Community Advisor and Adobe Champion
May 16, 2022

Hi @nikita24tailor ,

 

I had a similar requirement, Fetching page properties data in the sling model for further processing and the below solution worked for me.

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/fetch-page-properties-in-sling-model/td-p/321017

 

shabarish
Level 2
May 16, 2022

Hi @nikita24tailor ,

Its possible to get the name of  page properties but its not possible to identify those are from social tab. To identify those from social tab you can append social: in beginning of the name, Like how is done in OOTB( cq:, jcr:).

 

After that you can use Sling Model to get the names of the current page properties where component is authored by below code

@SlingObject
private Resource currentResource;
@SlingObject
private ResourceResolver resourceResolver;

@PostConstruct
protected void init() {
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page currentPage = Optional.ofNullable(pageManager)
.map(pm -> pm.getContainingPage(currentResource)).orElse(null);
ValueMap properties = currentPage.getProperties();
Set<String> socialProperties = properties.keySet().stream().filter(key -> key.startsWith("social:")).collect(Collectors.toSet());
LOG.info("Social properties:"+socialProperties);

 

DEBAL_DAS
DEBAL_DASAccepted solution
New Member
May 17, 2022

Here is sample implementation -

 

I was targetting /apps/weretail/components/structure/page/cq:dialog/content/items/tabs/items/socialmedia as shown below -

I would like to read name property of inputgroup, fieldfacebookAppIdvariantpathsocialmedia_type

In my AEM instance inputgroup and field doesn't have name property.

 

Sample Sling model -

 

package com.aem.demo.core.models;

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

import javax.annotation.PostConstruct;

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

import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.components.ComponentManager;

@Model(adaptables = SlingHttpServletRequest.class)
public class PagePropertiesModel {

	
	private ValueMap componentPropertymap;

	
	private List<String> propertylist;
	private String namepropertyvalue;

	@SlingObject
	SlingHttpServletRequest slingHttpServletRequest;

	@PostConstruct
	protected void init() {

		String relativecomponentPath = slingHttpServletRequest.getResource().getResourceType();

		 propertylist = new ArrayList<String>();

		ComponentManager componentManager = slingHttpServletRequest.getResourceResolver()
				.adaptTo(ComponentManager.class);

		Component component = componentManager.getComponent(relativecomponentPath);
		Resource localResource = component.getLocalResource("cq:dialog");

		Resource childresource = localResource
				.getChild("content/items/tabs/items/socialmedia/items/column/items/section/items");
		
		for (Resource resource : childresource.getChildren()) {
			componentPropertymap = resource.getValueMap();
			namepropertyvalue = componentPropertymap.get("name", String.class);
			propertylist.add(namepropertyvalue);
			
		}

		

	}

	/**
	 * @return the propertylist
	 */
	public List<String> getPropertylist() {
		return propertylist;
	}

	

}

HTL code -

<sly data-sly-use.compObj="com.aem.demo.core.models.PagePropertiesModel">
  <ul data-sly-list="${compObj.propertylist}">
    <li>${item}</li>
  </ul>
</sly>

 

Result -

 

Hope this will help. Please review.

 

 

 

 

Debal Das, Senior AEM Consultant