How to get design dialog properties in Sling model? - aem

I have a design dialog where the values are getting stored in etc/design//. But now how should i read these property in Sling model?

you could use script-bindings to get currentStyle -
#Inject #Source("script-bindings")
private Style currentStyle
then use -
currentStyle.get("<name of the text field>",String.class)

You can inject a ResourceResolverFactory then get a ResourceResolver and then obtain any property you need.

Related

HTL Access Property Without Getter

I'm writing an AEM component and I have an object being returned that is a type from an SDK. This type has public properties and no getters. For simplicity, it might be defined like this:
class MyItem {
public String prop1;
public String prop2;
}
Now normally, I would need a getter, like so:
class MyItem {
public String prop1;
public String prop2;
public String getProp1() {
return prop1;
}
}
But I do not have this luxury. Right now, I've got a Java implementation that uses another type to resolve this, but I think it's sort of crazy that HTL doesn't allow me to just access prop1 directly (it calls the getter). I've reviewed the documentation and can't see any indication of how this could be done. I'd like to be able to write:
${item.prop1}
And have it access the public property instead of calling getProp1().
Is this possible?
You don't need getters for public fields if those fields were declared by your Java Use-class. There's actually a test in Apache Sling that covers this scenario:
https://github.com/apache/sling/blob/trunk/bundles/scripting/sightly/testing-content/src/main/resources/SLING-INF/apps/sightly/scripts/use/repopojo.html
This also applies to Use-classes exported from bundles.
For Sling Models using the adapter pattern [0] I've created https://issues.apache.org/jira/browse/SLING-7075.
[0] - https://sling.apache.org/documentation/bundles/models.html#specifying-an-alternate-adapter-class-since-110
From the official documentation
Once the use-class has initialized, the HTL file is run. During this stage HTL will typically pull in the state of various member variables of the use-class and render them for presentation.
To provide access to these values from within the HTL file you must define custom getter methods in the use-class according to the following naming convention:
A method of the form getXyz will expose within the HTL file an object property called xyz.
For example, in the following example, the methods getTitle and getDescription result in the object properties title and description becoming accessible within the context of the HTL file:
The HTL parser does enumerate all the public properties just like any java enumeration of public fuields which include getters and public memebers.
Although it is questionable on whether you should have public variable but thats not part of this discussion. In essence ot should work as pointed by others.

How to call Sling Model Method with input parameter AEM

I am having a scenario in which i want to call a sling model with input parameter.
For this i have a code like this
<div data-sly-use.model3="${'com.bhf.aem.sling.models.Test' # colour='red'}">
</div>
But I want to call a method in sling model twice with two different parameters .Is it possible with sling models?
Any Help!!!
From AEM 6.3 there is a new HTL feature that allows to do this.
In the data-sly-include and data-sly-resource you can now pass
requestAttributes in order to use them in the receiving HTL-script.
This allows you to properly pass-in parameters into scripts or
components.
<sly data-sly-use.settings="com.adobe.examples.htl.core.hashmap.Settings"
data-sly-include="${ 'productdetails.html' # requestAttributes=settings.settings}"/>
Java-code of the Settings class, the Map is used to pass in the
requestAttributes:
public class Settings extends WCMUsePojo {
// used to pass is requestAttributes to data-sly-resource
public Map<String, Object> settings = new HashMap<String, Object>();
#Override
public void activate() throws Exception {
settings.put("layout", "flex");
}
}
For example, via a Sling-Model, you can consume the value of the specified requestAttributes. In this example, layout is injected via the Map from the Use-class:
#Model(adaptables=SlingHttpServletRequest.class)
public class ProductSettings {
#Inject #Optional #Default(values="empty")
public String layout;
}
By design of the HTL/Sightly language, sending parameters is only possible for data-sly-use (use objects initialization) and data-sly-call (template calls). The reason for this is to separate business logic from the view.
As mentioned by #tomasz-szymulewski, since https://issues.apache.org/jira/browse/SLING-5812, there is support for passing request attributes on resource/script inclusion in the Sling/AEM implementation.

How to access parent node properties in sightly?

We'l do in cq5(jsp) by accessing currentNode.getParent().getProperties();
How can we do similar thing in sightly?
You will need to implement a use class extending WCMUsePojo class or a sling model that exposes a method that returns you the properties of the parent node/resource.
Refer here for sling models, also refer to similar question here
You can still access these by ${currentNode.parent.properties}. Unfortunately this will return a PropertyIterator (see docs) and data-sly-list does not currently offer support for iterators.
So you will need to implement a Use API helper to gather those into a collection.
Just use
${currentPage.parent.properties['jcr:title']} or ${currentPage.parent.title}

Is there a global setting in Mapstruct that will trim a string value prior to setting it to a destination bean property

Is it possible to trim a string value before it is set against a bean property of type string in the destination bean?
Dozer offers such a facility through its mapping configuration for example,
<configuration>
<trim-strings>true</trim-strings>
</configuration>
Also see Dozer Global Configuration
With MapStruct 1.0.0.Final I can achieve this through Expressions or Before/After Mapping customization.
But wanted to know if there is a better way to handle such use cases.
Thanks in advance.
It appears MapStruct in its current form does not support this.
However one can achieve this effect with custom mapper methods, for example implement a class with a method that trims a String argument passed to it and then reference this class in the use attribute of the #Mapper annotation.
More at Invoking other mappers
If you require fine gained access control you could use
Selection based on Qualifiers
I was made aware of these approaches in response to a question I posted in mapstruct Google group
Example from #venkat-srinivasan answer's:
public class StringTrimmer {
public String trimString(String value) {
return value.trim();
}
}
and then in your mapper interface or class:
#Mapper(uses = StringTrimmer.class)
public interface MyMapper {

How to extend tag.object with new attributes within Adobe CQ5 TagManager API

I want to extend tag.object (TagManager API) with new attributes. By default, every tag.object has three attributes: name, title and description. Is it possible? Has anybody deal with it?
You would need to implement your own TagManager - probably extending the abstract TagManager interface and implementing it.
Have a look at the com.day.cq.tagging.impl package - especially the JcrTagManagerImpl class.
A workaround would be to wrap the tag object and encode the additional properties into the description field.