Automatic versioning of templates in Magnolia
Not so long ago Mark Halvorson mentioned in his presentation at the Magnolia Conference 2012 that he doesn't understand why he can't have versioning for templates in Magnolia the same way he has it for content. Then I thought why not? Should be pretty straightforward.
The first implementation was indeed easy. Similar to what Magnolia does when dealing with DMS documents - I just configured a custom save handler in the config:/modules/implace-templating/templatesEdit dialog that checks InplaceTemplatingModule.isVersionOnSave() in its postSave() method and if this value is set to true, it automatically creates a version. Job done I thought ... and in 5 minutes :) If I wanted to be nice, I could add the extra dialog - just like Magnolia does when invoking a workflow - or simply add the "comment" field in the templateEdit dialog. You can check the code at MGNLINTEMPL-21.
Only then did I remember that Mark mentioned that the Atlassian team doesn't edit their templates using the default dialog from Magnolia, but instead maps templates via WebDAV and accesses them as ordinary files.
No big deal, I thought. Instead of versioning templates in the postSave() method of the SaveHandler, I would configure an observer to automatically version the node once it is saved. Then the whole setup got a bit trickier. Magnolia also modifies content during versioning, to make the comment part of the versioned node, so whatever config I use needs to take care of it. Another complication was that when working with templates as with ordinary files, there is no extra field or extra dialog where I could stick the "comment" field.
To solve the first problem, I thought that all I had to do is set the RestrictToNodeTypeEventListener property to mgnl:content (template) node since the comment is stored in MetaData. If that worked, life would be too easy. RestrictToNodeTypeEventListener, contrary to its name, doesn't restrict observation to configured node types, but instead converts the path of the event to the parent node that is of configured node type or skips the event altogether if such a parent doesn't exist. While this behavior might be cool for other tasks, it was not what I was looking for here. So I ended up implementing another listener to take care of the issue. This other listener is now committed under MGNLOBS-16.
To take care of the second problem, I introduced a special command that will parse the template and look for whatever regex pattern is configured to extract the comment to be used for versioning. And you can also use a predefined template to fill such extracted comment in. Unfortunately, CommandEventListener is not flexible enough to use a command chain: only a single command can be specified as a parameter. To take care of this limitation I introduced commands under the inplace-templating module, built a command chain there, and in SpecifiedNodeTypeOnlyEventListener I now only set a delegate command that delegates to the appropriate command chain.
To see the code related to this second approach, look at MGNLINTEMPL-22.
To try it all at work, just get the latest snapshot of the inplace-templating module and deploy it on your Magnolia instance. You will also need the latest core module - 4.5.7-SNAPSHOT and of course make sure you also have the latest snapshot of the observation module installed.