stdio.h
stdio.h

Reputation: 126

AEM: links transform/rewrite in a page

In my current project the dam assets are being moved to CDN server and my current src attributes in img elements should refer the corresponding cdn server image and not the one in the dam.
eg: my current img element looks like this:
< img src="/content/dam/myproject/123.jpg">

I have a corresponding 123.jpg image in CDN server. NOW, the src should be changed to refer the CDN server image.
< img src="https://cdn-aem.com/content/dam/myproject/123.jpg ">

I can change this at the component level But I'm looking to change this at a more global level using OSGi service or something!

Any inputs ?

Upvotes: 1

Views: 10197

Answers (2)

Tiberiu Maxim
Tiberiu Maxim

Reputation: 1582

I wanted to achieve the same as you described. You may want to have a look here: https://adobe-consulting-services.github.io/acs-aem-commons/features/utils-and-apis/static-reference-rewriter/index.html

Steps:

A. Download and install AEM ACS Commons package on your instance (get zip package from the above website, install in package manager)

B. Go to apps/<yourapp>/config and create a file named com.adobe.acs.commons.rewriter.impl.StaticReferenceRewriteTransformerFactory-<your-custom-name>.xml with contents similar to these:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"     xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="sling:OsgiConfig"
    pipeline.type="your-custom-pipeline-name"
    attributes="[img:src\,srcset,link:href,script:src]"
    matchingPatterns="[img:srcset;(\/content\/dam\/.+?[jpg|png]) .+?w]"
    host.pattern="your.domain.com"
    prefixes="[/etc/designs,/content/dam]"
/>

C.Under apps/<yourapp>/config/rewriter create a file <another-custom-name>.xml containing this:

<?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"
    jcr:primaryType="sling:Folder"
    contentTypes="[text/html]"
    enabled="{Boolean}true"
    generatorType="htmlparser"
    order="{Long}1"
    serializerType="htmlwriter"
    transformerTypes="[linkchecker,your-custom-pipeline-name]"
/>

Reinstall the bundle on your instance and test. Good luck!

Upvotes: 1

nateyolles
nateyolles

Reputation: 1921

You can use a Sling Rewriter. The documents are available on the Apache Sling website. I'm including a sample Sling Transformer below. You also need to add a configuration node. You can find an additional example in the ACS Commons Versioned Clientlibs feature.

Add this Transformer and update the StartElement method to handle your path updates:

import java.io.IOException;
import java.util.Map;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.rewriter.ProcessingComponentConfiguration;
import org.apache.sling.rewriter.ProcessingContext;
import org.apache.sling.rewriter.Transformer;
import org.apache.sling.rewriter.TransformerFactory;
import org.osgi.service.component.ComponentContext;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

@Component
@Service
@Property(name="pipeline.type", value="linkrewriter", propertyPrivate=true)
public class LinkRewriterTransformerFactory implements TransformerFactory {

    public Transformer createTransformer() {
        return new LinkRewriterTransformer();
    }

    @Activate
    protected void activate(Map<String, Object> properties) {
    }

    @Deactivate
    protected void deactivate(ComponentContext ctx) {
    }

    private class LinkRewriterTransformer implements Transformer {
        private ContentHandler contentHandler;
        private SlingHttpServletRequest request;

        public void characters(char[] ch, int start, int length) throws SAXException {
            contentHandler.characters(ch, start, length);
        }

        public void dispose() {
        }

        public void endDocument() throws SAXException {
            contentHandler.endDocument();
        }

        public void endElement(String uri, String localName, String qName) throws SAXException {
            contentHandler.endElement(uri, localName, qName);
        }

        public void endPrefixMapping(String prefix) throws SAXException {
            contentHandler.endPrefixMapping(prefix);
        }

        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
            contentHandler.ignorableWhitespace(ch, start, length);
        }

        public void init(ProcessingContext context, ProcessingComponentConfiguration config) throws IOException {
            request = context.getRequest();
        }

        public void processingInstruction(String target, String data) throws SAXException {
            contentHandler.processingInstruction(target, data);
        }

        public void setContentHandler(ContentHandler handler) {
            this.contentHandler = handler;
        }

        public void setDocumentLocator(Locator locator) {
            contentHandler.setDocumentLocator(locator);
        }

        public void skippedEntity(String name) throws SAXException {
            contentHandler.skippedEntity(name);
        }

        public void startDocument() throws SAXException {
            contentHandler.startDocument();
        }

        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
            final AttributesImpl attributes = new AttributesImpl(atts);

            final String href = attributes.getValue("href");

            if (href != null) {
                for (int i = 0; i < attributes.getLength(); i++) {
                    if ("href".equalsIgnoreCase(attributes.getQName(i))) {
                        String cdnPath = /* process your path here */;
                        attributes.setValue(i, cdnPath);
                        break;
                    }
                }
            }

            contentHandler.startElement(uri, localName, qName, attributes);
        }

        public void startPrefixMapping(String prefix, String uri) throws SAXException {
            contentHandler.startPrefixMapping(prefix, uri);
        }
    }
}

Add this configuration node to /apps/myapp/config/rewriter/myapp.xml:

<?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"
    contentTypes="[text/html]"
    enabled="{Boolean}true"
    generatorType="htmlparser"
    order="1"
    paths="[/content/myapp]"
    serializerType="htmlwriter"
    transformerTypes="[linkchecker,linkrewriter]">
    <generator-htmlparser
        jcr:primaryType="nt:unstructured"
        includeTags="[META,/META,A,/A,IMG,AREA,FORM,BASE,LINK,SCRIPT,BODY,/BODY,VIDEO,/VIDEO,ASIDE,/ASIDE,SECTION,/SECTION]"/>
</jcr:root>

Upvotes: 5

Related Questions