I have a requirement to select the thumbnail of folder from AEM /content/dam instead of local upload. I understand it currently is a file upload which stores the folder thumbnail in binary format under /folderThumbnail in the folder. I want to make the same functionality work by selecting the image from DAM and store the binary file inside the folder.
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @aagarwal8192 ,
To customize the folder thumbnail functionality in Adobe Experience Manager (AEM) and allow users to select an image from the Digital Asset Management (DAM) instead of uploading a local image, you'll need to follow several steps. These include creating a custom component, modifying the folder thumbnail node structure, and implementing a servlet to handle the thumbnail selection and update process. Here’s a detailed guide on how to accomplish this:
Overlay the Default Component:
Modify the Overlayed Component:
<!-- /apps/dam/gui/content/assets/folder/dialog/.content.xml -->
<jcr:root
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
jcr:primaryType="cq:Dialog"
title="Folder Thumbnail"
xtype="dialog">
<items jcr:primaryType="cq:TabPanel">
<items jcr:primaryType="cq:WidgetCollection">
<imageTab
jcr:primaryType="cq:Widget"
xtype="panel"
title="Thumbnail">
<items jcr:primaryType="cq:WidgetCollection">
<thumbnailPath
jcr:primaryType="cq:Widget"
fieldLabel="Select Thumbnail"
name="./thumbnailPath"
xtype="pathfield"
rootPath="/content/dam"
allowUpload="false"
anchor="100%">
</thumbnailPath>
</items>
</imageTab>
</items>
</items>
</jcr:root>
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.api.servlets.SlingServletPaths;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.propertytypes.ServiceDescription;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component(service = { Servlet.class })
@SlingServletPaths("/bin/updateFolderThumbnail")
@ServiceDescription("Servlet to update folder thumbnail from DAM asset")
public class FolderThumbnailServlet extends SlingAllMethodsServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String folderPath = request.getParameter("folderPath");
String thumbnailPath = request.getParameter("thumbnailPath");
ResourceResolver resourceResolver = request.getResourceResolver();
Resource folderResource = resourceResolver.getResource(folderPath);
if (folderResource != null) {
ModifiableValueMap properties = folderResource.adaptTo(ModifiableValueMap.class);
properties.put("thumbnailPath", thumbnailPath);
resourceResolver.commit();
response.setStatus(HttpServletResponse.SC_OK);
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Folder resource not found");
}
}
}
(function(document, $) {
$(document).on("click", ".cq-damadmin-admin-actions-change-thumbnail", function() {
var folderPath = ...; // Get the folder path
var dialog = new CQ.Dialog({
title: "Select Thumbnail",
items: [{
xtype: "pathfield",
fieldLabel: "Select Thumbnail",
rootPath: "/content/dam",
listeners: {
change: function(field, value) {
$.post("/bin/updateFolderThumbnail", {
folderPath: folderPath,
thumbnailPath: value
}).done(function() {
alert("Thumbnail updated successfully!");
}).fail(function() {
alert("Failed to update thumbnail.");
});
}
}
}]
});
dialog.show();
});
})(document, Granite.$);
This process ensures the folder thumbnail can be updated using a DAM asset, providing a seamless experience within AEM. Adjust and refine the code snippets based on your specific AEM setup and requirements.
Hi @aagarwal8192 ,
To customize the folder thumbnail functionality in AEM to select an image from DAM instead of a local upload, you can follow these general steps:
1. Create a custom component: Create a custom component that allows the user to select an image from DAM. You can use the Asset Finder component or create a custom component that uses the Asset Selector API to allow the user to select an image.
2. Store the binary file in the folder: Once the user selects an image, you can use the Sling POST Servlet to store the binary file in the folder. You can create a custom servlet that handles the POST request and saves the binary file to the /folderThumbnail node of the folder.
3. Update the folder thumbnail: After storing the binary file in the folder, you can update the folder thumbnail to use the new image. You can use the Asset Manager API to set the thumbnail property of the folder to the path of the new image.
Here's an example of how you can use the Sling POST Servlet to store the binary file in the folder:
```
@SlingServlet(
methods = { "POST" },
resourceTypes = { "sling/folder" },
selectors = { "thumbnail" },
extensions = { "jpg", "jpeg", "png", "gif" }
)
public class FolderThumbnailServlet extends SlingAllMethodsServlet {
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
Resource folderResource = request.getResource();
Node folderNode = folderResource.adaptTo(Node.class);
Node thumbnailNode = JcrUtils.getNodeIfExists(folderNode, "folderThumbnail");
if (thumbnailNode == null) {
try {
thumbnailNode = folderNode.addNode("folderThumbnail", "nt:file");
Node contentNode = thumbnailNode.addNode("jcr:content", "nt:resource");
contentNode.setProperty("jcr:mimeType", "image/jpeg");
} catch (RepositoryException e) {
throw new ServletException("Failed to create folder thumbnail node", e);
}
}
InputStream inputStream = request.getInputStream();
Node contentNode = thumbnailNode.getNode("jcr:content");
Binary binary = contentNode.getSession().getValueFactory().createBinary(inputStream);
contentNode.setProperty("jcr:data", binary);
contentNode.setProperty("jcr:lastModified", Calendar.getInstance());
contentNode.getSession().save();
response.setStatus(HttpServletResponse.SC_OK);
}
}
```
In this example, we create a custom servlet that handles the POST request to store the binary file in the /folderThumbnail node of the folder. We check if the /folderThumbnail node exists, and if not, we create it. We then read the binary data from the request input stream and save it to the /folderThumbnail/jcr:content node as a binary property.
After storing the binary file in the folder, you can update the folder thumbnail to use the new image by setting the thumbnail property of the folder to the path of the new image. You can use the Asset Manager API to do this:
```
Resource folderResource = ...; // get the folder resource
String thumbnailPath = folderResource.getPath() + "/folderThumbnail/jcr:content";
AssetManager assetManager = folderResource.getResourceResolver().adaptTo(AssetManager.class);
assetManager.setThumbnail(folderResource.getPath(), thumbnailPath);
```
In this example, we get the folder resource and the path of the new thumbnail image. We then use the Asset Manager API to set the thumbnail property of the folder to the path of the new image.
Please note that this is just an example and may need to be customized to fit your specific requirements.
Can you share the use case you are trying to solve here?
This level of customization is not needed for a folder thumbnail which will not be utilized.
@gkalyanI have a use case where the folders and thumbnails are already there and we need to migrate it to AEM. AEM OOTB gives a behavior of merging 3 assets and create one thumbnail. This need to be re written using the custom thumbnail which is already written and then using the the AEM pathfield feature to choose from AEM and then override the custom folderThumbnail.
@HrishikeshKa Do you have any pointers for custom component ? As I can see in the tree the change thumbnail is coming as part of node structure. I can overlay it in apps and then create another similar button or override the default behaviour of the current button in JS. But how do we show the pathfield dialog and call the servlet ?
Hi @aagarwal8192 ,
To customize the folder thumbnail functionality in Adobe Experience Manager (AEM) and allow users to select an image from the Digital Asset Management (DAM) instead of uploading a local image, you'll need to follow several steps. These include creating a custom component, modifying the folder thumbnail node structure, and implementing a servlet to handle the thumbnail selection and update process. Here’s a detailed guide on how to accomplish this:
Overlay the Default Component:
Modify the Overlayed Component:
<!-- /apps/dam/gui/content/assets/folder/dialog/.content.xml -->
<jcr:root
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
jcr:primaryType="cq:Dialog"
title="Folder Thumbnail"
xtype="dialog">
<items jcr:primaryType="cq:TabPanel">
<items jcr:primaryType="cq:WidgetCollection">
<imageTab
jcr:primaryType="cq:Widget"
xtype="panel"
title="Thumbnail">
<items jcr:primaryType="cq:WidgetCollection">
<thumbnailPath
jcr:primaryType="cq:Widget"
fieldLabel="Select Thumbnail"
name="./thumbnailPath"
xtype="pathfield"
rootPath="/content/dam"
allowUpload="false"
anchor="100%">
</thumbnailPath>
</items>
</imageTab>
</items>
</items>
</jcr:root>
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.api.servlets.SlingServletPaths;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.propertytypes.ServiceDescription;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component(service = { Servlet.class })
@SlingServletPaths("/bin/updateFolderThumbnail")
@ServiceDescription("Servlet to update folder thumbnail from DAM asset")
public class FolderThumbnailServlet extends SlingAllMethodsServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String folderPath = request.getParameter("folderPath");
String thumbnailPath = request.getParameter("thumbnailPath");
ResourceResolver resourceResolver = request.getResourceResolver();
Resource folderResource = resourceResolver.getResource(folderPath);
if (folderResource != null) {
ModifiableValueMap properties = folderResource.adaptTo(ModifiableValueMap.class);
properties.put("thumbnailPath", thumbnailPath);
resourceResolver.commit();
response.setStatus(HttpServletResponse.SC_OK);
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Folder resource not found");
}
}
}
(function(document, $) {
$(document).on("click", ".cq-damadmin-admin-actions-change-thumbnail", function() {
var folderPath = ...; // Get the folder path
var dialog = new CQ.Dialog({
title: "Select Thumbnail",
items: [{
xtype: "pathfield",
fieldLabel: "Select Thumbnail",
rootPath: "/content/dam",
listeners: {
change: function(field, value) {
$.post("/bin/updateFolderThumbnail", {
folderPath: folderPath,
thumbnailPath: value
}).done(function() {
alert("Thumbnail updated successfully!");
}).fail(function() {
alert("Failed to update thumbnail.");
});
}
}
}]
});
dialog.show();
});
})(document, Granite.$);
This process ensures the folder thumbnail can be updated using a DAM asset, providing a seamless experience within AEM. Adjust and refine the code snippets based on your specific AEM setup and requirements.
@HrishikeshKa Thanks for your entire solution. This clearly is the solution to my requirement. In the source code you mentioned its and EXTJS based dialog. Is it possible to achieve the same using Coral UI Pathfield ?
Views
Like
Replies