Creating Content Fragments Programmatically (Best Practice)? | Community
Skip to main content
New Participant
February 7, 2022
Solved

Creating Content Fragments Programmatically (Best Practice)?

  • February 7, 2022
  • 2 replies
  • 4769 views

Hey all,

 

I'm working on a service will take data from an API &, in theory, write what is returned to a list of content fragments. I've gotten pretty far along, but I'm wondering if there's a better / cleaner way than my current approach. 

 

Right now I have a function createContentFragment (seen below) which takes in a fullBranch object (data I want to turn into a content fragment), parentResource (self explanatory) and templateResource (template of the content fragment I want to turn this data into).

I noticed in the ContentFragment class that there's not a "setValues" or "setValue"  function... it seems from the documentation that I would need to iterate over each contentElement & set each value individually. Obviously this is pretty annoying, so wondering if anyone has any suggestions on how to better / more easily set the ContentElement values than my intended approach? I also have a Store model (separate from the templateResource for now) which I was thinking I could possibly connect to the content fragment somehow? Not sure if this is possible. Any help is much appreciated!

 

private void createContentFragment(FullBranch fullBranch, Resource parentResource, Resource templateResource) { try { FragmentTemplate tpl = templateResource.adaptTo(FragmentTemplate.class); if (tpl != null) { ContentFragment newFragment = tpl.createFragment(parentResource, fullBranch.getKey(), fullBranch.getName()); Iterator < ContentElement > contentElement = newFragment.getElements(); //current long winded approach while (contentElement.hasNext()) { ContentElement contentElementObject = contentElement.next(); FragmentData value = contentElementObject.getValue(); String FieldName = contentElementObject.getName(); //would have to get the value from fullBranch using the FieldName and another function w/ a switch statement value.setValue("test"); contentElementObject.setValue(value); } } ObjectMapper().writeValueAsString(fullBranch)); } catch (Exception ex) { LOGGER.error("Something went wrong" + ex.getMessage()); } }
This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by Mani_kumar_

Please find the some of the same code below.

 Resource fragmentResource = resourceResolver.getResource(fragmentPath);
        if (null != fragmentResource) {
            ContentFragment contentFragment = fragmentResource.adaptTo(ContentFragment.class);
            if (null != contentFragment) {
                Iterator<ContentElement> elements = contentFragment.getElements();
                while (elements.hasNext()) {
                    ContentElement contentElement = elements.next();
                    if (contentElement.getValue().getDataType().isMultiValue()) {
                        String[] values = contentElement.getValue().getValue(String[].class);
                        String value = null;
    
                        if (values != null) {
                            value = StringUtils.join(values, CommonConstants.CHAR_COMMA);
                            cfElements.put(contentElement.getName(), value);
                        }
    
                    } else {
                        cfElements.put(contentElement.getName(), contentElement.getContent());
                    }
                }
            }
        }

 

Also check below thread for creating CFs.

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/programmatically-create-a-contentfragment/td-p/360808

 

2 replies

Mani_kumar_
Mani_kumar_Accepted solution
New Participant
February 8, 2022

Please find the some of the same code below.

 Resource fragmentResource = resourceResolver.getResource(fragmentPath);
        if (null != fragmentResource) {
            ContentFragment contentFragment = fragmentResource.adaptTo(ContentFragment.class);
            if (null != contentFragment) {
                Iterator<ContentElement> elements = contentFragment.getElements();
                while (elements.hasNext()) {
                    ContentElement contentElement = elements.next();
                    if (contentElement.getValue().getDataType().isMultiValue()) {
                        String[] values = contentElement.getValue().getValue(String[].class);
                        String value = null;
    
                        if (values != null) {
                            value = StringUtils.join(values, CommonConstants.CHAR_COMMA);
                            cfElements.put(contentElement.getName(), value);
                        }
    
                    } else {
                        cfElements.put(contentElement.getName(), contentElement.getContent());
                    }
                }
            }
        }

 

Also check below thread for creating CFs.

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/programmatically-create-a-contentfragment/td-p/360808

 

sreenu539
New Participant
July 13, 2023

any example to unit test 

contentElement.getValue().getValue(String[].class);

I am getting io.wcm unsupported operation exception, when trying to unit test this specific line of code. 

milind_bachani
Employee
February 8, 2022
user00928Author
New Participant
February 8, 2022

Thanks for the reply, I followed the first link's guidelines, but was more wondering if it was possible to map a Model to the content fragment (i.e. use setters from that model to fill in data)... the second link you sent I believe references fragmentManager.create() which I think is a deprecated function in newer versions of AEM