When I am trying to access the page model json, I see just the sling resource type component name and not the exact node values. I tried different ways and when I say <page-name>.model.json, it always returns the nodes that are at first level. Child nodes are not being retrieved. To explain it better see the following JSON response.
"productlist": {
"columnClassNames": "aem-GridColumn aem-GridColumn--default--12",
":type": "demo/components/content/productlist",
"headlineText": "Product List"
}
if you see the above JSON which is rendered when I did page mode json and it has a component called ProductList which is a multifield type. IT returns the type of component and not exact values inside it. I tried all ways using Jackson annotations to make it work, but no luck. So if anyone has faced the same issue and could help me with the best approach, it would be helpful.
When I checked List component, it has one multifield value as text and it is stored as String[] in JCR. I am not sure how can I do that with the composite multifield. Because under productlist node I will be having node structure as below.
Each node having two properties. It could be more. To retrieve the values, I have a sling model with these two properties and I am referencing the same model as List<LinksModel> links where LinksModel is the sling model with above mentioned two properties.
Does .infinity.json solve your purpose?
Views
Replies
Total Likes
@Hemant,
then what is the purpose of having Sling Models and exporter framework ? I want to use sling models to retrieve specific fields using sling models.
Views
Replies
Total Likes
"I want to use sling models to retrieve specific fields using sling models."
To render MF values onto a web page by Sling Models (which is the main use case for using Multi-fields - not to render as JSON) - its straightforward.
See this Article -- Scott's Digital Community: Creating a HTL Repeating Data Set 6.3 Component that uses Sling Models
There is very little Java code. You Inject the node that represents the Multi field - as shown in the article. The Java code:
package
com.htl.community.coral.core.models;
import
javax.annotation.PostConstruct;
import
javax.inject.Inject;
import
javax.inject.Named;
import
org.apache.sling.api.resource.Resource;
import
org.apache.sling.models.annotations.Default;
import
org.apache.sling.models.annotations.Model;
import
org.apache.sling.models.annotations.Optional;
import
org.apache.sling.settings.SlingSettingsService;
@Model
(adaptables = Resource.
class
)
public
class
Multifield {
// Inject the products node under the current node
@Inject
@Optional
public
Resource products;
// No need of a post construct as we don't have anything to modify after the
// model is constructed
}
Then you can write out the MF values in HTL like this:
<
div
data-sly-use.multiItems
=
"com.htl.community.coral.core.models.Multifield"
>
<
div
data-sly-list.head
=
"${multiItems.products.listChildren}"
>
<
div
style
=
"height:250px;"
><
img
src=${head.pathbr}
height
=
200
width
=
270
style
=
"padding:4px"
/><
h2
>${head.product}</
h2
>
<
p
>${head.desc}</
p
>
</
div
>
<
hr
>
</
div
>
</
div
>
When you render MF values as HTML - the output is shown in the web page. For example:
Views
Replies
Total Likes
Thanks for the reply. I tried this way initially and I still see the same output. I am not trying to iterate the values in a html. I want the JSON response of that multifield component with values inside it. When I did page.model.json, I see the below JSON response. And I have only one component multifield on the page.
{"title": "HomePage",
"lastModifiedDate": 1525322551215,
"templateName": "content-page",
"cssClassNames": "page basicpage",
"language": "en",
":items": {
"root": {
"gridClassNames": "aem-Grid aem-Grid--12 aem-Grid--default--12",
"columnCount": 12,
":items": {
"responsivegrid": {
"gridClassNames": "aem-Grid aem-Grid--12 aem-Grid--default--12",
"columnCount": 12,
":items": {
"testmulti": {
":type": "reactaem/components/content/testmulti",
"columnClassNames": "aem-GridColumn aem-GridColumn--default--12"}
},
":itemsOrder": ["testmulti"],
":type": "wcm/foundation/components/responsivegrid",
"columnClassNames": "aem-GridColumn aem-GridColumn--default--12"}
},
":itemsOrder": ["responsivegrid"],
":type": "wcm/foundation/components/responsivegrid"}},
":itemsOrder": ["root"],
":type": "reactaem/components/structure/page"
}
If you see the highlighted "Bold" "testmulti" node, that is actual multi filed with values inside it. But I don't see them when I do
http://localhost:6302/content/reactaem/en/HomePage.model.json . Find the JCR node structure below.
If you observe the node structure of multifield, and when I say paage.mode.json instead of just giving me the type of component, I am expecting to give me JSON like
":items": {
"testmulti": {
[
":type": "reactaem/components/content/testmulti",
"columnClassNames": "aem-GridColumn aem-GridColumn--default--12",
"pathbr": "/content/en",
"product": "English"
],
[
":type": "reactaem/components/content/testmulti",
"columnClassNames": "aem-GridColumn aem-GridColumn--default--12",
"pathbr": "/content/en",
"product": "French"
]
}
Enable the AEM content services feature flag and append .caas.json to the url
http://localhost:4504/content/AEM63App/en.caas.json
I hope this helps
Views
Replies
Total Likes
Also - please explain why you want this output as JSON - are you using the JSON for input somewhere else - ie - a JS Framework lib?
Most of the use cases for MF is to render the values as HTML.
Views
Replies
Total Likes
Also - if you really need JSON for some other process - there is a way to achieve this.
Views
Replies
Total Likes
Yes, there are ways. I want to know if Sling Model supports the way I was trying to achieve and not that I am missing some thing.
Views
Replies
Total Likes
Hi Narendran,
Did you ever resolve this?
I too have been looking at a similar thing and have the same problem as you. I have sling models to back my resource and when I access the full path of the resource with .model.json I get all the data I expect including the multi-field data. However when I try this at the page level, I get the resource model data but not for the multi-field.
I have seen that http://localhost:4502/content/we-retail/language-masters/en.model.json you can see that the core list component includes the multi-field data. However I cannot see what is different in the core list model to mine that make this work. In fact the list model looks very different to how the sling model tutorial suggests.
Have you managed to resolve this?
Views
Replies
Total Likes
If someone is looking for idea to implement custom solution for this, you can check below:
AEM - Get JSON response of an AEM Page
Note : It is just an idea.
Views
Replies
Total Likes
Yes, I want this JSON to be passed to Front END to render the experience.
Views
Replies
Total Likes
"Yes, I want this JSON to be passed to Front END to render the experience." - you may have to look at writing a custom AEM Service that reads the nodes and retrieves the node data. Then you can encode the data into JSON in a way that meets your business requirements.
Views
Replies
Total Likes
Hi Narendran
Could you please explain me what is the exact use case you are trying to acheive? I believe you are trying to fetch the values of multiflield using Sling models ? I couln't understand your question exactly
Thanks
Veena
Views
Replies
Total Likes
Hi Veena,
Go to any page which is ootb, and then hit model.json. For ex: http://localhost:4502/content/we-retail/us/en.model.json.
If you check this Page Json, you see all the components that are being used on that page which is expected. Now create any composite multifield component and drop it on the page as I did in my original post. It is not needed to be complex. Just have a multifield with two fields, 1) Text and 2) path field.
Now drop the same component on the same en.html page and try to render the model.json. Now you will see the component type and not the actual content there. I see Model json is returning the first level component values and not the child nodes under those components. Let me know if you need more details.
Views
Replies
Total Likes
Hi narendran63116907 / iainc65537558
Views
Replies
Total Likes
Thanks very much - that has done the trick. For the record this is the code. (I am sure there are other issues with the code, but for the meantime this works)
@Model(
adaptables = { SlingHttpServletRequest.class, Resource.class },
adapters = { NewsCarouselModel.class, ComponentExporter.class },
resourceType = NewsCarouselModel.RESOURCE_TYPE
)
@Exporter(name = "jackson", extensions = "json", options = {})
@JsonSerialize(as = NewsCarouselModel.class)
public class NewsCarouselModel implements ComponentExporter {
static final String RESOURCE_TYPE = "my-apps/components/content/newsCarousel";
@ChildResource(name = "newsItems",injectionStrategy = InjectionStrategy.OPTIONAL)
private List<NewsItems> newsItems = new ArrayList<>();
public List<NewsItems> getNewsItems() {
return newsItems;
}
public void setNewsItems(List<NewsItems> newsItems) {
this.newsItems = newsItems;
}
@Model(adaptables = { SlingHttpServletRequest.class,Resource.class })
public static class NewsItems {
@Inject
@Optional
@Named("title")
private String title;
@Inject
@Optional
@Named("link")
private String link;
@Inject
@Optional
@Named("description")
private String description;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
@Override
public String getExportedType() {
return RESOURCE_TYPE;
}
}
Views
Replies
Total Likes
Not 100% done - I appear to have broken the sling model such that it is not returning data to my HTL script or when I directly request the resource with the .model.json selector. It brings back the multifield, but if I have top level properties it is not returning them.
Views
Replies
Total Likes
All sorted now - changed @Inject to @ValueMapValue and model is getting returned correctly in all instances. Into the HTL from the use method and from the model.json request on both the resource and the page.
Thanks to balajia1879175 for the guidance.
Views
Replies
Total Likes
Hi @iainc65537558 ,
I am trying to do something similar but not able to.
Can you help me how actually it worked for you.
When i hit the component resource path with .model.json extension,i am only getting the properties saved in that node and not the child nodes.
Views
Replies
Total Likes
Hi Narendran,
I am facing a similar issue like this. Did you find a solution for this?
Thanks,
Rajeswari K
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies