Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

Modify ProductPicker

DhirajAg
Level 4
Level 4

Hi,

I was going though the productpicker /libs/commerce/gui/components/common/productpicker and used it in one of my dialogues. By default it returns the base products and not the variants for each base product. Can i customize this to return variants as well ? If yes, how can I do it ?

9 Replies
smacdonald2008
Level 10
Level 10

I am checking with the product team on this question. 

DhirajAg
Level 4
Level 4

Thanks Scott

Can i get the source code of the following file ? com.adobe.cq.commerce.pim.impl.contentfinder.ProductViewHandler 

It is placed within resources/install/0/cq-commerce-pim-5.11.30.jar but I am not sure where to look for this jar 

smacdonald2008
Level 10
Level 10

If you know the bundle number -- you can find the bundles here: 

C:\AEM61_3\crx-quickstart\launchpad\felix

smacdonald2008
Level 10
Level 10

We also have plans on providing more eCommerce content like this. It looks like we will be going an Ask the AEM Community Experts session on E Commerce in AUG too. 

DhirajAg
Level 4
Level 4

Thanks for your reply Scott ! I am looking forward to that session in Aug. 

I did check crx-quickstart\launchpad\felix and found 475 bundles and realized it wouldn't be possible to find that particular jar.

I got the class file from https://repo.adobe.com/nexus/content/groups/public/com/adobe/cq/commerce/cq-commerce-pim/5.9.26/cq-commerce-pim-5.9.26.jar , decompiled it and found cq:commerceType value set as product which can be changed to variant in the ProductFilter

private static class ProductFilter implements GQL.Filter { ResourceResolver resolver; ProductFilter(ResourceResolver resolver) { this.resolver = resolver; } public boolean include(Row row) throws RepositoryException { String path = row.getPath(); Resource resource = this.resolver.getResource(path); if (resource == null) { return false; } ValueMap valueMap = (ValueMap)resource.adaptTo(ValueMap.class); return (valueMap.containsKey("cq:commerceType")) && (valueMap.get("cq:commerceType").equals("product")); } }

Would this be the correct way to achieve my requirement? Thanks again for your help on this.

smacdonald2008
Level 10
Level 10

Looks like you are on the right path - i would recommend that you test this on a DEV Sandbox CQ instance - so anything you do will not break anything important. 

DhirajAg
Level 4
Level 4

Hey Scott,

I am getting the following error when I try to build my code

[ERROR] Exception Details:
[ERROR] Location:
[ERROR] com/day/cq/commons/servlets/AbstractPredicateServlet.<init>()V @1: return
[ERROR] Reason:
[ERROR] Error exists in the bytecode
[ERROR] Bytecode:
[ERROR] 0000000: 2ab1

[ERROR] -----------------------------------------------------
[ERROR] realm =    plugin>org.apache.felix:maven-scr-plugin:1.20.0
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/C:/Users/dhiagarwal/.m2/repository/org/apache/felix/maven-scr-plugin/1.20.0/maven-scr-plugin-1.20.0.jar
[ERROR] urls[1] = file:/C:/Users/dhiagarwal/.m2/repository/org/slf4j/slf4j-simple/1.5.11/slf4j-simple-1.5.11.jar
[ERROR] urls[2] = file:/C:/Users/dhiagarwal/.m2/repository/org/apache/maven/maven-archiver/2.2/maven-archiver-2.2.jar
[ERROR] urls[3] = file:/C:/Users/dhiagarwal/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar
[ERROR] urls[4] = file:/C:/Users/dhiagarwal/.m2/repository/org/codehaus/plexus/plexus-archiver/1.0-alpha-7/plexus-archiver-1.0-alpha-7.jar
[ERROR] urls[5] = file:/C:/Users/dhiagarwal/.m2/repository/org/apache/felix/org.apache.felix.scr.generator/1.12.0/org.apache.felix.scr.generator-1.12.0.jar
[ERROR] urls[6] = file:/C:/Users/dhiagarwal/.m2/repository/org/ow2/asm/asm-all/5.0.2/asm-all-5.0.2.jar
[ERROR] urls[7] = file:/C:/Users/dhiagarwal/.m2/repository/org/osgi/org.osgi.core/4.2.0/org.osgi.core-4.2.0.jar
[ERROR] urls[8] = file:/C:/Users/dhiagarwal/.m2/repository/org/osgi/org.osgi.compendium/4.2.0/org.osgi.compendium-4.2.0.jar
[ERROR] urls[9] = file:/C:/Users/dhiagarwal/.m2/repository/org/sonatype/plexus/plexus-build-api/0.0.7/plexus-build-api-0.0.7.jar
[ERROR] urls[10] = file:/C:/Users/dhiagarwal/.m2/repository/org/codehaus/plexus/plexus-utils/1.5.8/plexus-utils-1.5.8.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import  from realm ClassRealm[project>com.mec:meCommerce.core:0.0.1-SNAPSHOT, parent: ClassRealm[maven.api, parent: null]]]

I have tried jdk 1.7 as well as 1.8

Would I required an unobfuscated uber jar to have this work?

Added the code below.

package com.mec.core.servlets; import com.adobe.cq.commerce.api.Product; import com.adobe.granite.xss.XSSAPI; import com.day.cq.tagging.Tag; import com.day.cq.tagging.TagManager; import com.day.cq.wcm.core.contentfinder.Hit; import com.day.cq.wcm.core.contentfinder.ViewHandler; import com.day.cq.wcm.core.contentfinder.ViewQuery; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; import javax.jcr.query.Row; import javax.jcr.query.RowIterator; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.apache.jackrabbit.commons.query.GQL; import org.apache.jackrabbit.commons.query.GQL.Filter; import org.apache.jackrabbit.commons.query.GQL.ParserCallback; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.request.RequestPathInfo; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ValueMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component @Service @Properties({ @Property(name = "service.description", value = { "Handles the display of the variants tab in the content finder" }), @Property(name = "sling.servlet.paths", value = { "/bin/wcm/contentfinder/variant/view" }) }) public class VariantViewHandler extends ViewHandler { private static Logger log = LoggerFactory.getLogger(VariantViewHandler.class); @Reference private XSSAPI xssAPI; private static final String DEFAULT_START_PATH = "/etc/commerce/products"; protected ViewQuery createQuery(SlingHttpServletRequest request, Session session, String queryString) throws RepositoryException { ParserCallback cb = new ParserCallback((TagManager) request.getResourceResolver().adaptTo(TagManager.class)); GQL.parse(queryString, session, cb); StringBuilder gql = cb.getQuery(); String path = cb.getStartPath(); if (path == null) { RequestPathInfo pathInfo = request.getRequestPathInfo(); String startPath = pathInfo.getSuffix() != null ? pathInfo.getSuffix() : "/etc/commerce/products"; path = "path:\"" + startPath + "\""; } if (gql.length() > 0) { gql.append(" "); } gql.append(path).append(" "); String limit = cb.getLimit(); if (limit == null) { limit = request.getParameter("limit"); if ((limit != null) && (!limit.equals(""))) { limit = "limit:" + limit; } else { limit = "limit:20"; } } gql.append(limit).append(" "); String order = cb.getOrder(); if (order == null) { order = "order:-jcr:lastModified"; } else if ((order.substring("order:-".length()).startsWith("jcr:content/")) || (order.substring("order:-\"".length()).startsWith("jcr:content/"))) { order = order.replaceFirst("jcr:content/", ""); } gql.append(order).append(" "); return new GQLViewQuery(request, gql.toString(), session, this.xssAPI.getRequestSpecificAPI(request)); } private static Hit createHit(Product product, String excerpt, XSSAPI xssAPI) throws RepositoryException { Hit hit = new Hit(); String path = product.getPath(); String name = path.substring(path.lastIndexOf("/") + 1); String title = product.getTitle(); if ((title == null) || (title.length() == 0)) { title = name; } hit.set("name", xssAPI.encodeForHTML(name)); hit.set("path", path); hit.set("thumbnail", xssAPI.getValidHref(product.getThumbnailUrl(48))); hit.set("title", xssAPI.encodeForHTML(title)); hit.set("sku", xssAPI.encodeForHTML(product.getSKU())); hit.set("excerpt", xssAPI.filterHTML(excerpt)); return hit; } protected void bindXssAPI(XSSAPI paramXSSAPI) { this.xssAPI = paramXSSAPI; } protected void unbindXssAPI(XSSAPI paramXSSAPI) { if (this.xssAPI == paramXSSAPI) { this.xssAPI = null; } } private static class ProductFilter implements GQL.Filter { ResourceResolver resolver; ProductFilter(ResourceResolver resolver) { this.resolver = resolver; } public boolean include(Row row) throws RepositoryException { String path = row.getPath(); Resource resource = this.resolver.getResource(path); if (resource == null) { return false; } ValueMap valueMap = (ValueMap) resource.adaptTo(ValueMap.class); return (valueMap.containsKey("cq:commerceType")) && (valueMap.get("cq:commerceType").equals("variant")); } } private static class ParserCallback implements GQL.ParserCallback { private StringBuilder query = new StringBuilder(); private String startPath = null; private String type = null; private String limit = null; private String order = null; private TagManager tagMgr; public ParserCallback(TagManager tagMgr) { this.tagMgr = tagMgr; } public void term(String property, String value, boolean optional) throws RepositoryException { if (property.equals("path")) { this.startPath = ("path:\"" + value + "\""); return; } if (property.equals("type")) { this.type = ("type:\"" + value + "\""); return; } if (property.equals("limit")) { this.limit = ("limit:\"" + value + "\""); return; } if (property.equals("order")) { this.order = ("order:\"" + value + "\""); return; } if (optional) { this.query.append("OR "); } if (property.equals("tag")) { if (this.tagMgr == null) { this.query.append("\"cq:tags\":\""); this.query.append(value).append("\" "); } else { Tag tag = this.tagMgr.resolve(value); if (tag != null) { this.query.append(tag.getGQLSearchExpression("cq:tags")); this.query.append(" "); } else { this.query.append("\"cq:tags\":\"______invalid______\" "); } } } else if (property.length() == 0) { this.query.append("\"").append(value).append("\""); } else { this.query.append("\"").append(property).append("\":"); this.query.append("\"").append(value).append("\" "); } } public StringBuilder getQuery() { return this.query; } public String getStartPath() { return this.startPath; } public String getType() { return this.type; } public String getLimit() { return this.limit; } public String getOrder() { return this.order; } } private static class GQLViewQuery implements ViewQuery { private final SlingHttpServletRequest request; private final String queryStr; private final Session session; private final XSSAPI xssAPI; public GQLViewQuery(SlingHttpServletRequest request, String queryStr, Session session, XSSAPI xssAPI) { this.request = request; this.queryStr = queryStr; this.session = session; this.xssAPI = xssAPI; } public Collection<Hit> execute() { List<Hit> hits = new ArrayList(); ResourceResolver resolver = this.request.getResourceResolver(); VariantViewHandler.log.debug("executing GQL query: " + this.queryStr); RowIterator rows = GQL.execute(this.queryStr, this.session, null, new VariantViewHandler.ProductFilter(resolver)); while (rows.hasNext()) { Row row = rows.nextRow(); try { Product product = (Product) resolver.getResource(row.getPath()).adaptTo(Product.class); String excerpt = ""; try { excerpt = row.getValue("rep:excerpt()").getString(); } catch (Exception e) { } hits.add(VariantViewHandler.createHit(product, excerpt, this.xssAPI)); } catch (RepositoryException re) { VariantViewHandler.log.error("A repository error occurred", re); } } return hits; } } }
kautuk_sahni
Community Manager
Community Manager

Hi 

Reply for the internal team :-

    Returning other types than ‘product' is not supported by the product picker ootb.
    To achieve your goal you could maybe:
    •    Override /libs/commerce/gui/components/common/productpicker/clientlibs/productpicker.js in /apps and introduce a custom type (type=productorvariant)
    •    Create a custom view handler (e.g. CustomProductViewHandler), similar to com.adobe.cq.commerce.pim.impl.contentfinder.ProductViewHandler, that would return product or variant, registered to the path     /bin/wcm/contentfinder/productorvariant/view

I hope this would help you.

Thanks and Regards

Kautuk Sahni

DhirajAg
Level 4
Level 4

Hi Kautuk,

 

Thanks for your reply.I have done the exact same thing as mentioned in my previous reply. however when i try to build my bundle which has the custom ViewHandler I get below error. Can you help me out here ?

[ERROR] Exception Details:
[ERROR] Location:
[ERROR] com/day/cq/commons/servlets/AbstractPredicateServlet.<init>()V @1: return
[ERROR] Reason:
[ERROR] Error exists in the bytecode
[ERROR] Bytecode:
[ERROR] 0000000: 2ab1

[ERROR] -----------------------------------------------------
[ERROR] realm =    plugin>org.apache.felix:maven-scr-plugin:1.20.0
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/C:/Users/dhiagarwal/.m2/repository/org/apache/felix/maven-scr-plugin/1.20.0/maven-scr-plugin-1.20.0.jar
[ERROR] urls[1] = file:/C:/Users/dhiagarwal/.m2/repository/org/slf4j/slf4j-simple/1.5.11/slf4j-simple-1.5.11.jar
[ERROR] urls[2] = file:/C:/Users/dhiagarwal/.m2/repository/org/apache/maven/maven-archiver/2.2/maven-archiver-2.2.jar
[ERROR] urls[3] = file:/C:/Users/dhiagarwal/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar
[ERROR] urls[4] = file:/C:/Users/dhiagarwal/.m2/repository/org/codehaus/plexus/plexus-archiver/1.0-alpha-7/plexus-archiver-1.0-alpha-7.jar
[ERROR] urls[5] = file:/C:/Users/dhiagarwal/.m2/repository/org/apache/felix/org.apache.felix.scr.generator/1.12.0/org.apache.felix.scr.generator-1.12.0.jar
[ERROR] urls[6] = file:/C:/Users/dhiagarwal/.m2/repository/org/ow2/asm/asm-all/5.0.2/asm-all-5.0.2.jar
[ERROR] urls[7] = file:/C:/Users/dhiagarwal/.m2/repository/org/osgi/org.osgi.core/4.2.0/org.osgi.core-4.2.0.jar
[ERROR] urls[8] = file:/C:/Users/dhiagarwal/.m2/repository/org/osgi/org.osgi.compendium/4.2.0/org.osgi.compendium-4.2.0.jar
[ERROR] urls[9] = file:/C:/Users/dhiagarwal/.m2/repository/org/sonatype/plexus/plexus-build-api/0.0.7/plexus-build-api-0.0.7.jar
[ERROR] urls[10] = file:/C:/Users/dhiagarwal/.m2/repository/org/codehaus/plexus/plexus-utils/1.5.8/plexus-utils-1.5.8.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import  from realm ClassRealm[project>com.mec:meCommerce.core:0.0.1-SNAPSHOT, parent: ClassRealm[maven.api, parent: null]]]

I have tried jdk 1.7 as well as 1.8

Would I required an unobfuscated uber jar to have this work?