Resource Mapping in Adobe Experience Manager (AEM)

Abhigyan Swaroop
3 min readJul 11, 2020

Resource Mapping is very common and one of the extensively used solution in any technical implementation using AEM. In this article, we will try to understand the basics about it.

What is Resource Mapping in AEM?

Resource Mapping in AEM is a feature which enables AEM to define redirect, virtual host or Vanity URLs. It is used to create desired beautified URL Patterns which is clean and user-friendly in order to help make your website user-friendly and URLs, easy to remember.

For example, if an actual URL/content path in repository refers to https:www.myHost.com/Content/myHome/Homepage/contentpage.html
with the help of resource Mapping it can be converted into a user-friendly form
https:www.myHost.com/contentpage.html

How to define Resource Mapping ?

  1. Define desire mapping pattern in
    org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl
    You can define the set of rules which will execute and form the URLs based on the pattern you want the end users to access.
    The list can be viewed under JCRResolver in AEM and can be used to resolve and test the configuration.
    You can make a use of resource.resolver.mapping to create desired pattern of content path, for an example, a typical mapping set-up looks like following:
<?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:OsgiConfig”
resource.resolver.map.location=”/etc/map.publish”
resource.resolver.mapping=”[/content/myCompany/((?=us|au)[^/]+)/([^/]+)&lt;/$2,/content/myCompany/((?=us|au)[^/]+)/([^/]+)/([^/]+)/([^/]+)&lt;/$4]”/>

If, you notice closely, I have defined resource.resolver.map.location to,etc/map.publish That way you can even make it run modespecific, by taking advantage of the Sling OSGi Installer’s run mode awareness. More details here.

The Above Mapping will convert on publish (as you are making use of publish run mode).

* (host)/content/myCompany/us/en.html -> (host)/en.html

* (host)/content/myCompany/us/en/article/mySampleArticle.html ->(host)/mySampleArticle.html

More information about each of the properties and flags for attached Image can be found here

Resource Resolver Factory config

2. Testing your Configuration
To test your Resource Resolution is working as expected, you can go to Resource Resolver console in AEM and can test your URL and corresponding pattern.
This allows you to enter a URL or resource path. Click Resolve or Map to confirm how the system will transform the entry.
* Resolver Map Entries The list of entries used by the ResourceResolver.resolvemethods to map URLs to Resources.
* Mapping Map Entries The list of entries used by the ResourceResolver.map methods to map Resource Paths to URLs.

Defining Reverse Mapping for the mapped Paths

Now, that you have shortened the URLs for the end-users, we would need a reverse mapping in order to create an internal redirect so that correct content is served upon request.

  1. If you remember resource.resolver.map.location in the configuration we defined above, would be our location to create this reverse mapping (by default this mapping location is /etc/map).
    A typical Reverse Resolver mapping would look like
<?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:Mapping"
sling:internalRedirect="[/content/myCompany/$1/$2,/content/myCompany/us/en/article/$1/$2]"
sling:match=".+([^/]+)/(.*)$"/>

This will convert the shortened URLs into AEM understandable path i.e.
(host)/mySampleArticle.html -> (host)/ content/myCompany/us/en/artical /mySampleArticle

More details on the reverse mapping can be found here.

2. If you notice closely the screen-shot attached above, we can define both forward and backward mapping as a part of resource.resolver.mapping itself.
Incoming mappings are applied to request paths to map to resource paths, outgoing mappings are applied to map resource paths to paths used on subsequent requests.
Form is <internalPathPrefix><op><externalPathPrefix> where <op>is

  • > for incoming mappings,
  • < for outgoing mappings and
  • : for mappings applied in both directions.
    Mappings are applied in configuration order by comparing and replacing URL prefixes.
    Note: The use of “-” as the <op> value indicating a mapping in both directions is deprecated. (resource.resolver.mapping)
From my experience, I would suggest creating rewrite rules in dispatcher which would make the reverse mapping lot simpler and clean.For example: A sample rewrite Rule RewriteCond %{HTTP_HOST}    www.myCompany.com [OR]
RewriteCond %{HTTP_HOST} www.beta.myCompany.com
RewriteRule ^/$ /en [R=permanent,L]
RewriteCond %{HTTP_HOST} www.myCompany.com [OR]
RewriteCond %{HTTP_HOST} www.beta.myCompany.com
RewriteCond %{REQUEST_URI} ^/en$
RewriteRule /(.*) /content/MyCompany/us/$1.html [PT,QSA,NE,L]

Some issue you could face in above implementation

  1. If the Resource mapping is done for child pages i.e. for above example article then the reverse mapping needs to be defined keeping the URL structure which dispatcher will hit Publish server (check the dispatcher logs in this case), that can be little complex.
    2. While writing the reverse mapping, you can face, conflicting rule, which could result in 404 or incorrect redirection, therefore, always make use of JCR Revolver to check your config.

Useful Resources :

--

--