Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
LinkRewriter configuration for AEM.
// Create configuration inside /apps/<project-name>/config/rewriter/default.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"
paths="[/content/abc]"
generatorType="htmlparser"
order="1"
serializerType="htmlwriter"
transformerTypes="[linkchecker,versioned-clientlibs,surajk-url-rewriter]">
<generator-htmlparser
jcr:primaryType="nt:unstructured"
includeTags="[A,IMG,SCRIPT,LINK]"/>
</jcr:root>
package com.surajkamdi.core.services.rewriter;
import com.surajkamdi.core.utils.PathUtil;
import com.adobe.acs.commons.util.ModeUtil;
import java.io.IOException;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.sling.rewriter.ProcessingComponentConfiguration;
import org.apache.sling.rewriter.ProcessingContext;
import org.apache.sling.rewriter.Transformer;
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;
/** LinkRewriter will rewrite sites urls to remove "/content/abc". */
public class LinkRewriter implements Transformer {
private static final String HREF = "href";
private static final String DATA_NO_REWRITE = "data-no-rewrite";
private static final String A = "a";
private ContentHandler contentHandler;
@Override
public void setDocumentLocator(Locator locator) {
contentHandler.setDocumentLocator(locator);
}
@Override
public void startDocument() throws SAXException {
contentHandler.startDocument();
}
@Override
public void endDocument() throws SAXException {
contentHandler.endDocument();
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
contentHandler.startPrefixMapping(prefix, uri);
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
contentHandler.endPrefixMapping(prefix);
}
@Override
public void startElement(String uri, String localName, String qualifiedName, Attributes atts)
throws SAXException {
if (shouldRewrite(localName, atts)) {
String href = PathUtil.removeContentPrefix(atts.getValue(HREF));
if (href != null) {
AttributesImpl modifiedAttributes = new AttributesImpl(atts);
modifiedAttributes.setValue(atts.getIndex(HREF), href);
contentHandler.startElement(uri, localName, qualifiedName, modifiedAttributes);
} else {
contentHandler.startElement(uri, localName, qualifiedName, atts);
}
} else {
contentHandler.startElement(uri, localName, qualifiedName, atts);
}
}
@Override
public void endElement(String uri, String localName, String qualifiedName) throws SAXException {
contentHandler.endElement(uri, localName, qualifiedName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
contentHandler.characters(ch, start, length);
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
contentHandler.ignorableWhitespace(ch, start, length);
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
contentHandler.processingInstruction(target, data);
}
@Override
public void skippedEntity(String name) throws SAXException {
contentHandler.skippedEntity(name);
}
@Override
public void dispose() {
// nothing to dispose.
}
@Override
public void init(ProcessingContext context, ProcessingComponentConfiguration config)
throws IOException {
// nothing to init.
}
@Override
public void setContentHandler(ContentHandler handler) {
this.contentHandler = handler;
}
private boolean shouldRewrite(String localName, Attributes atts) {
return A.equalsIgnoreCase(localName)
&& ModeUtil.isPublish()
&& !BooleanUtils.toBoolean(atts.getValue(DATA_NO_REWRITE));
}
}
package com.surajkamdi.core.services.rewriter;
import org.apache.sling.rewriter.Transformer;
import org.apache.sling.rewriter.TransformerFactory;
import org.osgi.service.component.annotations.Component;
@Component(property = {"pipeline.type=surajk-url-rewriter"}, service = {TransformerFactory.class})
public class LinkRewriterFactory implements TransformerFactory {
@Override
public Transformer createTransformer() {
return new LinkRewriter();
}
}
package com.surajkamdi.core.utils;
import java.util.Arrays;
import org.apache.commons.lang3.StringUtils;
public class PathUtil {
private static final String CONTENT_PREFIX = "/content/abc";
private static final String[] PREFIXES = {
CONTENT_PREFIX,
};
private PathUtil() {
throw new IllegalStateException("Utility class");
}
/**
* Remove any of the PREFIXES such as /content/abc from beginning of path, if exists.
* @param path the path to process
* @return path with removed PREFIXES such as /content/abc
*/
public static String removeContentPrefix(String path) {
if (StringUtils.isBlank(path)) {
return path; // blank, return it as is.
} else {
return Arrays.stream(PREFIXES)
.filter(prefix -> StringUtils.startsWith(path, prefix)) // find prefix
.findFirst() // cannot match more than one
.map(foundPrefix -> StringUtils.removeStart(path, foundPrefix)) // remove prefix
.orElse(path);
}
}
/**
* Prepends /content/abc if the path is missing it.
* @param path the path to prepend content path to.
*/
public static String addContentPrefix(String path) {
if (path == null) {
return null;
} else {
if (StringUtils.startsWith(path, "/")) {
// starts with /, prepend /content/abc
return StringUtils.prependIfMissing(path, CONTENT_PREFIX);
} else {
// does not start with /, prepend /content/abc/ (note additional slash)
return StringUtils.prependIfMissing(path, CONTENT_PREFIX + "/");
}
}
}
/**
* Checks if path starts with /content/abc.
* @param path the path.
*/
public static boolean isABCPath(String path) {
return StringUtils.startsWith(path, CONTENT_PREFIX);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment