As I mentioned in one of my previous post the event system has been revised to me more modular and, probably more importantly, to be native .NET.
An event, an action from a user, triggers the event system which is one or more .NET classes which will act upon this event in some way. In versions of Tridion prior to 2011 the event system has been a single class which then leads to having to combine different event activity into the same piece of code. For instance, additional logging and workflow elements might have to be combined; this leads to unnecessary complexity in the code itself. It also means you cannot easily turn off (and on) part of the code.
In SDL Tridion 2011, this has changed (although you can still run older event systems) to allow you to hook into events using multiple separate event systems. As Bart Koopman explains in this article, when we hook into the events we concern ourselves with the phase of the event, the type of event and the object itself.
The phase relates to where in the event you are, for example, initiated, processed, committed etc. The type refers to the type of event, e.g. Publishing, BluePrint, or Data Modification events. Lastly our object (or in more familiar terms “item”) itself; our Component, Page, Schema etc. With these I can easily define that I would like to fire an event on a Component, when it is published and after that publish action has started.
Two more additional features are important. Firstly, it is quite possible that you have more than one event system hooked into the same event, so with the “Event Subscription Order” you can also specify the order in which your code is triggered (creating a event system stack). Secondly, you can also specify an event to run asynchronously rather than wait for code to complete before other code can continue (synchronously).
Event System Example
We need to do two simple things to get this to work:
1) Define out event system class
2) Configure SDL Tridion to load the event system and make it active
The Event System Class
We need to define our event system and this being .NET we can pretty much do anything we want from here, however, we need to at minimum hook (or rather subscribe) to an event.
Our event is going to log everything that happens to a Windows Event log called “Message Log”. We open our class and declare all the variables we need etc:
using System; using System.Diagnostics; using System.Threading; using Tridion.ContentManager; using Tridion.ContentManager.Extensibility; using Tridion.ContentManager.Extensibility.Events; namespace Tridion.Utilities. ExampleEventSystem { [TcmExtension("ExampleEventSystemEventHandlerExtension")] public class ExampleEventSystem : TcmExtension { #region Local Variables private static EventLog messageLog = new EventLog(); #endregion
In our constructor we will initialize out Windows Event Log and call our subscribe method:
public AuditLogger() { Init(); Subscribe(); }
Create the event log:
private static void Init() { if (!EventLog.SourceExists("TridionMessages")) { EventLog.CreateEventSource("TridionMessages ", "Message Log"); } messageLog.Source = " TridionMessages "; }
Subscribe to our events:
public void Subscribe() { EventSystem.Subscribe<IdentifiableObject, TcmEventArgs>( LogMessage, EventPhases.Processed); }
In this case I have used all “IdentifiableObject” which is everything, the method, LogMessage, that will called when the event fires and the phase is “processed”. The method signatures for subscribing are:
Subscribe<TSubject, TEvent>(TcmEventHandler<TSubject, TEvent> eventHandler, EventPhases phases, EventSubscriptionOrder order) SubscribeAsync<TSubject, TEvent>(TcmEventHandler<TSubject, TEvent> eventHandler, EventPhases phases, EventSubscriptionOrder order)
In our case we defined no subscription order so it will be “normal” order.
And finally define the method that will actually log our message:
private static void LogMessage(IdentifiableObject subject, TcmEventArgs args, EventPhases phase) { String message = "Session user: " + subject.Session.User.Title.ToString(); message = message + "\nTarget URI: " + subject.Id; message = message + "\nItem Type: " + subject.GetType().Name; message = message + "\nEvent: " + args.GetType().ToString(); message = message + "\nPhase: " + phase.ToString(); messageLog.WriteEntry(message, EventLogEntryType.Information, 0, 0); } } }
Configuring Tridion
To load our event system, we must load the class responsible. This we do in the Tridion.ContentManager.config which can be found under the %TRIDION_HOME%\config directory and we add a line to the extensions section to add our assembly:
<extensions> <add assemblyFileName="C:\myevevntsystem\messagelogger.dll"/> </extensions>
This is simply great!
Just waiting to get my hands on Tridion 2011!
Really? Aside from the actual dll, that’s “all” you need to register an extension with the CMS?
Not sure what I was waiting for… oh yeah, I’m still a TBB newbie. 😉
This post is very helpful.
I am trying to transform a page when it is published using a xsl definition.I was able to capture the page publish event,thanks to your post.Can you please help me with how to get the page and how to modify the published content in the event handler.