Michal Cukierman
Jan 2 2023 5 min read
Michal Cukierman
Jan 2 2023 5 min read
Comparing two versions of a single page on one system
Content versioning is one of the essential features of a mature CMS. The ability to work with pages, compare and roll back when needed is a must in a collaborative environment. Luckily it’s also well supported by Apache Sling. In this article, I will explain how to do basic operations using only JCR and Sling APIs.
Sling supports versioning of JCR Resources. JCR Resources are used to represent the content
, and as a consequence, it’s possible to version pages, assets, and tags. Unlike other Content Management Systems, we do not store scripts, configurations, and bundles in the JCR, for more information, see this blog post.
To make a JCR Resource versionable, we need to add JCR Mixin
to it. The easiest way to do it is to execute a script in the Groovy Console:
home = session.getNode("/published/ds-website/pages/home");
home.addMixin("mix:versionable")
// Save is required to get apply mixin
session.save();
You can verify the result with the Resource Browser. The resource should now contain new properties.
New properties assigned the versioned resource
Again, let's use Groovy script to create a couple of versions of a homepage:
home = session.getNode("/published/ds-website/pages/home");
for (int i = 0; i< 10; i++) {
home.checkout();
home.checkin();
}
println home.getVersionHistory();
The code above should create 10 versions of a page and print the complete history once done. Note that version creation is relatively expensive, so we should not overuse it. Each version of a resource is stored as a jcr:fronzenNode
under /jcr:system/jcr:versionStorage/<generated hash>
.
In my case, the path is /jcr:system/jcr:versionStorage/5f/2b/64/5f2b64d2-fdb9-4ed5-af8a-cd92a6971f66
.
There are multiple ways we can access the page versions.
Directly by accessing frozen node with .html extension.
In my case, it's http://localhost:8080/jcr:system/jcr:versionStorage/5f/2b/64/5f2b64d2-fdb9-4ed5-af8a-cd92a6971f66/1.10/jcr:frozenNode/jcr:content.html
, but it will be unique on every system.
Programmatically by using JCR API [1]
Using Sling API for getting available versions and fetching versioned content [2]
Before using Sling version info, the configuration: org.apache.sling.servlets.get.impl.version.VersionInfoServlet has to be enabled with default values. Once it's done, the versions can be read by visiting the following URL: http://localhost:8080/content/ds-website/pages/home.V.tidy.json
.
JSON with homepage versions information
It's relatively easy to compare two versions by comparing the output of requests to URLs:
http://localhost:8080/content/ds-website/pages/home.tidy.5.json;v=1.10
and
http://localhost:8080/content/ds-website/pages/home.tidy.5.json
It's also possible to read individual components from versioned pages:
http://localhost:8080/content/ds-website/pages/home/jcr:content/rootcontainer/header.tidy.5.json;v=1.10
At the time of writing, content versioning is still on our Roadmap. Nevertheless, we get most of the work done by the JCR and Sling projects, and as a result, the feature should be shipped relatively quickly. We can once again benefit from choosing a battle-tested platform to run our CMS.