Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events

Access Properties values set via WCM USE class

Avatar

Level 4

WCM USE class creates a MAP from backend Service.

 

resource.adaptTo(ModifiableValueMap.class).putAll(backendPropertyMAP); // Creates a MAP of all properties custom + authored

In HTML
 

<a   ng-class="${properties.key1fromResource}" ng-disabled="${properties.key2fromResource}"> TEXT </a>

 

Above snippet works fine when user who has all permissions views the page.

But when I view the page for a user who only has read access on ‘/content/page’ values don’t get printed and end result is

 <a> TEXT </a>

 

One way to handle is store values in JCR nodes which can be fetched in HTML, checking if there is a way to still read properties for a user with Read only access without saving in JCR node.

8 Replies

Avatar

Employee

You can also access the Map (backendPropertyMAP) by the component.

There is no need to put these values into the resource object.

Avatar

Employee

See your point, still I would save this in a proper way. Not by workarounds.

Avatar

Level 4

Gdubz wrote...

Hi ptK,

Firstly, WCMUse[1] is deprecated, use WCMUsePojo[2] instead. Secondly, is there any particular reason you're using a ModifiableValueMap[3] to READ values? You should really just be using a regular ValueMap[4] instead, if you can help it.

In the event that you can't help but use the ModifiableValueMap, you may need to utilize a Service Resolver[5] that has sufficient privileges to read and write content, in lieu of the user's (possibly unprivileged) ResourceResolver[6].

[1] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/com/adobe/cq/sightly/WCMUse.html
[2] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/com/adobe/cq/sightly/WCMUsePojo.html
[3] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/org/apache/sling/api/resource/ModifiableV...
[4] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/org/apache/sling/api/resource/ValueMap.ht...
[5] https://helpx.adobe.com/experience-manager/using/querying-experience-manager-sling.html
[6] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/org/apache/sling/api/resource/ResourceRes...

 

        Tried Creating a resource from Service , but still facing the same issue.
        
       

 
// Method to create resource // resourcePath= getResource().getPath(); Values passed from WCM Class Map<String, Object> param = new HashMap<String, Object>(); param.put(ResourceResolverFactory.SUBSERVICE, "backendMap"); ResourceResolver resolver = null; try { resolver = resourceResolverFactory.getServiceResourceResolver(param); resolver.getResource(resourcePath); session = resolver.adaptTo(Session.class); } catch (org.apache.sling.api.resource.LoginException e1) { log.info("Login Exception "+e1.getMessage()); } return resolver.getResource(resourcePath);

        
        When I view my "resource" object in my debugger I see all custom properties stored in WCM Class.

        But when I try to access values using ${properties.key1fromResource} I see empty values 
        
 

Avatar

Level 5

ptK wrote...

Gdubz wrote...

Hi ptK,

Firstly, WCMUse[1] is deprecated, use WCMUsePojo[2] instead. Secondly, is there any particular reason you're using a ModifiableValueMap[3] to READ values? You should really just be using a regular ValueMap[4] instead, if you can help it.

In the event that you can't help but use the ModifiableValueMap, you may need to utilize a Service Resolver[5] that has sufficient privileges to read and write content, in lieu of the user's (possibly unprivileged) ResourceResolver[6].

[1] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/com/adobe/cq/sightly/WCMUse.html
[2] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/com/adobe/cq/sightly/WCMUsePojo.html
[3] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/org/apache/sling/api/resource/ModifiableV...
[4] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/org/apache/sling/api/resource/ValueMap.ht...
[5] https://helpx.adobe.com/experience-manager/using/querying-experience-manager-sling.html
[6] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/org/apache/sling/api/resource/ResourceRes...

 

        Tried Creating a resource from Service , but still facing the same issue.
        
       

  1.  
 
  1. // Method to create resource
  2. // resourcePath= getResource().getPath(); Values passed from WCM Class
  3. Map<String, Object> param = new HashMap<String, Object>();
  4. param.put(ResourceResolverFactory.SUBSERVICE, "backendMap");
  5. ResourceResolver resolver = null;
  6. try {
  7. resolver = resourceResolverFactory.getServiceResourceResolver(param);
  8. resolver.getResource(resourcePath);
  9. session = resolver.adaptTo(Session.class);
  10.  
  11.  
  12. } catch (org.apache.sling.api.resource.LoginException e1) {
  13. log.info("Login Exception "+e1.getMessage());
  14. }
  15. return resolver.getResource(resourcePath);
  16.  

        
        When I view my "resource" object in my debugger I see all custom properties stored in WCM Class.

        But when I try to access values using ${properties.key1fromResource} I see empty values 
        
 

 

You're probably seeing the values in the debugger because it's showing you what has been modified during that session (without regard to whether you've saved your changes or not). However, without persisting your changes to the resource, when accessed via ${ properties.* } from your component, it's likely that your injected property key/values will be empty. There could also be a conflict because you're using a reserved/pre-defined "properties" variable, that just may not care about your injected values. I really don't know in this case, just throwing it out there as a possibility.

The easiest solution would probably be what Feike was suggesting, which is to utilize the ${ properties } variable for authored properties, and your own separate custom map variable for injected properties. Could also look into possibly using a @SlingFilter[1] (example[2]) instead of a WCMUsePojo class, to intercept the resource property definition and inject your values there. Should warn you that if you don't scope this properly, it could be resource heavy.

[1] https://sling.apache.org/documentation/the-sling-engine/filters.html
[2] https://github.com/Adobe-Consulting-Services/acs-aem-samples/blob/master/bundle/src/main/java/com/ad...

Avatar

Level 10

Agree with Greg - create a Service Resolver that has sufficient privileges to read and write content. That is true of most JCR operations. 

Avatar

Level 4

Service Resolver works , after saving the session , values are stored at content node. I  dont want values to be stored in JCR  so session.save() or resource.commit() wont be helpful. 

         Following code returns NULL when user does not have write permissions: 

ModifiableValueMap valueMap = resource.adaptTo(ModifiableValueMap.class);


      http://labs.6dglobal.com/blog/2015-02-17/modifiablevaluemap-not-found/ talks about the issue .  I wonder if we code can still inject values to resource after user does not have permissions to write 

      Is there a reference code available for this kind of problem ?

Avatar

Employee

How you want to solve this issue via a Resource is just not the way, as you can see you arrive in kind of hacks and workarounds.

Split this into other methods that you can access in your component.