From 5144ae1afdff302f055e97970a5836ef5e4626c6 Mon Sep 17 00:00:00 2001 From: Levente Santha Date: Mon, 26 Jul 2021 16:58:34 +0300 Subject: [PATCH 1/3] CIF-2188 - Expose HTML id attribute in component edit dialogs * adding field for HTML id attribute in edit dialog of components * reusing the HTML id generation of core WCM components * updated unit tests --- .../datalayer/DataLayerComponent.java | 21 ++++++++++++----- .../internal/datalayer/DataLayerListItem.java | 5 ++-- .../models/v1/common/ProductListItemImpl.java | 4 ++-- .../CommerceContentFragmentImpl.java | 5 ++++ .../models/v1/product/ProductImpl.java | 13 ++++++++++- .../models/v1/page/PageMetadataImplTest.java | 2 +- .../models/v1/product/ProductImplTest.java | 22 +++++++++++++++--- .../test/resources/context/jcr-content.json | 4 ++++ .../result-datalayer-product-component.json | 2 +- .../v1/carousel/_cq_dialog/.content.xml | 7 +++++- .../categorycarousel/_cq_dialog/.content.xml | 3 ++- .../_cq_dialog/.content.xml | 5 ++++ .../_cq_dialog/.content.xml | 5 ++++ .../v1/product/_cq_dialog/.content.xml | 6 ++++- .../productcarousel/_cq_dialog/.content.xml | 1 + .../productcollection/_cq_dialog/.content.xml | 5 ++++ .../v2/productlist/_cq_dialog/.content.xml | 2 ++ .../v1/productteaser/_cq_dialog/.content.xml | 5 ++++ .../relatedproducts/_cq_dialog/.content.xml | 1 + .../v1/searchbar/_cq_dialog/.content.xml | 23 +++++++++++++++++++ .../header/v1/header/_cq_dialog/.content.xml | 23 +++++++++++++++++++ .../structure/header/v1/header/header.html | 5 ++-- 22 files changed, 148 insertions(+), 21 deletions(-) create mode 100644 ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/searchbar/v1/searchbar/_cq_dialog/.content.xml create mode 100644 ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/header/v1/header/_cq_dialog/.content.xml diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerComponent.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerComponent.java index ff587f4103..9f90c0214b 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerComponent.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerComponent.java @@ -15,23 +15,28 @@ import javax.inject.Inject; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.caconfig.ConfigurationBuilder; +import org.apache.sling.models.annotations.injectorspecific.Self; import com.adobe.cq.commerce.core.components.datalayer.CategoryData; +import com.adobe.cq.wcm.core.components.models.Component; import com.adobe.cq.wcm.core.components.models.datalayer.AssetData; import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData; +import com.adobe.cq.wcm.core.components.util.ComponentUtils; import com.fasterxml.jackson.annotation.JsonIgnore; public abstract class DataLayerComponent { - public static final String ID_SEPARATOR = "-"; + public static final String ID_SEPARATOR = ComponentUtils.ID_SEPARATOR; @Inject protected Resource resource; + @Self + private Component wcmComponent; + private String id; private Boolean dataLayerEnabled; private ComponentData componentData; @@ -67,10 +72,14 @@ protected ComponentData getComponentData() { } protected String generateId() { - String resourceType = resource.getResourceType(); - String prefix = StringUtils.substringAfterLast(resourceType, "/"); - String path = resource.getPath(); - return StringUtils.join(prefix, ID_SEPARATOR, StringUtils.substring(DigestUtils.sha256Hex(path), 0, 10)); + if (wcmComponent == null) { + String resourceType = resource.getResourceType(); + String prefix = StringUtils.substringAfterLast(resourceType, "/"); + String path = resource.getPath(); + return ComponentUtils.generateId(prefix, path); + } else { + return wcmComponent.getId(); + } } public String getId() { diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerListItem.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerListItem.java index b5b0bc63d0..9e6e96f105 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerListItem.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerListItem.java @@ -13,10 +13,11 @@ ******************************************************************************/ package com.adobe.cq.commerce.core.components.internal.datalayer; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.resource.Resource; +import com.adobe.cq.wcm.core.components.util.ComponentUtils; + public abstract class DataLayerListItem extends DataLayerComponent { public static final String ITEM_ID_PREFIX = "item"; @@ -35,6 +36,6 @@ protected String getIdentifier() { @Override protected String generateId() { String prefix = StringUtils.join(parentId, ID_SEPARATOR, ITEM_ID_PREFIX); - return StringUtils.join(prefix, ID_SEPARATOR, StringUtils.substring(DigestUtils.sha256Hex(getIdentifier()), 0, 10)); + return ComponentUtils.generateId(prefix, getIdentifier()); } } diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/common/ProductListItemImpl.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/common/ProductListItemImpl.java index 10990849cb..60822ac366 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/common/ProductListItemImpl.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/common/ProductListItemImpl.java @@ -18,7 +18,6 @@ import javax.annotation.Nullable; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; @@ -30,6 +29,7 @@ import com.adobe.cq.commerce.core.components.services.urls.UrlProvider; import com.adobe.cq.commerce.core.components.services.urls.UrlProvider.ParamsBuilder; import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData; +import com.adobe.cq.wcm.core.components.util.ComponentUtils; import com.day.cq.wcm.api.Page; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -150,7 +150,7 @@ protected ComponentData getComponentData() { @Override protected String generateId() { String prefix = StringUtils.join(parentId, ID_SEPARATOR, ITEM_ID_PREFIX); - return StringUtils.join(prefix, ID_SEPARATOR, StringUtils.substring(DigestUtils.sha256Hex(getSKU()), 0, 10)); + return ComponentUtils.generateId(prefix, getSKU()); } @Override diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/contentfragment/CommerceContentFragmentImpl.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/contentfragment/CommerceContentFragmentImpl.java index ca2ec10fe3..dcaaa1d506 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/contentfragment/CommerceContentFragmentImpl.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/contentfragment/CommerceContentFragmentImpl.java @@ -311,6 +311,11 @@ public String getEditorJSON() { return contentFragment.getEditorJSON(); } + @Override + public String getId() { + return contentFragment.getId(); + } + static class EmptyContentFragment implements ContentFragment { /** * The empty return value means that the model does not contain a valid content fragment. diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java index 036809cb78..26c80ea5d3 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java @@ -72,8 +72,10 @@ import com.adobe.cq.commerce.magento.graphql.SimpleProduct; import com.adobe.cq.commerce.magento.graphql.VirtualProduct; import com.adobe.cq.sightly.SightlyWCMMode; +import com.adobe.cq.wcm.core.components.models.Component; import com.adobe.cq.wcm.core.components.models.datalayer.AssetData; import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData; +import com.adobe.cq.wcm.core.components.util.ComponentUtils; import com.adobe.cq.wcm.launches.utils.LaunchUtils; import com.day.cq.commons.Externalizer; import com.day.cq.wcm.api.Page; @@ -428,7 +430,16 @@ public ComponentData getComponentData() { @Override protected String generateId() { - return StringUtils.join("product", ID_SEPARATOR, StringUtils.substring(DigestUtils.sha256Hex(getSku()), 0, 10)); + String id = super.generateId(); + if (StringUtils.isNotBlank(properties.get(Component.PN_ID, String.class))) { + // if available use the id provided by the user + return id; + } else { + // otherwise include the product SKU in the id + String prefix = StringUtils.substringBefore(id, ID_SEPARATOR); + String suffix = StringUtils.substringAfterLast(id, ID_SEPARATOR) + getSku(); + return ComponentUtils.generateId(prefix, suffix); + } } @Override diff --git a/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/page/PageMetadataImplTest.java b/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/page/PageMetadataImplTest.java index d3b7118398..9f53492344 100644 --- a/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/page/PageMetadataImplTest.java +++ b/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/page/PageMetadataImplTest.java @@ -163,7 +163,7 @@ public void testPageMetadataModelOnProductPage() throws Exception { // Asserts that the right product resource is used when PageMetadataImpl adapts the request to the Product component ComponentData data = productModel.getData(); assertEquals("venia/components/commerce/product", data.getType()); - assertEquals("product-8309e8957e", data.getId()); + assertEquals("product-3944cc709b", data.getId()); } @Test diff --git a/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImplTest.java b/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImplTest.java index 9221309b0b..d7653e7894 100644 --- a/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImplTest.java +++ b/bundles/core/src/test/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImplTest.java @@ -75,6 +75,7 @@ import io.wcm.testing.mock.aem.junit.AemContextCallback; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.mockito.Matchers.any; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; @@ -118,6 +119,7 @@ private static AemContext createContext(String contentPath) { private static final String PAGE = "/content/pageA"; private static final String PRODUCT = "/content/pageA/jcr:content/root/responsivegrid/product"; + private static final String PRODUCT_WITH_ID = "/content/pageA/jcr:content/root/responsivegrid/productwithid"; private Resource productResource; private Resource pageResource; @@ -325,7 +327,7 @@ public void testSafeDescriptionWithNull() { SimpleProduct product = mock(SimpleProduct.class, RETURNS_DEEP_STUBS); when(product.getDescription()).thenReturn(null); Whitebox.setInternalState(productModel.getProductRetriever(), "product", Optional.of(product)); - Assert.assertNull(productModel.getDescription()); + assertNull(productModel.getDescription()); } @Test @@ -338,7 +340,7 @@ public void testSafeDescriptionHtmlNull() { Whitebox.setInternalState(productModel.getProductRetriever(), "product", Optional.of(product)); - Assert.assertNull(productModel.getDescription()); + assertNull(productModel.getDescription()); } @Test @@ -486,7 +488,7 @@ public void testProductNoGraphqlClient() { Assert.assertFalse("Product is not configurable", productModel.isConfigurable()); Assert.assertFalse("Product is not a grouped product", productModel.isGroupedProduct()); Assert.assertFalse("Product is not virtual", productModel.isVirtualProduct()); - Assert.assertNull("The product retriever is not created", productModel.getProductRetriever()); + assertNull("The product retriever is not created", productModel.getProductRetriever()); } @Test @@ -552,4 +554,18 @@ public void testStorefrontContextRender() throws IOException { String jsonResult = productModel.getStorefrontContext().getJson(); assertEquals(mapper.readTree(expected), mapper.readTree(jsonResult)); } + + @Test + public void testManualHtmlId() throws IOException { + context.currentResource(PRODUCT_WITH_ID); + context.request().setServletPath(PRODUCT_WITH_ID + ".beaumont-summit-kit.html"); + productResource = context.resourceResolver().getResource(PRODUCT_WITH_ID); + SlingBindings slingBindings = (SlingBindings) context.request().getAttribute(SlingBindings.class.getName()); + slingBindings.setResource(productResource); + slingBindings.put(WCMBindingsConstants.NAME_PROPERTIES, productResource.getValueMap()); + + productModel = context.request().adaptTo(ProductImpl.class); + + assertEquals("custom-id", productModel.getId()); + } } diff --git a/bundles/core/src/test/resources/context/jcr-content.json b/bundles/core/src/test/resources/context/jcr-content.json index 85bc21717b..eb9165ea5e 100644 --- a/bundles/core/src/test/resources/context/jcr-content.json +++ b/bundles/core/src/test/resources/context/jcr-content.json @@ -55,6 +55,10 @@ "product": { "sling:resourceType": "venia/components/commerce/product" }, + "productwithid": { + "sling:resourceType": "venia/components/commerce/product", + "id": "custom-id" + }, "productlist": { "loadClientPrice": true, "showImage": true, diff --git a/bundles/core/src/test/resources/results/result-datalayer-product-component.json b/bundles/core/src/test/resources/results/result-datalayer-product-component.json index afa145e4b0..a741cb18bd 100644 --- a/bundles/core/src/test/resources/results/result-datalayer-product-component.json +++ b/bundles/core/src/test/resources/results/result-datalayer-product-component.json @@ -1,5 +1,5 @@ { - "product-8309e8957e": { + "product-a8f26bcdca": { "xdm:SKU": "MJ01", "xdm:listPrice": 58.0, "xdm:categories": [ diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/carousel/v1/carousel/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/carousel/v1/carousel/_cq_dialog/.content.xml index 626c92adf9..1a313b358a 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/carousel/v1/carousel/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/carousel/v1/carousel/_cq_dialog/.content.xml @@ -17,7 +17,7 @@ <titleType granite:class="core-title-sizes" jcr:primaryType="nt:unstructured" @@ -28,6 +28,11 @@ jcr:primaryType="nt:unstructured" sling:resourceType="core/wcm/components/commons/datasources/allowedheadingelements/v1"/> </titleType> + <id jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/form/textfield" + fieldDescription="HTML ID attribute to apply to the component." + fieldLabel="ID" + name="./id"/> </items> </column> </items> diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/categorycarousel/v1/categorycarousel/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/categorycarousel/v1/categorycarousel/_cq_dialog/.content.xml index 4ebc7c7158..1e0dc0e83f 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/categorycarousel/v1/categorycarousel/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/categorycarousel/v1/categorycarousel/_cq_dialog/.content.xml @@ -16,7 +16,8 @@ value="Shop by category" /> <content granite:class="cmp-cif-categorycarousel__editor" jcr:primaryType="nt:unstructured" - sling:resourceType="granite/ui/components/coral/foundation/form/multifield" + sling:resourceType="granite/ui/components/coral/foundation/form/multifield" + sling:orderBefore="id" composite="{Boolean}true" fieldLabel="Categories"> <field granite:class="cmp-cif-categorycarousel__editor-item-multifield-composite-item coral-Well" diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/experiencefragment/v1/experiencefragment/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/experiencefragment/v1/experiencefragment/_cq_dialog/.content.xml index 77d6f752e5..4f61dc5f7d 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/experiencefragment/v1/experiencefragment/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/experiencefragment/v1/experiencefragment/_cq_dialog/.content.xml @@ -18,6 +18,11 @@ fieldDescription="The name of this experience fragment location." fieldLabel="Experience fragment location name." name="./fragmentLocation"/> + <id jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/form/textfield" + fieldDescription="HTML ID attribute to apply to the component." + fieldLabel="ID" + name="./id"/> </items> </column> </items> diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/featuredcategorylist/v1/featuredcategorylist/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/featuredcategorylist/v1/featuredcategorylist/_cq_dialog/.content.xml index ee0e8e6bdd..b29e1bc16e 100755 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/featuredcategorylist/v1/featuredcategorylist/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/featuredcategorylist/v1/featuredcategorylist/_cq_dialog/.content.xml @@ -56,6 +56,11 @@ </items> </field> </content> + <id jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/form/textfield" + fieldDescription="HTML ID attribute to apply to the component." + fieldLabel="ID" + name="./id"/> </items> </column> </items> diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/product/v1/product/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/product/v1/product/_cq_dialog/.content.xml index caddc378ef..872991b06a 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/product/v1/product/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/product/v1/product/_cq_dialog/.content.xml @@ -30,7 +30,11 @@ text="Without a manual product selection, this component will display a product based on an URL selector."/> </items> </well> - + <id jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/form/textfield" + fieldDescription="HTML ID attribute to apply to the component." + fieldLabel="ID" + name="./id"/> </items> </column> </items> diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productcarousel/v1/productcarousel/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productcarousel/v1/productcarousel/_cq_dialog/.content.xml index b257da4ed1..9a1edd2f23 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productcarousel/v1/productcarousel/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productcarousel/v1/productcarousel/_cq_dialog/.content.xml @@ -13,6 +13,7 @@ <items jcr:primaryType="nt:unstructured"> <content jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/multifield" + sling:orderBefore="id" fieldLabel="Carousel content" typeHint="[product@String[]]"> <field jcr:primaryType="nt:unstructured" diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productcollection/v2/productcollection/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productcollection/v2/productcollection/_cq_dialog/.content.xml index 4c26eb8667..9206905447 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productcollection/v2/productcollection/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productcollection/v2/productcollection/_cq_dialog/.content.xml @@ -20,6 +20,11 @@ fieldDescription="Number of products to show on single page" fieldLabel="Page Size" name="./pageSize"/> + <id jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/form/textfield" + fieldDescription="HTML ID attribute to apply to the component." + fieldLabel="ID" + name="./id"/> </items> </column> </items> diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productlist/v2/productlist/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productlist/v2/productlist/_cq_dialog/.content.xml index 1ee0f34c21..31dacb373d 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productlist/v2/productlist/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productlist/v2/productlist/_cq_dialog/.content.xml @@ -17,6 +17,7 @@ <showTitle jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/checkbox" + sling:orderBefore="id" fieldDescription="Show category title of product list" name="./showTitle" text="Show title" @@ -26,6 +27,7 @@ <showImage jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/checkbox" + sling:orderBefore="id" fieldDescription="Show category image of product list" name="./showImage" text="Show image" diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productteaser/v1/productteaser/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productteaser/v1/productteaser/_cq_dialog/.content.xml index 00ac71d4cf..0754dadc06 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productteaser/v1/productteaser/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/productteaser/v1/productteaser/_cq_dialog/.content.xml @@ -65,6 +65,11 @@ fieldDescription="The text displayed by the call-to-action button" fieldLabel="Call to action text" name="./ctaText"/> + <id jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/form/textfield" + fieldDescription="HTML ID attribute to apply to the component." + fieldLabel="ID" + name="./id"/> </items> </column> </items> diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/relatedproducts/v1/relatedproducts/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/relatedproducts/v1/relatedproducts/_cq_dialog/.content.xml index 0109d090bc..37288a8fa6 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/relatedproducts/v1/relatedproducts/_cq_dialog/.content.xml +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/relatedproducts/v1/relatedproducts/_cq_dialog/.content.xml @@ -21,6 +21,7 @@ selectionId="sku" /> <relationType jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/select" + sling:orderBefore="id" fieldLabel="Target products to display." name="./relationType"> <datasource jcr:primaryType="nt:unstructured" diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/searchbar/v1/searchbar/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/searchbar/v1/searchbar/_cq_dialog/.content.xml new file mode 100644 index 0000000000..71e062cca2 --- /dev/null +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/commerce/searchbar/v1/searchbar/_cq_dialog/.content.xml @@ -0,0 +1,23 @@ +<?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="Search Bar" + sling:resourceType="cq/gui/components/authoring/dialog" + trackingFeature="cif-core-components:searchbar:v1"> + <content + jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/container"> + <items jcr:primaryType="nt:unstructured"> + <column jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/container"> + <items jcr:primaryType="nt:unstructured"> + <id jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/form/textfield" + fieldDescription="HTML ID attribute to apply to the component." + fieldLabel="ID" + name="./id"/> + </items> + </column> + </items> + </content> +</jcr:root> \ No newline at end of file diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/header/v1/header/_cq_dialog/.content.xml b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/header/v1/header/_cq_dialog/.content.xml new file mode 100644 index 0000000000..8b03539ad1 --- /dev/null +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/header/v1/header/_cq_dialog/.content.xml @@ -0,0 +1,23 @@ +<?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="Page Header" + sling:resourceType="cq/gui/components/authoring/dialog" + trackingFeature="cif-core-components:header:v1"> + <content + jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/container"> + <items jcr:primaryType="nt:unstructured"> + <column jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/container"> + <items jcr:primaryType="nt:unstructured"> + <id jcr:primaryType="nt:unstructured" + sling:resourceType="granite/ui/components/coral/foundation/form/textfield" + fieldDescription="HTML ID attribute to apply to the component." + fieldLabel="ID" + name="./id"/> + </items> + </column> + </items> + </content> +</jcr:root> \ No newline at end of file diff --git a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/header/v1/header/header.html b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/header/v1/header/header.html index 9c3a2e96e5..9916c36b95 100644 --- a/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/header/v1/header/header.html +++ b/ui.apps/src/main/content/jcr_root/apps/core/cif/components/structure/header/v1/header/header.html @@ -11,9 +11,10 @@ ~ governing permissions and limitations under the License. ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/--> -<sly data-sly-use.header="${'com.adobe.cq.commerce.core.components.models.header.Header' @ minicartNodeName = 'minicart'}" /> +<sly data-sly-use.header="${'com.adobe.cq.commerce.core.components.models.header.Header' @ minicartNodeName = 'minicart'}" + data-sly-use.component="com.adobe.cq.wcm.core.components.models.Component"/> -<header class="header__root header__closed"> +<header id="${component.id}" class="header__root header__closed"> <div class="header__toolbar"> <a href="${header.navigationRootPageUrl}"> <img class="header__logo" src="${resource.path}/logo.svg" height="24" alt="${header.navigationRootPageTitle}" title="${header.navigationRootPageTitle}" /> From 2e93482716735d3e790988d2b307fc8bf777abbc Mon Sep 17 00:00:00 2001 From: Levente Santha <levente@adobe.com> Date: Mon, 26 Jul 2021 17:33:31 +0300 Subject: [PATCH 2/3] CIF-2188 - Expose HTML id attribute in component edit dialogs * fixing IT failure --- .../test/resources/datalayer/chaz-kangeroo-hoodie-product.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/http/src/test/resources/datalayer/chaz-kangeroo-hoodie-product.json b/it/http/src/test/resources/datalayer/chaz-kangeroo-hoodie-product.json index 34f57570b3..b92fc6d832 100644 --- a/it/http/src/test/resources/datalayer/chaz-kangeroo-hoodie-product.json +++ b/it/http/src/test/resources/datalayer/chaz-kangeroo-hoodie-product.json @@ -1,5 +1,5 @@ { - "product-500741b9f1": { + "product-4489fda6a6": { "xdm:SKU": "MH01", "xdm:listPrice": 52.0, "xdm:assets": [ From 2cad8b9c4e6226fee8b7b71e2632097aba8962ea Mon Sep 17 00:00:00 2001 From: Levente Santha <levente@adobe.com> Date: Wed, 28 Jul 2021 16:41:21 +0300 Subject: [PATCH 3/3] CIF-2188 - Expose HTML id attribute in component edit dialogs * cleaned up ID_SEPARATOR --- .../core/components/internal/datalayer/AssetDataImpl.java | 7 ++----- .../components/internal/datalayer/CategoryDataImpl.java | 6 ++---- .../components/internal/datalayer/DataLayerComponent.java | 1 - .../components/internal/datalayer/DataLayerListItem.java | 2 ++ .../internal/models/v1/common/ProductListItemImpl.java | 2 ++ .../components/internal/models/v1/product/ProductImpl.java | 2 ++ .../converters/ProductToProductListItemConverter.java | 6 ++---- 7 files changed, 12 insertions(+), 14 deletions(-) diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/AssetDataImpl.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/AssetDataImpl.java index ba1eff4818..484cd60869 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/AssetDataImpl.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/AssetDataImpl.java @@ -18,11 +18,9 @@ import java.util.Date; import java.util.Map; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang3.StringUtils; - import com.adobe.cq.commerce.core.components.models.product.Asset; import com.adobe.cq.wcm.core.components.models.datalayer.AssetData; +import com.adobe.cq.wcm.core.components.util.ComponentUtils; public class AssetDataImpl implements AssetData { private final Asset asset; @@ -33,8 +31,7 @@ public AssetDataImpl(Asset asset) { @Override public String getId() { - return StringUtils.join(asset.getType(), DataLayerComponent.ID_SEPARATOR, StringUtils.substring(DigestUtils.sha256Hex(asset - .getPath()), 0, 10)); + return ComponentUtils.generateId(asset.getType(), asset.getPath()); } @Override diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/CategoryDataImpl.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/CategoryDataImpl.java index beff18984f..909951f86c 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/CategoryDataImpl.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/CategoryDataImpl.java @@ -15,12 +15,10 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ package com.adobe.cq.commerce.core.components.internal.datalayer; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang3.StringUtils; - import com.adobe.cq.commerce.core.components.datalayer.CategoryData; import com.adobe.cq.commerce.core.components.internal.models.v1.product.AssetImpl; import com.adobe.cq.wcm.core.components.models.datalayer.AssetData; +import com.adobe.cq.wcm.core.components.util.ComponentUtils; public class CategoryDataImpl implements CategoryData { private String id; @@ -35,7 +33,7 @@ public CategoryDataImpl(String id, String name, String image) { @Override public String getId() { - return StringUtils.join("category", DataLayerComponent.ID_SEPARATOR, StringUtils.substring(DigestUtils.sha256Hex(id), 0, 10)); + return ComponentUtils.generateId("category", id); } @Override diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerComponent.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerComponent.java index 11b3c90da8..399ef458df 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerComponent.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerComponent.java @@ -31,7 +31,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; public abstract class DataLayerComponent { - public static final String ID_SEPARATOR = ComponentUtils.ID_SEPARATOR; @Inject protected Resource resource; diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerListItem.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerListItem.java index 1a490fe2d0..ca7fe6c5c7 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerListItem.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/datalayer/DataLayerListItem.java @@ -20,6 +20,8 @@ import com.adobe.cq.wcm.core.components.util.ComponentUtils; +import static com.adobe.cq.wcm.core.components.util.ComponentUtils.ID_SEPARATOR; + public abstract class DataLayerListItem extends DataLayerComponent { public static final String ITEM_ID_PREFIX = "item"; diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/common/ProductListItemImpl.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/common/ProductListItemImpl.java index 9a4753fc4a..f11d535183 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/common/ProductListItemImpl.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/common/ProductListItemImpl.java @@ -34,6 +34,8 @@ import com.day.cq.wcm.api.Page; import com.fasterxml.jackson.annotation.JsonIgnore; +import static com.adobe.cq.wcm.core.components.util.ComponentUtils.ID_SEPARATOR; + public class ProductListItemImpl extends DataLayerListItem implements ProductListItem { private String sku; diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java index 0d3512b266..070364937d 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/components/internal/models/v1/product/ProductImpl.java @@ -84,6 +84,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import static com.adobe.cq.wcm.core.components.util.ComponentUtils.ID_SEPARATOR; + @Model( adaptables = SlingHttpServletRequest.class, adapters = Product.class, diff --git a/bundles/core/src/main/java/com/adobe/cq/commerce/core/search/internal/converters/ProductToProductListItemConverter.java b/bundles/core/src/main/java/com/adobe/cq/commerce/core/search/internal/converters/ProductToProductListItemConverter.java index 0d6e3a82cb..280e8ef09c 100644 --- a/bundles/core/src/main/java/com/adobe/cq/commerce/core/search/internal/converters/ProductToProductListItemConverter.java +++ b/bundles/core/src/main/java/com/adobe/cq/commerce/core/search/internal/converters/ProductToProductListItemConverter.java @@ -18,14 +18,12 @@ import java.util.Locale; import java.util.function.Function; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.adobe.cq.commerce.core.components.internal.datalayer.DataLayerComponent; import com.adobe.cq.commerce.core.components.internal.models.v1.common.PriceImpl; import com.adobe.cq.commerce.core.components.internal.models.v1.common.ProductListItemImpl; import com.adobe.cq.commerce.core.components.models.common.Price; @@ -34,6 +32,7 @@ import com.adobe.cq.commerce.magento.graphql.GroupedProduct; import com.adobe.cq.commerce.magento.graphql.ProductImage; import com.adobe.cq.commerce.magento.graphql.ProductInterface; +import com.adobe.cq.wcm.core.components.util.ComponentUtils; import com.day.cq.wcm.api.Page; /** @@ -69,8 +68,7 @@ public ProductListItem apply(final ProductInterface product) { String resourceType = parentResource.getResourceType(); String prefix = StringUtils.substringAfterLast(resourceType, "/"); String path = parentResource.getPath(); - String parentId = StringUtils.join(prefix, DataLayerComponent.ID_SEPARATOR, StringUtils.substring(DigestUtils.sha256Hex(path), - 0, 10)); + String parentId = ComponentUtils.generateId(prefix, path); ProductListItem productListItem = new ProductListItemImpl(product.getSku(), product.getUrlKey(),