Versioning functionality is enabled by default in Magnolia in the Pages, Assets and Contacts apps. Versions are saved automatically and can be reverted to as necessary.

The versioning functionality is enhanced by the Diff module that adds diff and redlining capabilities. (warning) The Diff module is not yet available in the CE, but will be in an future release of Magnolia 5.

By default, versions are created when pages, assets and contacts are published, unpublished and restored in the related apps. Versions are also created in these apps for the purpose of restoring items prior to deletion. For more information see Deleting and restoring.

Versioning can be enabled by configuration for any content app

In a new installation of the Magnolia bundle all demo pages, assets and contacts do not have versions even though the status indicator is green (published). This is because the content is marked as published when bootstrapped into the web applications, but no actual publication has taken place at this point in time. The available versions actions remain inactive until actual versions are created by publishing, unpublishing or deleting.

 

Version configuration

The VersionConfig classes in the CE and EE differ.

  • In the CE, the number of versions is set to 3 and this is not configurable.
  • In the EE, the number of versions is not limited and can be set by configuration. By default up to 10 versions are stored. This is configured in  /server/versions:

Node nameValue
 server

 version

 active

true

 maxVersionIndex

 10

Properties:

  • active allows you to enable and disable versioning.
  • maxVersionIndex sets the number of versions to store.

Previous versions created before setting new maximum version index will not be affected until a new version is created. For example, if node ‘A' has 10 versions and you change the max version index to 2, you will still see all 10 versions until the next versioning occurs. Once node 'A' is versioned again, all previous 9 versions will be removed.

Version command

Versions are created when VersionCommand is triggered. A new version of the content is created and added to the version file. VersionCommand provides for standard and recursive versioning, and the addition of a version comment.

Command chains

Command definitions that call versionCommand are configured for the activate and deactivate command chains in the Activation and Workflow modules.

Here's the command definition in the activation module in the Configuration app > /modules/activation/commands/versioned/activate/version and /deactivate/version. You will find similar configurations for the workflow module in the Configuration app > /modules/workflow/commands/workflow/activate/version and /deactivate/version.

Node nameValue
 modules 

 activation

 

 commands

 

 default

 

 versioned

 

 activate

 

 version

 

 class

info.magnolia.commands.impl.VersionCommand

 enabled

 true

 activate

 

 deactivate

 

 version

 

 class

 info.magnolia.commands.impl.VersionCommand

 enabled

 true

 deactivate

 

The command chains are triggered when the Publish, Unpublish and Publish deletion actions are executed in the various apps that use them. Here's the action definition for the Publish action in the Assets app configured in the Configuration app > /modules/dam/apps/assets/subApps/browser/actions/activate.

Node nameValue
 modules 

 dam

 

 apps

 

 assets

 

 subApps

 

 browser

 

 actions

 

 activate

 

 availability

 

 catalog

 versioned

 class

info.magnolia.ui.framework.action.ActivationActionDefinition

 command

 activate

 icon

 icon-publish

Showing versions

The Show versions action opens a dialog that displays a list of versions. The SHOW action in the dialog opens the selected version in the detail subapp.

The ShowVersionsAction and ShowVersionsActionDefintion classes define the dialog and its content, and what happens when the CANCEL and SHOW actions are executed. All that is necessary is the configuration of an action definition within an app configuration. The code takes care of the rest. Here's the action definition for the Show versions action in the Contacts app configured in the Configuration app > /modules/contacts/apps/contacts/subApps/browser/actions/showVersions.

(warning) 5.3 +

Node nameValue
 modules 

 contacts

 

 apps

 

 contacts

 

 subApps

 

 browser

 

 actions

 

 showVersions

 

 availability

 

 rules

 

 HasVersionsRule

 

 ruleClass

info.magnolia.ui.api.availability.HasVersionsRule

 class

info.magnolia.ui.contentapp.browser.action.ShowVersionsActionDefinition

 icon

 icon-show-versions

 

5.2.x and earlier versions

Node nameValue
 modules 

 contacts

 

 apps

 

 contacts

 

 subApps

 

 browser

 

 actions

 

 showVersions

 

 availability

 

 ruleClass

info.magnolia.ui.api.availability.HasVersionsRule

 class

info.magnolia.ui.contentapp.browser.action.ShowVersionsActionDefinition

 icon

 icon-show-versions

Here's a snippet from ShowVersionsAction that ensures that the correct content is displayed when SHOW is clicked.

@Override
protected Location getLocation() throws ActionExecutionException {
  try {
      final Node node = getNode();
      final String path = node.getPath();
      final String appName = appContext.getName();
      return new DetailLocation(appName, "detail", DetailView.ViewType.VIEW, path, (String)getItem().getItemProperty("versionName").getValue());
    } catch (RepositoryException e) {
      throw new ActionExecutionException("Could not get node from nodeAdapter " + nodeAdapter.getItemId());
    }
}

Enabling versioning in content apps

You can enable versioning in a content app by triggering the activate/deactivate command chains in the versions catalog instead of the activate/deactivate commands in the default catalog. Here is the process to enable versioning in the Categories app.

In the Configuration app > /modules/categorization/apps/categories/subApps/browser:

  1. Change the activate and deactivate action definitions.
    In the /actions/activate and /deactivate nodes add a catalog property and set the value to versioned. This calls the chained version command configured in the activation module in modules/activation/commands/versioned/activate and /deactivate.

    Node nameValue
     modules 

     categorization

     

     apps

     

     categories

     

     subApps

     

     browser

     

     actions

     

     activate

     

     availability

     

     catalog

    versioned

     class

    info.magnolia.ui.framework.action.ActivationActionDefinition

     command

    activate

     icon

    icon-publish

     recursive

    true

     deactivate

     

     availability

     

     catalog

    versioned

     class

    info.magnolia.ui.framework.action.DeactivationActionDefinition

     command

    deactivate

     icon

    icon-unpublish
  2. Add the Show versions action configuration.
    In the /actions node add the /showVersions configuration as shown below. Alternatively, you can simply extend the configuration in another content app, for example the configuration in the Contacts app configured in /modules/contacts/apps/contacts/subApps/browser/actions/showVersions.

(warning) 5.3 +

Node nameValue

 browser

 

 actions

 

 activate

 

 deactivate

 

 showVersions

 

 availability

 

 rules

 

 HasVersionsRule

 

 ruleClass

info.magnolia.ui.api.availability.HasVersionsRule

 class

info.magnolia.ui.contentapp.browser.action.ShowVersionsActionDefinition 

 icon

icon-show-versions

5.2 and earlier version

Node nameValue

 browser

 

 actions

 

 activate

 

 deactivate

 

 showVersions

 

 availability

 

 ruleClass

info.magnolia.ui.api.availability.HasVersionsRule

 class

info.magnolia.ui.contentapp.browser.action.ShowVersionsActionDefinition 

 icon

icon-show-versions

 

  1. Add the Show versions action to the action bar.
    In the /actionbar/sections/category/groups node, add the /versionsActions configuration shown below. Alternatively, you can simply extend the configuration in another content app, for example the configuration in the Contacts app configured in /modules/contacts/apps/contacts/subApps/browser/actionbar/sections/contact/groups/versionsActions.

    Node nameValue

     browser

     

     actions

     

     actionbar

     

     sections

     

     root

     

     deletedFolder

     

     deletedCategory

     

     folder

     

     category

     

     groups

     

     addActions

     

     editActions

     

     activationActions

     

     importExportActions

     

     versionsActions

     

     items

     

     showVersions

     
  2. In the Categories app, create a few versions by activating and deactivating an item and then execute the Show versions action to open the VERSIONS dialog.

Comparing versions

Version comparison relies on functionality provided by the Diff module. The module uses the daisydiff java library to compare HTML files.

Diff servlet

VersionDiffHtmlServlet is registered in the Magnolia filter chain in the Configuration app > /server/filters/servlets/VersionDiffHtmlServlet. The controller generates the diff view between two versions of a page by checking the toVersionNr and fromVersionNr request parameters.

Node nameValue

 VersionDiffHtmlServlet

 

 mappings

 

 -.magnolia-versionDiff

 

 pattern

/.magnolia/versionDiff

 parameters

 

 class

info.magnolia.cms.filters.ServletDispatchingFilter

 comment

 Shows html diff of different page versions.

 enabled

 true

 servletClass

 info.magnolia.module.diff.VersionDiffHtmlServlet

 servletName

 VersionDiffHtmlServlet

Diff configuration

(warning) Magnolia 4.5.10/Diff 1.1.5 +. The default settings for headers, cookies, host and port can be set by configuration.

By default Magnolia is set to generate a JSESSIONID cookie. This is configured in the diff module in the Configuration app > /modules/diff/config/cookies

Node nameValue
 modules 

 diff

 

 config

 

 cookie

 

 0

JSESSIONID

You can configure custom settings for:

  • cookies: You can specify any number of custom session cookie names to forward.
  • headers: The default value is none. By adding a  headers config node you can specify any number of headers to be sent to the diff servlet thereby automatically excluding any headers that are not specified.
  • host and port: The default host and port is localhost and 8080. However, the Diff module will work even if you change the default Tomcat port. This means that you can use the diff functionality against another server.

(warning) Headers and cookies are configured separately.

Node nameValue

 diff

 

 config

 

 cookies

 

 0

<cookieA>

 1

<cookieB>

 headers

 

 0

<headerA>

 1

<headerB>

 host

<host>

 port

<port>

Diff HTML generator

VersionDiffHtmlGenerator compares two HTML files using HTMLDiffer and returns HTML that highlights the differences between the compared pages:

  • The comparison only includes the body of the HTML document.
  • The differences are marked with span tags.
  • The header is taken from the HTML of the page that is compared to.
  • CSS is added.

Here's a snippet from diff.css (GIT) located in the mgnl-resources folder of the module jar

/*
 * Styles for the HTML Diff
 */
span.diff-html-added {
    font-size: 100%;
    background-color: #ccffcc; /* light green */
    cursor: pointer;
}
span.diff-html-removed {
    font-size: 100%;
    text-decoration: line-through;
    background-color: #fc6f6f; /* light red */
    cursor: pointer;
}
span.diff-html-changed {
    background-color: #95c6fd; /* light blue */
    cursor: pointer;
}
span.diff-html-selected {
    background-color: #FF8800; /* light orange */
    cursor: pointer;
}

Diff utility classes

Two utility classes are provided:

  • DiffUtil provides the buildComparisonURL, buildComparisonURLToCurrent and buildComparisonURLToCurrentUnversioned methods.
  • VersionComparison is a POJO that gets and sets the versionFrom and versionTo methods.

Compare actions

The CompareVersionsAction and CompareToPreviousVersionAction open the diff subapp (see below) configured in the Pages app. The action definitions are configured in the Configuration app > /modules/pages/apps/pages/subApps/browser/actions.

Node nameValue
 modules 

 pages

 

 apps

 

 pages

 

 subApps

 

 browser

 

 actions

 

 compareVersions

 

 availability

 

 class

info.magnolia.module.diff.app.action.CompareVersionsActionDefinition 

 icon

icon-compare-versions

 label

Compare versions

 compareToPreviousVersion

 

 availability

 

 class

 info.magnolia.module.diff.app.action.CompareToPreviousVersionActionDefinition

 icon

 icon-compare-versions

 label

 Compare to previous version

Diff subapp

The diff view that opens when comparing different page versions is configured in the Pages app. This configuration is in the Configuration app > /modules/pages/apps/pages/subApps/diff.

Node nameValue
 modules 

 pages

 

 apps

 

 pages

 

 subApps

 

 browser

 

 detail

 

 diff

 

 class

info.magnolia.ui.framework.app.embedded.EmbeddedPageSubAppDescriptor

 label

 Show changes

 subAppClass

 info.magnolia.ui.framework.app.embedded.EmbeddedPageSubApp

Here's the diff subapp for the /demo-project/about/history page. The URL is http://localhost:8080/magnoliaAuthor/.magnolia/admincentral#app:pages:diff;/magnoliaAuthor/.magnolia/versionDiff?diffViewContentHandle=/demo-project/about/history&fromVersionNr=1.2&toVersionNr=1.0. Note the reference to the diffViewContentHandle and VersionNr parameters

The CompareToPreviousVersionAction is also used in the workflow process to open the diff subapp. You can find the action definition and action assignment configurations in the Configuration app > /modules/pages/messageViews/publish/actions/diff and /messageViews/actionbar/sections/workflowActions/groups/reviewActions/items/diff.

#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))