Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
Expand All @@ -45,6 +46,7 @@
import com.adobe.cq.export.json.ContainerExporter;
import com.adobe.cq.export.json.ExporterConstants;
import com.adobe.cq.wcm.core.components.internal.ContentFragmentUtils;

import com.adobe.cq.wcm.core.components.util.AbstractComponentImpl;
import com.adobe.cq.wcm.core.components.internal.models.v1.datalayer.ContentFragmentDataImpl;
import com.adobe.cq.wcm.core.components.models.contentfragment.ContentFragment;
Expand Down Expand Up @@ -106,14 +108,30 @@ public class ContentFragmentImpl extends AbstractComponentImpl implements Conten
@Nullable
private String displayMode;

@ValueMapValue(name = "vcfTemplate", injectionStrategy = InjectionStrategy.OPTIONAL)
@Nullable
private String vcfTemplate;

private DAMContentFragment damContentFragment = new EmptyContentFragment();

private String fragmentId;

private static final String MASTER_VARIATION = "master";
private static final String VCF_PUBLISH_URL_FORMAT = "/adobe/experimental/previewtemplates-expires-20260301/contentFragments/%s/%s/%s.html";

@PostConstruct
private void initModel() {
if (StringUtils.isNotEmpty(fragmentPath)) {
Resource fragmentResource = resourceResolver.getResource(fragmentPath);
if (fragmentResource != null) {
damContentFragment = new DAMContentFragmentImpl(fragmentResource, contentTypeConverter, variationName, elementNames);
fragmentId = fragmentResource.getValueMap().get("jcr:uuid", String.class);
if (fragmentId == null) {
Resource jcrContent = fragmentResource.getChild("jcr:content");
if (jcrContent != null) {
fragmentId = jcrContent.getValueMap().get("jcr:uuid", String.class);
}
}
}
}
}
Expand Down Expand Up @@ -224,6 +242,23 @@ public String[] getParagraphs() {
return content.split("(?=(<p>|<h1>|<h2>|<h3>|<h4>|<h5>|<h6>))");
}

@Nullable
@Override
public String getFragmentId() {
return fragmentId;
}

@Nullable
@Override
public String getVcfPublishUrl() {
if (!"vcf".equals(displayMode) || StringUtils.isEmpty(vcfTemplate) || StringUtils.isEmpty(fragmentId)) {
return null;
}
String variation = StringUtils.isNotEmpty(variationName) && !MASTER_VARIATION.equals(variationName)
? variationName : "main";
return String.format(VCF_PUBLISH_URL_FORMAT, vcfTemplate, fragmentId, variation);
}

@Override
@NotNull
protected ComponentData getComponentData() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,30 @@ default String getExportedType() {
default String[] getParagraphs() {
return null;
}

/**
* Returns the JCR UUID of the referenced content fragment, or {@code null}
* if the fragment does not exist or has no UUID.
*
* @return the fragment UUID, or {@code null}
* @since com.adobe.cq.wcm.core.components.models.contentfragment 1.7.0
*/
@Nullable
@JsonIgnore
default String getFragmentId() {
return null;
}

/**
* Returns the publish delivery URL for a Visual Content Fragment, or {@code null}
* when VCF display mode is not active or the required configuration is missing.
*
* @return the publish VCF URL, or {@code null}
* @since com.adobe.cq.wcm.core.components.models.contentfragment 1.7.0
*/
@Nullable
@JsonIgnore
default String getVcfPublishUrl() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
@Version("1.5.1")
@Version("1.6.0")
package com.adobe.cq.wcm.core.components.models.contentfragment;

import org.osgi.annotation.versioning.Version;
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,82 @@ void getParagraphOfSingleTextDisplayMode() {
assertArrayEquals(new String[]{MAIN_CONTENT}, contentFragment.getParagraphs());
}

@Test
void vcfPublishUrlWithTemplate() {
ContentFragment fragment = getModelInstanceUnderTest("vcf-with-template");
assertEquals(
"/adobe/experimental/previewtemplates-expires-20260301/contentFragments/hero-banner/5037ca42-4dab-4a55-aaa8-1a3db1f2e2c4/main.html",
fragment.getVcfPublishUrl());
}

@Test
void vcfPublishUrlWithVariation() {
ContentFragment fragment = getModelInstanceUnderTest("vcf-with-template-and-variation");
assertEquals(
"/adobe/experimental/previewtemplates-expires-20260301/contentFragments/hero-banner/5037ca42-4dab-4a55-aaa8-1a3db1f2e2c4/teaser.html",
fragment.getVcfPublishUrl());
}

@Test
void vcfPublishUrlWithoutTemplate() {
ContentFragment fragment = getModelInstanceUnderTest("vcf-without-template");
assertNull(fragment.getVcfPublishUrl());
}

@Test
void vcfPublishUrlNonVcfMode() {
ContentFragment fragment = getModelInstanceUnderTest(CF_TEXT_ONLY);
assertNull(fragment.getVcfPublishUrl());
}

@Test
void vcfPublishUrlMasterVariationMapsToMain() {
ContentFragment fragment = getModelInstanceUnderTest("vcf-with-master-variation");
assertEquals(
"/adobe/experimental/previewtemplates-expires-20260301/contentFragments/hero-banner/5037ca42-4dab-4a55-aaa8-1a3db1f2e2c4/main.html",
fragment.getVcfPublishUrl());
}

@Test
void vcfPublishUrlWithJcrContentUuid() {
ContentFragment fragment = getModelInstanceUnderTest("vcf-with-structured-fragment");
assertEquals("b2a7f9c1-3e5d-4f8a-9c1e-d7b3a2f5e8c4", fragment.getFragmentId());
assertEquals(
"/adobe/experimental/previewtemplates-expires-20260301/contentFragments/hero-banner/b2a7f9c1-3e5d-4f8a-9c1e-d7b3a2f5e8c4/main.html",
fragment.getVcfPublishUrl());
}

@Test
void fragmentIdFromDirectNode() {
ContentFragment fragment = getModelInstanceUnderTest(CF_TEXT_ONLY);
assertEquals("5037ca42-4dab-4a55-aaa8-1a3db1f2e2c4", fragment.getFragmentId());
}

@Test
void fragmentIdFromJcrContent() {
ContentFragment fragment = getModelInstanceUnderTest(CF_STRUCTURED);
assertEquals("b2a7f9c1-3e5d-4f8a-9c1e-d7b3a2f5e8c4", fragment.getFragmentId());
}

@Test
void fragmentIdNullWhenNoPath() {
ContentFragment fragment = getModelInstanceUnderTest(CF_STRUCTURED_NO_PATH);
assertNull(fragment.getFragmentId());
}

@Test
void vcfPublishUrlNullWhenNoFragmentId() {
ContentFragment fragment = getModelInstanceUnderTest("vcf-no-fragment-id");
assertNull(fragment.getFragmentId());
assertNull(fragment.getVcfPublishUrl());
}

@Test
void fragmentIdNullWhenInvalidPath() {
ContentFragment fragment = getModelInstanceUnderTest(CF_STRUCTURED_NON_EXISTING_PATH);
assertNull(fragment.getFragmentId());
}

@Test
void testDataLayerJson() {
Utils.enableDataLayer(context, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
"jcr:created" : "Wed Aug 30 2017 13:35:42 GMT+0200",
"jcr:content" : {
"jcr:primaryType" : "dam:AssetContent",
"jcr:uuid" : "b2a7f9c1-3e5d-4f8a-9c1e-d7b3a2f5e8c4",
"jcr:title" : "Test Content Fragment",
"jcr:description" : "This is a test content fragment.",
"jcr:lastModifiedBy": "admin",
Expand Down
43 changes: 43 additions & 0 deletions bundles/core/src/test/resources/contentfragment/test-content.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,49 @@
"sling:resourceType": "core/wcm/components/contentfragment/v1/contentfragment",
"fragmentPath" : "/content/dam/contentfragments/structured",
"elementNames" : ["second", "non-existing", "main"]
},
"vcf-with-template" : {
"jcr:primaryType" : "nt:unstructured",
"sling:resourceType": "core/wcm/components/contentfragment/v1/contentfragment",
"fragmentPath" : "/content/dam/contentfragments/text-only",
"displayMode" : "vcf",
"vcfTemplate" : "hero-banner"
},
"vcf-with-template-and-variation" : {
"jcr:primaryType" : "nt:unstructured",
"sling:resourceType": "core/wcm/components/contentfragment/v1/contentfragment",
"fragmentPath" : "/content/dam/contentfragments/text-only",
"displayMode" : "vcf",
"vcfTemplate" : "hero-banner",
"variationName" : "teaser"
},
"vcf-without-template" : {
"jcr:primaryType" : "nt:unstructured",
"sling:resourceType": "core/wcm/components/contentfragment/v1/contentfragment",
"fragmentPath" : "/content/dam/contentfragments/text-only",
"displayMode" : "vcf"
},
"vcf-with-master-variation" : {
"jcr:primaryType" : "nt:unstructured",
"sling:resourceType": "core/wcm/components/contentfragment/v1/contentfragment",
"fragmentPath" : "/content/dam/contentfragments/text-only",
"displayMode" : "vcf",
"vcfTemplate" : "hero-banner",
"variationName" : "master"
},
"vcf-with-structured-fragment" : {
"jcr:primaryType" : "nt:unstructured",
"sling:resourceType": "core/wcm/components/contentfragment/v1/contentfragment",
"fragmentPath" : "/content/dam/contentfragments/structured",
"displayMode" : "vcf",
"vcfTemplate" : "hero-banner"
},
"vcf-no-fragment-id" : {
"jcr:primaryType" : "nt:unstructured",
"sling:resourceType": "core/wcm/components/contentfragment/v1/contentfragment",
"fragmentPath" : "/content/dam/contentfragments/structured-nested-model",
"displayMode" : "vcf",
"vcfTemplate" : "hero-banner"
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions content/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ module.exports = function(config) {
'src/content/jcr_root/apps/core/wcm/components/commons/site/clientlibs/**/js/*.js',
'src/content/jcr_root/apps/core/wcm/components/image/v3/image/clientlibs/site/**/js/*.js',
'src/content/jcr_root/apps/core/wcm/components/contentfragment/v1/contentfragment/clientlibs/editor/authoring/js/editAction.js',
'src/content/jcr_root/apps/core/wcm/components/contentfragment/v1/contentfragment/clientlibs/editor/authoring/js/vcfRenderer.js',
'src/content/jcr_root/apps/core/wcm/components/contentfragment/v1/contentfragment/clientlibs/editor/dialog/js/editDialog.js',
'src/content/jcr_root/apps/core/wcm/components/commons/editor/clientlibs/htmlidvalidator/js/*.js',
'test/**/*Test.js',
'test/**/*Test.html'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/radiogroup"
deleteHint="{Boolean}false"
fieldDescription="Single Text Element mode allows selection of one multiline text element and enables paragraph control options. Multiple Elements mode allows selection of one or more elements of the Content Fragment."
fieldDescription="Single Text Element mode allows selection of one multiline text element and enables paragraph control options. Multiple Elements mode allows selection of one or more elements. Content Fragment Visualization mode allows selection of an HTML template for rendering a Visual Content Fragment."
fieldLabel="Display Mode"
name="./displayMode"
vertical="{Boolean}false">
vertical="{Boolean}true">
<granite:data
jcr:primaryType="nt:unstructured"
display-mode-radio-group="{Boolean}true"/>
Expand All @@ -59,6 +59,10 @@
checked="{Boolean}true"
text="Multiple Elements"
value="multi"/>
<vcf
jcr:primaryType="nt:unstructured"
text="Content Fragment Visualization"
value="vcf"/>
</items>
</displayMode>
<elementNames
Expand Down Expand Up @@ -117,8 +121,30 @@
<granite:data
jcr:primaryType="nt:unstructured"
element-names-container="{Boolean}true"
element-mode-field="{Boolean}true"
field-path="${requestPathInfo.resourcePath}"/>
</elementNames>
<vcfTemplateContainer
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<granite:data
jcr:primaryType="nt:unstructured"
vcf-mode-field="{Boolean}true"/>
<items jcr:primaryType="nt:unstructured">
<vcfTemplate
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
emptyText="Select a template"
fieldDescription="Select an HTML template for rendering the Visual Content Fragment."
fieldLabel="Visualization Template"
name="./vcfTemplate">
<granite:data
jcr:primaryType="nt:unstructured"
vcf-template-selector="{Boolean}true"/>
<items jcr:primaryType="nt:unstructured"/>
</vcfTemplate>
</items>
</vcfTemplateContainer>
<variationName
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@

#base=js
editAction.js
vcfRenderer.js
Loading
Loading