Adobe Experience Manager’s Sling RepoInit: When Should You Use It?

November 16, 2021
Lead Developer

We’re back to discuss when and how to use Sling Repolnit! Wondering what this tool is? Check out our post on the "what" and "why" behind it before diving into the below use cases. 

As a note, for the purposes of this article, all examples for RepoInit are syntax agnostic. This is because a RepoInit configuration can either be in a .cfg.json format or .xml format. So say, if you are doing this in  .xml you will have to use  "
" for a new-line character while /n would work just fine in case of a .cfg.json. If you want a quick refresher, look back to this post!

Use Case One: Permission Modelling

You can create users and groups, assign group membership, assign privileges and even add glob restrictions via repo init. If you have used ACL packages or any other third-party packages for performing these operations earlier, this should be a refreshing change!  

create path /home/groups/my-demo-site(rep:AuthorizableFolder)
create group Demo_Site_Users with path /home/groups/my-demo-site
set ACL for Demo_Site_Users
    allow jcr:read on /content/my-demo-site restriction(rep:glob,/jcr:primaryType)
end
set ACL for Demo_Site_Users
allow jcr:read on /content/my-demo-site restriction(rep:glob,/:childOrder)
end

create path /content/my-demo-site/language-masters/en(cq:Page)
create path /content/my-demo-site/language-masters/en/jcr:content(cq:PageContent)
set properties on /content/my-demo-site/language-masters/en/jcr:content
set sling:resourceType{String} to foundation/components/redirect
set sling:redirectStatus{Long} to 302
set sling:redirect{Boolean} to true
set jcr:title{String} to \"My Demo Site\"
set hideInNav{Boolean} to true
set noCrawling{Boolean} to true
set excludeFromSiteSearch{Boolean} to true
set cq:template{String} to /conf/my-demo-site/settings/wcm/templates/redirectpage
end
create group Demo_Site_SubGroup with path /home/groups/my-demo-site
add Demo_Site_SubGroup to group Demo_Site_Users
set ACL for Demo_Site_SubGroup
    allow jcr:read,jcr:modifyProperties,jcr:addChildNodes,rep:write,crx:replicate,
jcr:removeNode,jcr:removeChildNodes,jcr:lockManagement,jcr:versionManagement,jcr:nodeTypeManagement on /content/my-demo-site/language-masters/en
end

Two quick notes:

First, so far CUGs can’t be set up via RepoInit. While that is a limitation, I would still prefer it over one of the other ways discussed in this article.

Second, RepoInit does not support Authorizable names with spaces.

Use Case Two: Application Configuration

More often than not, you might run into exceptions where application execution errored out because a certain service user was missing. What did you do? Rambled and created a new one? What if you forgot to mention it to another developer who recently merged your code? Domino effect! Creating service users and setting service user permission is now just a few lines of work thanks to RepoInit. And since it is easily maintained in code, there is no way you are missing it.

Let's compare two ways to create service users: 

The Ensure Authorizable way: You need to create an OSGi configuration for each service user or group with the corresponding PID and unique identifier, so for two service users, two configurations are required.

/apps/my-demo-site/config/com.adobe.acs.commons.users.impl.EnsureServiceUser-serviceUser1

<?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"
    principalName="service-user1"
    operation="add"
    ensure-immediately="{Boolean}true"
    aces="[type=allow;privileges=jcr:read\,rep:write;path=/content/my-demo-site;rep:glob=/jcr:content/*]"/>

/apps/my-app/config/com.adobe.acs.commons.users.impl.EnsureServiceUser-serviceUser2

<?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"
    principalName="service-user2"
    operation="add"
    ensure-immediately="{Boolean}true"
    aces="[type=allow;privileges=jcr:read\,rep:write;path=/content/my-demo-site;rep:glob=/jcr:content/*]"/>

The Repo Init way: You do not need two configurations! 

create service user service-user1, service-user2
set ACL on /content/my-demo-site/jcr:content/*
    allow jcr:read for service-user1,service-user2
    allow rep:write for service-user1,service-user2
end

On the page for Ensure Authorizable in ACS AEM Commons, it is now recommended to move to Sling RepoInit!

Use Case Three: Initialize Content Structure

Creating paths, setting node types, defining default properties, and creating namespaces are a few tasks that come to mind when thinking about the initial project structure definition. Repoinit enables us to define all this and more.

For example, assume you have to: 

  • Register a custom JCR Namespace 
  • Create a folder named “XYZ” within the dam assets
  • Create a new path "/path/A"
  • Update an existing property under path "/path/B"

If you take the On-deploy script approach, which is not even available in Adobe Experience Manager as a Cloud Service (AEMaaCS), once you have registered the namespace via a CND file or CRX Explorer, the script to perform the remaining steps would look something like:

public class PrecreateContentScript extends OnDeployScriptBase {
 
    @Override
    protected void execute() throws Exception {
        Resource parent = this.getResourceResolver().resolve("/path");
        this.getResourceResolver().create(parent, "A",
                ImmutableMap.of(
                        "sling:ResourceType", "x/y/z",
                        "someInteger", 42,
                        "someBoolean", true,
                        "someDate", new Date()));
 
        Resource b = this.getResourceResolver().resolve("/path/B");
        ValueMap map = b.adaptTo(ModifiableValueMap.class);
 
        map.putIfAbsent("sling:ResourceType", "x/y/z");
        map.putIfAbsent("someInteger", 42);
        map.putIfAbsent("someBoolean", true);
        map.putIfAbsent("someDate", new Date());
    }
}

The Repo Init way:  

register namespace (my-demo-site) http://my.demo.site/content
create path (nt:unstructured) /path/A
set properties on /path/A, /path/B
  set sling:ResourceType{String} to /x/y/z
  default someInteger{Long} to 42
  set someFlag{Boolean} to true
  default someDate{Date} to "2020-03-19T11:39:33.437+05:30"
end

Wrapping It Up

Above are just a few of the use cases for when and how to use Sling Repolnit! Whether you need to set up permission modeling, configure applications, or initialize content structure—we highly recommend giving Sling Repolnit a try.

References and Resources: 

Part two of our Adobe Experience Manager’s Sling RepoInit series.