3
votes

Using Adobe Experience Manager 5.6.1 (AEM) (Formerly CQ5) I am trying to create a new tab similar to the Image tab in Page Properties. It would be titled "Logo".

I basically just copied the Image tab to create a logo tab and renamed the paths to reflect the logo purpose. For instance, I set the fileReferenceParamater to ./logo/fileReference and requestSuffix to /logo.img.png.

When I edit the properties, I can drag an image into the tab just as I can with the "Image" tab, however, the image never appears there. I am guessing this is because the default image handler is not picking up the request. The error is:

Cannot serve request to /content/my-site/home-page/en_us/jcr:content/logo.img.png in org.apache.sling.servlets.get.DefaultGetServlet

When I looked at the content node there was no sling:resourceType. When I added a resource type of foundation/components/adaptiveimage then it worked. However, I noticed that the "Image" node didn't have a sling:resourceType. I guess the img.png.java servlet in the foundation page is handling that request.

I tried creating a logo.img.png.jsp file in my page component to handle the request, but that didn't seem to work.

How can I get AEM to either add the sling:resourceType or to handle the request?

3

3 Answers

5
votes

I was facing the similar problem and I found a simpler way to resolve. All you need to do is to add a hidden xtype under the your logo image as below:

<yourlogo
    jcr:primaryType="cq:Widget"
    <-- other properties -->
    xtype="html5smartimage">

    <items jcr:primaryType="cq:WidgetCollection">
        <resType
            jcr:primaryType="cq:Widget"
            ignoreData="{Boolean}true"
            name="./logo/sling:resourceType"
            value="foundation/components/image"
            xtype="hidden"/>
    </items>

</yourlogo>
1
votes

Well, after some time experimenting, this is what I ended up doing to get this to work. If there is an easier way, I would be happy to know it.

First, I copied the /libs/foundation/components/page/img.png.java file and added it to my compiled package with some modifications.

@SlingServlet(
        resourceTypes = "sling/servlet/default",
        selectors = "imgnode",
        extensions = {"png","jpg","jpeg","gif"},
        methods = "GET"
)
public class SimpleImageServlet extends AbstractImageServlet {

Where img.png.java had the following line:

Image image = new Image(c.resource, "image");

I changed it to:

Image image = new Image(c.resource);

This relies on SCR annotations to generate the OSGi configuration so that this servlet will handle image requests having the imgnode selector. Instead of looking for a child image node it just expects the current resource to be an image.

Second, I added a component to the body.jsp overlay of the page component, like so.

<cq:include path="logo" resourceType="/apps/my-site/components/logo" />

This maps the logo path to a component for rendering.

Third, within the logo.jsp on the component I set the selector to imgnode rather than img.

Image img = new Image(resourcePage, "logo");
img.setSelector("imgnode");

I believe this step would be similar if the adaptiveimage were overlayed. You just need to render out URLs that include the imgnode selector.

Fourth, I setup the logo image dialog tab in page properties to use the expected requestSuffix and set the other properties to point to the logo sub-node.

Examples:

requestSuffix = "/logo.imgnode.png"
fileReferenceParameter = "./logo/fileReference"

Fifth, I made sure that the image dialog tab for the /apps/my-site/components/logo component pointed to itself.

Examples:

requestSuffix = ".imgnode.png"
fileReferenceParameter = "./fileReference"

Now whether it is in page properties, component editing, or final rendering, the image is handled appropriately.

0
votes

this is a bit of a nuisance with using the image widget controls--only the image component nicely handles the data, and the servlet that handles ".img" is tied to the image component resourceType.

the easiest thing is to just use the value of the fileReference property instead of referencing the image as part of the page. since you're using assets from DAM, this is a reasonable approach.

this doesn't address the issue with a user uploading an image directly. i wanted to suggest having a hidden field like "./logo/sling:resourceType", but testing that locally resulted in an error when trying to save the dialog.

another approach is the following:

<sling:include resourceType="foundation/components/adaptiveimage" resource="${resource.path}/logo" />

(assuming resource is jcr:content). this is effectively the same as adding a sling:resourceType, but there are at least 2 downsides:

  1. the image becomes authorable at that point as opposed to in the dialog
  2. this method only works for rendering a normal tag. it won't work for any sort of background image