How to intercept a Magnolia CMS workflow. On launch.

Magnolia CMS Enterprise Edition ships with a very complete workflow engine, based on JBPM and perfectly integrated with the CMS Pulse system (more info on how it works here).
With JBPM you can model complex flows, using scheduled actions, flow gateways, events and connectors; and everything can be done visually, in Eclipse, in a professional way.
But.. you know.. sometimes you have to proceed in your development cutting the steps, in a very quick way.

For example, imagine you have to intercept a precise moment, for example when an editor launch the publication workflow. Normally, you have to:

  1. Clone EE git repository
  2. Install JBPM editor in Eclipse
    1. ..yes, you need Eclipse! Otherwise, manual editing of verbose XML..
  3. Edit the reviewForPublication workflow (adding a new Task)
  4. Create a WorkItemHandler in Magnolia
  5. Plug your business logic there
  6. Pack your changes and release your module

Quite long, yes. But there is a shortcut!

  1. Create a Command in Magnolia
  2. Plug your business logic there
  3. Pack your changes and release your module

Once an editor choose to activate a content, fills a two-fields dialog (optionally) and then click on SAVE button.

Workflow launch action
Workflow launch action
Standard workflow parameters
Standard workflow parameters

This action launches a Magnolia command. To be more precise, a Magnolia command chain, composed by 2 sub-commands:

  1. version: version the context node, to avoid ghost content activation
  2. activate: responsible of activating a workflow, the reviewForPublication one
A standard set up
A standard set up

Now, the game is simple. Just create a command and place it into the chain: before “version” to act before a version of the Node is created; in the middle to act before the workflow is instantiated; after “activate” to do something right after the workflow is launched.

A new command is placed just before the activation command
A new command is placed just before the activation command

The game is over. Once workflow is launched, the following lines are generated in log file:

2015-05-07 23:55:12,303 INFO  info.magnolia.commands.MgnlCommand                : Logging command parameters: 
2015-05-07 23:55:12,304 INFO  info.magnolia.commands.MgnlCommand                : param repository: website
2015-05-07 23:55:12,304 INFO  info.magnolia.commands.MgnlCommand                : param recursive: false
2015-05-07 23:55:12,304 INFO  info.magnolia.commands.MgnlCommand                : param path: /demo-features
2015-05-07 23:55:12,304 INFO  info.magnolia.commands.MgnlCommand                : param modifiedOnly: false
2015-05-07 23:55:12,304 INFO  info.magnolia.commands.MgnlCommand                : param uuid: babb5315-f417-4083-9cf1-714bb304742f
2015-05-07 23:55:12,304 INFO  info.magnolia.commands.MgnlCommand                : param comment: This is a comment
2015-05-07 23:55:12,304 INFO  info.magnolia.commands.MgnlCommand                : param publicationDate: 2015-05-07T23:54:00
2015-05-07 23:55:12,304 INFO  info.magnolia.commands.MgnlCommand                : param requestor: superuser

This is the code (the simples Magnolia Command ever!):

package com.matteopelucco.commands;

import info.magnolia.commands.MgnlCommand;
import info.magnolia.context.Context;

public class ContextLoggerCommand extends MgnlCommand {

  @Override
  public boolean execute(Context context) throws Exception {

    log.info("Logging command parameters: ");

    for (Object key : context.keySet()) {
      log.info("param {}: {}", key, context.get(key));
    }

    return true;

  }

}

To close the work, just pack this into the module: first, extract “log” node in XML and save into /$MODULE-NAME%/src/main/resources/mgnl-bootstrap/$MODULE-NAME%. Then, order the node in the
module VersionHandler:


package com.matteopelucco.setup;

import info.magnolia.module.DefaultModuleVersionHandler;
import info.magnolia.module.InstallContext;
import info.magnolia.module.delta.OrderNodeBeforeTask;
import info.magnolia.module.delta.Task;
import info.magnolia.repository.RepositoryConstants;

import java.util.List;

/**
 * This class is optional and lets you manager the versions of your module, by registering "deltas" to maintain the module's configuration, or other type of content. If you don't need this, simply
 * remove the reference to this class in the module descriptor xml.
 */
public class SampleModuleVersionHandler extends DefaultModuleVersionHandler {

  @Override
  protected List < Task > getBasicInstallTasks(InstallContext installContext) {

    List <task> basicInstallTasks = super.getBasicInstallTasks(installContext);
    basicInstallTasks.add(new OrderNodeBeforeTask("Log activation command ordering", "This task orders log command node before activate", RepositoryConstants.CONFIG,
	"/modules/workflow/commands/workflow/activate/log", "activate"));
    return basicInstallTasks;
  }
}
</task>

Just a note before ending: this is NOT a reccomended way to follow in everyday Magnolia workflow customization activities: JBPM editing is the right choice. But this approach allows to better understand what happen behind the scenes. And in some cases, can save your time for quick / one-shot customizations.

Latest articles

Matteo Pelucco Written by:

One Comment

  1. ana
    February 4

    Hi Matteo, Thanks for your articles on Magnolia. They are very helpful. -How is SampleModuleVersionHandler handled when I create a Maven package. Do I have to define it somehow in the POM or not? Best regards, Ana

Leave a Reply

Your email address will not be published. Required fields are marked *


7 − two =