January 4, 2021
Estimated Post Reading Time ~

Content Fragment with Component

Browse and use Content fragment inside the custom component
AEM introduced Content Fragment with 6.2 and now almost everyone knows about Content Fragments and How to create and use them.

But we are restricted to use Content Fragments inside page only via Content Fragment components (WCM core content fragment and foundation Content Fragment components)

What if we need to use Content Fragments like other assets e.g. images using PathField or PathBrowser in the component.

There is a possibility to achieve this and Content Fragment can be browsed and used from any component. Content Fragments variations can also be added from the component.

Content Fragment(without variation)
  • In the component, dialog creates a PathField to browse Content Fragment.
  • In HTL, use JAVA API to read HTML content from content fragments master variation node's jcr:data property.


Example :
Component Dailog:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" 
xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="CF Test Dialog"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<heading
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldLabel="Heading"
name="./heading"
required="{Boolean}true"/>
<cf-field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldDescription="Browse CF"
fieldLabel="Browse CF"
name="./cfdata"
rootPath="/content/dam"/>
</items>
</column>
</items>
</content>
</jcr:root>


HTL:
<h2>Content Fragment Test Component</h2>
<h3>${properties.heading}</h3>
<div data-sly-use.cf="${'com.aem.community.core.components.ContentFragmentContent' @ cfInput=properties.cfdata}">
${cf.content @ context='html'}
</div>


JAVA:
Above com.aem.community.core.components.ContentFragmentContent java code is available at GitHub
ContentFragmentContent.java

Content Fragment(with variation)

  • In the component, dialog creates a PathField to browse Content Fragment.
  • Create dropdown with options to populate content fragment variation
  • Create a hidden field item to store content fragment variation value on dialog submit. this value will be used to set the preselected variation option in the dropdown when the dialog will be loaded again.
  • In HTL, use JAVA API to read HTML content from content fragments master or selected variation node's jcr:data property.
  • Create clientlibs with category 'cq.authoring.dialog', add Javascript to populate dropdown option for component variations, variations can be retrieved by making an ajax call to browsed Content Fragment with cfm.info selectors and with JSON extension e.g. http://localhost:4502/content/dam/we-retail/en/experiences/arctic-surfing-in-lofoten/arctic-surfing-in-lofoten.cfm.info.json?ck=0.8366689055424192&_=1535814701363 . Below is the response to the above request, variations can be read and dialog variations dropdown options can be created.
{"name":"arctic-surfing-in-lofoten","title":"Arctic Surfing in Lofoten","description":"Surfing in Northern Norway","path":"/content/dam/we-retail/en/experiences/arctic-surfing-in-lofoten/arctic-surfing-in-lofoten","elements":[{"name":"main","title":"Main","contentType":"text/html"}],"variations":[{"name":"master","title":"Master","description":"Represents the original content fragment"},{"name":"teaser","title":"Teaser","description":""}]}

sample javascript created for demo at cf-variation-handler.js

Example :
Component Dailog:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="CF Test Dialog"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<heading
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldLabel="Heading"
name="./heading"
required="{Boolean}true"/>
<cf-field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldDescription="Browse CF"
fieldLabel="Browse CF"
name="./cfdata"
rootPath="/content/dam"/>
<variation
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
emptyText="Select"
fieldLabel="Variation"
name="./variation"/>
<varhidden
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/hidden"
name="./selectVariation"/>
</items>
</column>
</items>
</content>
</jcr:root>


HTL:
<h2>Content Fragment Test Component</h2>
<h3>${properties.heading}</h3>
<div data-sly-use.cf="${'com.aem.community.core.components.ContentFragmentContent' @ cfInput=properties.cfdata, variation=properties.variation}">
${cf.content @ context='html'}
</div>


JAVA:
Same java code is compatible with both ContentFragmentContent.java




By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.