AEM Cloud Service - Assets Open PDF in new browser tab

Goal

AEM Cloud Version :  2021.3.5026.20210309T210727Z-210225 (March 09, 2021)

Add a button Open PDF in Tab to the Assets Console tool bar for inline opening the selected PDF in a new browser tab (please stress test it for larger PDFs as the getStream() function might cause performance issues)

Demo | Package Install | Github


Open PDF Button


PDF In New Tab


Solution

1) Add a proxy servlet apps.experienceaem.assets.core.servlets.PDFProxyServlet to set the content disposition of PDF stream to inline, so user can view the PDF pages in browser...

package apps.experienceaem.assets.core.servlets;

import com.day.cq.dam.api.Asset;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

@Component(
        name = "Experience AEM Proxy Servlet",
        immediate = true,
        service = Servlet.class,
        property = { "sling.servlet.methods=GET", "sling.servlet.paths=/bin/eaem/proxy" })
public class PDFProxyServlet extends SlingAllMethodsServlet {
    private static final Logger log = LoggerFactory.getLogger(PDFProxyServlet.class);

    @Override
    protected final void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response)
            throws ServletException, IOException {
        try {
            final String pdfPath = request.getParameter("path");

            if (StringUtils.isEmpty(pdfPath)) {
                return;
            }

            Resource pdfRes = request.getResourceResolver().getResource(pdfPath);

            streamPDF(response, pdfRes);
        } catch (final Exception e) {
            log.error("Could not get response", e);
            response.setStatus(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    private void streamPDF(final SlingHttpServletResponse response, final Resource pdfRes) throws Exception {
        String fileName = pdfRes.getPath().substring(pdfRes.getPath().lastIndexOf("/") + 1);

        response.setContentType("application/pdf");
        response.setHeader("Content-disposition", "inline; filename=" + fileName);

        Asset asset = pdfRes.adaptTo(Asset.class);
        final InputStream in = asset.getOriginal().getStream();

        final OutputStream out = response.getOutputStream();

        IOUtils.copy(in, out);

        out.close();

        in.close();
    }
}


2) Create the button configuration in /apps/eaem-assets-open-pdf/clientlibs/open-pdf-new-tab/open-pdf-but

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/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"
    sling:resourceType="granite/ui/components/coral/foundation/collection/action"
    activeSelectionCount="single"
    icon="filePDF"
    target=".cq-damadmin-admin-childpages"
    text="Open PDF in Tab"
    title="Open PDF in new tab"
    variant="actionBar"/>


3) Create a clientlib /apps/eaem-assets-open-pdf/clientlibs/open-pdf-new-tab/clientlib with categories=dam.gui.actions.coral for adding the button in Assets Console action bar and open the PDF in new tab when clicked

(function ($, $document) {
    "use strict";

    var _ = window._,
        initialized = false,
        ASSETS_PAGE = "/assets.html", $openPDFBut,
        BESIDE_ACTIVATOR = "cq-damadmin-admin-actions-create-activator",
        PROXY_PDF_URL = "/bin/eaem/proxy?path=",
        OPEN_PDF_BUT_URL = "/apps/eaem-assets-open-pdf/clientlibs/open-pdf-new-tab/open-pdf-but.html";

    if (!isAssetsPage()) {
        return;
    }

    $document.on("foundation-contentloaded", addActionBarButtons);

    $document.on("foundation-selections-change", ".foundation-collection", enableOpenPDFButton);

    function enableOpenPDFButton(){
        if(!$openPDFBut){
            return;
        }

        var $selections = $(".foundation-selections-item");

        if ($selections.length !== 1) {
            $openPDFBut.addClass("foundation-collection-action-hidden");
            return;
        }

        var mimeType = $selections.find(".foundation-collection-assets-meta").data("asset-mimetype");

        if(mimeType !== "application/pdf"){
            return;
        }

        $openPDFBut.removeClass("foundation-collection-action-hidden");
    }

    function addActionBarButtons(){
        if (initialized) {
            return;
        }

        initialized = true;

        $.ajax(OPEN_PDF_BUT_URL).done(addOpenPDFButton);
    }

    function addOpenPDFButton(html) {
        html = html || "";

        if(!html.trim()){
            return;
        }

        var $eActivator = $("." + BESIDE_ACTIVATOR);

        if ($eActivator.length == 0) {
            return;
        }

        $openPDFBut = $("<coral-actionbar-item>" + html + "</coral-actionbar-item>")
                                        .insertAfter($eActivator.closest("coral-actionbar-item"));

        $openPDFBut = $openPDFBut.find("button");

        $openPDFBut.click(openPDFInNewTab);
    }

    function openPDFInNewTab() {
        var $selections = $(".foundation-selections-item"),
            assetPath = $selections.data("foundationCollectionItemId");

        window.open(PROXY_PDF_URL + assetPath, '_blank');
    }

    function isAssetsPage() {
        return (window.location.pathname.indexOf(ASSETS_PAGE) >= 0);
    }
}(jQuery, jQuery(document)));


No comments:

Post a Comment