Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.

Issues with custom columns in listview for AEM 6.2

Avatar

Level 5

l followed the instructions in the documentation on how to add new columns to the list view for consoles in AEM, but have run up against a few issues. 

First of all, I'm not sure if it's the installation or what, but the repo linked from that section doesn't seem to be compatible with AEM 6.2--though I could select the "Created" column in the config modal, the column never actually showed.

I ended up having a little more success when I added stuff manually--the columns appear when I select them, but aren't filling in the data for the rows. I think this has to do with the fact that the code to handle custom rows in the analyticscell.js doesn't seem to be able to handle anything aside from numbers. I'll show what I'm doing below.

I created an overlay at /apps/wcm/core/content/common/availablecolumns with the following code (truncated to save characters):

<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured"> <author jcr:primaryType="nt:unstructured" jcr:title="Author" columnGroup="news" page-info-provider="news" page-info-provider-property="author" default="{Boolean}true" sortable="{Boolean}true"/> <dispDate.../> </jcr:root>

I added a handler called NewsPageInfoProvider.java with the following (modeled after the github example):

@Component( metatype = false, immediate = true ) @Service @Properties(value = { @Property(name = "pageInfoProviderType", value = "sites.listView.info.provider." + NewsPageInfoProvider.providerType) }) public class NewsPageInfoProvider implements PageInfoProvider { public static final String providerType = "news"; public void updatePageInfo(SlingHttpServletRequest request, JSONObject info, Resource resource) throws JSONException { Article article = resource.adaptTo(Page.class).adaptTo(Article.class); JSONObject myProjectInfo = new JSONObject(); if (article != null) { Author a = article.getAuthor(); String author = ""; if(a != null) author = a.getDisplayName(); myProjectInfo.put("author", author); myProjectInfo.put("dispDate", article.getDispDate()); } info.put(providerType, myProjectInfo); } }

This works insofar as the columns can be added, and the java class is run for each row item (I confirmed this with logging).

Digging deeper, it appears that all custom columns are handled by the block starting at 185 in /libs/cq/gui/components/coral/admin/page/row/row.jsp, this code has comments and variable names suggesting it's treating everything like an analytics number. Furthermore, once it collects all the data it called up the analyticscell HTL file (selection from line 203):

if (propValue != null) { request.setAttribute("sites.listView.info.render.provider", providerName); request.setAttribute("sites.listView.info.render.providerProperty", columnProviderProperty); request.setAttribute("sites.listView.info.render.value", propValue.toString()); request.setAttribute("sites.listView.info.render.trend", trendInfo); %><cq:include path="<%=resource.getPath()%>" resourceType="cq/gui/components/siteadmin/admin/listview/coral/analytics/analyticscell"/><% }

 The HTL is pretty inconsequential, but the js use file (/libs/cq/gui/components/siteadmin/admin/listview/coral/analytics/analyticscell/analytics cell.js) it calls on in is confusing. I've confirmed with logging that my author and dispDate columns are processed, but nothing useful is returned by this file. Here's a snippet:

var providerName = _retrieveAttribute(CONST.PROP_PROVIDER_NAME, "default-provider"); var providerProperty = _retrieveAttribute(CONST.PROP_PROVIDER_PROPERTY, "default-property"); var valueAttribute = _retrieveAttribute(CONST.PROP_VALUE, -2); var trendInfo = _retrieveAttribute(CONST.PROP_TREND, 0); var dataPending = parseInt(valueAttribute) == -1; var dataAvailable = !(parseInt(valueAttribute) == -2); var text = ""; var value = "0"; var trend = ""; if (parseInt(valueAttribute) >= 0) { if (providerProperty == "averagetimespentonpage") { text = parseFloat(valueAttribute).toFixed(1); value = text; text += " min"; } else { // apply formatting to show K, M, G, etc text = _formatNumber(parseInt(valueAttribute)); value = text; } if (trendInfo < 0) { trend = "decrease"; } else if (trendInfo > 0) { trend = "increase"; } } else if (!dataAvailable) { text = "N/A"; } else if (dataPending) { text = "Pending" } return { dataAvailable: dataAvailable, dataPending: dataPending, trend: trend, // "increase" or "decrease" text: text, value: value };

I think this will only ever return a number in "value." I suspect this is a design issue that goes back to row.jsp as opposed to the analyticscell.js. But I can't figure out what should be done to remediate this issue.

Finally, here's a screenshot of what my console (a custom console to display news stories) looks like:

6 Replies

Avatar

Level 5

I ended up overlaying the entire analyticscell folder and modified analyticscell.js to be this (added a final else {} block).

/* * ADOBE CONFIDENTIAL * * Copyright 2015 Adobe Systems Incorporated * All Rights Reserved. * * NOTICE:  All information contained herein is, and remains * the property of Adobe Systems Incorporated and its suppliers, * if any.  The intellectual and technical concepts contained * herein are proprietary to Adobe Systems Incorporated and its * suppliers and may be covered by U.S. and Foreign Patents, * patents in process, and are protected by trade secret or copyright law. * Dissemination of this information or reproduction of this material * is strictly forbidden unless prior written permission is obtained * from Adobe Systems Incorporated. */ "use strict"; var global = this; use([], function () { var PROP_PREFIX = "sites.listView.info.render"; var CONST = { PROP_PROVIDER_NAME: PROP_PREFIX + ".provider", PROP_PROVIDER_PROPERTY: PROP_PREFIX + ".providerProperty", PROP_VALUE: PROP_PREFIX + ".value", PROP_TREND: PROP_PREFIX + ".trend", FORMATS: ["", "k", "M", "G", "T", "P", "E"] }; var _formatNumber = function(number) { var formatIndex = 0; var formattedNumber; while (number > 1000) { number = number / 1000; formatIndex++; } formattedNumber = (number % 1 > 0) ? number.toFixed(3) : number; formattedNumber = formattedNumber + " " + CONST.FORMATS[formatIndex]; return formattedNumber; }; var _retrieveAttribute = function (attrName, defaultValue) { var value = defaultValue; if (global.request && global.request.getAttribute && global.request.getAttribute(attrName)) { value = global.request.getAttribute(attrName); } return value; }; var providerName = _retrieveAttribute(CONST.PROP_PROVIDER_NAME, "default-provider"); var providerProperty = _retrieveAttribute(CONST.PROP_PROVIDER_PROPERTY, "default-property"); var valueAttribute = _retrieveAttribute(CONST.PROP_VALUE, -2); var trendInfo = _retrieveAttribute(CONST.PROP_TREND, 0); var dataPending = parseInt(valueAttribute) == -1; var dataAvailable = !(parseInt(valueAttribute) == -2); var text = ""; var value = "0"; var trend = ""; if (parseInt(valueAttribute) >= 0) { if (providerProperty == "averagetimespentonpage") { text = parseFloat(valueAttribute).toFixed(1); value = text; text += " min"; } else { // apply formatting to show K, M, G, etc text = _formatNumber(parseInt(valueAttribute)); value = text; } if (trendInfo < 0) { trend = "decrease"; } else if (trendInfo > 0) { trend = "increase"; } } else if (!dataAvailable) { text = "N/A"; } else if (dataPending) { text = "Pending" } else { dataAvailable = true; dataPending = false; text = valueAttribute; value = valueAttribute; } return { dataAvailable: dataAvailable, dataPending: dataPending, trend: trend, // "increase" or "decrease" text: text, value: value }; });

I don't think this is a good solution long-term, but I can't figure out how to get this working natively.

Avatar

Level 5

It works with the overlay, but I'm not sure if that's my best option. I think i'm just missing something in terms of how to get it working natively. That or the native solution is broken.

Avatar

Level 10

Seem to be an issue with the code that you overlay fixed. I would log a bug against that so Support and Eng are aware of it. 

Avatar

Level 1

I ran into the exact same issue. Thanks for pointing me to /apps/cq/gui/components/coral/admin/page/row/row.jsp. I decided to overlay that JSP rather than the analyticscell component, but I agree, it looks like an Adobe bug or limitation.

Avatar

Level 3

I have an almost similar issue with the list view in AEM 6.3 on /aem/products.html/etc/commerce/products page. The above changes work on site.html but for the  products.html no changes work. Seems like it is using different template/path which I am unable to find.