Expand my Community achievements bar.

SOLVED

Convert ACS Generic List into JSON/Array and then Inject JSON/Array into Page

Avatar

Level 4

Hi All,

I have a requirement to access the list stored in ACS Commons Generic List, then convert that list into JSON/Array in the backend and inject that JSON/Array into the page (most likely into customheaderlibs). I want to store JSON/Array in the JavaScript variable on the page. Some of the components on the page will use this list to run some business logic.

<script>
    // If Array
    window.genericList = [${genericListComingFromACSCommons}];
    // OR
    // If JSON
    window.genericList = JSON.parse(${genericListComingFromACSCommons});
</script>

 Added code for clarification only. I have no idea how I will be able to bind the data at a page level. I tried looking this up over the internet but haven't found anything close to what I am looking for.

Any suggestion or idea on implementing this whole setup would be helpful.

Thank you!

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Sure,

Interface:


public interface GenListConverter {
String getGenericListInJson();
}

 

Sling Model:

import com.adobe.acs.commons.genericlists.GenericList;
import com.argenx.core.models.GenListConverter;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.google.gson.Gson;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Default;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class GenListConverterImpl implements GenListConverter {

    @SlingObject
    ResourceResolver resourceResolver;

    @Inject
    @Default(values = "/etc/acs-commons/lists/targets")
    private String genericListPath;

    private String genericListJson;

    @PostConstruct
    protected void init(){
        PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
        Page listPage = pageManager.getPage(genericListPath);
        GenericList genericList = listPage.adaptTo(GenericList.class);
        Gson gson = new Gson();
        genericListJson = gson.toJson(genericList);
    }

    @Override
    public String getGenericListInJson() {return genericListJson;}
}

HTML:

On html call the sling model using sightly

<sly data-sly-use.model="<package-name>.GenListConverter">
${model.genericListInJson}
</sly>

 

this should work. FYI, I haven't built this code, this is something I wrote on a raw editor, please run it and check. Thank you.

View solution in original post

3 Replies

Avatar

Community Advisor

Hi @webdev91 ,

 

you can access your generic list through Page Manager API.

 

PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page listPage = pageManager.getPage("/etc/acs-commons/lists/targets");

Then adapt the Page object to a com.adobe.acs.commons.genericlists.GenericList object:

 GenericList genericList = listPage.adaptTo(GenericList.class);

now the  genericList has a method called getItems() which returns a java.util.List, which you need to convert into a json object.

String jsonStr = JSONArray.toJSONString(genericList.getItems());

you can return this jsonStr to your customHeaderLibs and then keep it in a div for the front end team to consume.

 

Let me know if you want me to write a sling model for you.

Thank you.

 

Regards,

Sravan

Avatar

Level 4

Hi @B_Sravan,

Thank you for your quick response.

I saw this code snippet on the ACS Commons website. But I was confused about implementing the whole setup so that the list would be injected on a page. The reason I mentioned customHeaderLibs is so that the list will be loaded before any other component loads. I was unsure what to use, either a Sling Model, Servlets, or Service.

Since you already mentioned the Sling Model, yes, it would be great if you could write a sling model for me. That would definitely give me a better idea.

Thanks in advance.

Avatar

Correct answer by
Community Advisor

Sure,

Interface:


public interface GenListConverter {
String getGenericListInJson();
}

 

Sling Model:

import com.adobe.acs.commons.genericlists.GenericList;
import com.argenx.core.models.GenListConverter;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.google.gson.Gson;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Default;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class GenListConverterImpl implements GenListConverter {

    @SlingObject
    ResourceResolver resourceResolver;

    @Inject
    @Default(values = "/etc/acs-commons/lists/targets")
    private String genericListPath;

    private String genericListJson;

    @PostConstruct
    protected void init(){
        PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
        Page listPage = pageManager.getPage(genericListPath);
        GenericList genericList = listPage.adaptTo(GenericList.class);
        Gson gson = new Gson();
        genericListJson = gson.toJson(genericList);
    }

    @Override
    public String getGenericListInJson() {return genericListJson;}
}

HTML:

On html call the sling model using sightly

<sly data-sly-use.model="<package-name>.GenListConverter">
${model.genericListInJson}
</sly>

 

this should work. FYI, I haven't built this code, this is something I wrote on a raw editor, please run it and check. Thank you.