Expand my Community achievements bar.

SOLVED

Get property name in sling model

Avatar

Level 5

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.

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Here is sample implementation -

 

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

DEBAL_DAS_0-1652776257355.png

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>

DEBAL_DAS_2-1652776557189.png

 

Result -

DEBAL_DAS_1-1652776539242.png

 

Hope this will help. Please review.

 

 

 

 

View solution in original post

6 Replies

Avatar

Community Advisor

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

Avatar

Level 5

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.

Avatar

Community Advisor

@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

Avatar

Community Advisor

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-s...

 

Avatar

Level 3

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:).

shabarish_0-1652703942012.png

 

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);

 

Avatar

Correct answer by
Employee Advisor

Here is sample implementation -

 

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

DEBAL_DAS_0-1652776257355.png

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>

DEBAL_DAS_2-1652776557189.png

 

Result -

DEBAL_DAS_1-1652776539242.png

 

Hope this will help. Please review.