In this final installment of “Customizing the Sitefinity Content Admin” we’ll be going deep into Sitefinity’s Event Control system managed by what are called ‘Decorators’. This is pretty much for Developers only, however if you stick around until the end of the post I’ll be going over some exciting features that have come out / will be coming out since I started this series.
I’ve created/updated a content item, and I need it to DO something
It’s quite common that on creation of a content item in a CMS we need something to happen other than just publishing the piece.
- I’d like an email to be sent on publish
- I’d like to generate a page
- Update my remote CRM
Out of the box, this is seemingly impossible, but by overriding Sitefinity’s own individual ‘decorators’ we can manage these events. In this post I’ll show you how to implement and override your own decorator for a content item as well as fire off the aforementioned events.
If you haven’t done so already you may want to read part I and part II of the series before continuing.
The Lifecycle Decorator
To get started we need to implement a variation of our own ‘decorator’ by overriding the LifecycleDecorator class found wrapped in the Sitefinity DLL.
What it does
Sitefinity manages the various stages of a content item’s ‘life’ through this class, whether the item is being created as a draft, being published, being unpublished, or being deleted. Through this cycle we manipulate the data at various stages and trigger events as we please. There are many different methods and events we can override, so I suggest for developers to delve into the LifecycleDecorator class using JustDecompile, a very cool Telerik tool used to decompile DLLs and view the raw code of classes. It’s free (free!) and can be downloaded here. Any decompile tool will do, but this goes hand-and-hand nicely with other Telerik products including Sitefinity and DevCraft.
How to Implement
You can start by creating a class from scratch and have it inherit from the Lifecycle. For this example we’re are going to override Events in particular, so let’s go with naming it EventsDecorator. As you can see from the decompiled code, this requires two parametered constructors in order to satisfy the requirements of the interface. This is tricky (and somewhat unusual) but is necessary to carry out the two major functions of the decorator: delegate the various stages of the content item and to handle various actions.
The only variable that needs to change here is the name of your class. The following structure works fine for each Sitefinity content type:
Now that we’ve added our Decorator class we need to ‘register’ and override it in the global.asax. This file should already exist in your project, but if not you can create it from scratch and it will automatically fire from the base level of your project.
The specific method we will need to override to ‘register’ our decorator is the Boostrapper_Intialized event. Using the object factory we register and override the functionality of the baked-in decorator by injecting directly, as you can see below:
Inside this method we also set the type of ContentManager we’ll be utilizing; in this case the Events Manager. I also included a News Item decorator for example.
If we run the project our custom decorator will now handle all Event Content lifecycling and event handling. Since we haven’t changed anything, it will run and handle exactly like the original.
Methods to Note
While there are many exciting methods and events to override on a lifecyle decorator, we’re going to focus on the most important one, ‘Execute on Publish’. This handles the entire process of the content item on publish and garnishes the most availability to the item’s properties and current status. You’ll notice it carries a ‘MasterItem’ state and a ‘LiveItem’ state of the content item. We’ll go into more detail over the difference for the two, but generally the ‘MasterItem’ is the current state of the content item and the one we’ll be working with the most. This method can be implemented as follows:
If we were to debug this method we’ll see that this method fires on post-back of a content item publish, whether it’s brand new or being edited. From here we can create and transcribe various event methods which will handle any tasks we need to automatically fire.
Sending an Email
One of the most important tools for businesses is undoubtedly communication. When a new event is created we want to make sure people know about it! Whether it’s triggering a dynamic newsletter or even sending an internal message to an administrator, we can easily do this in our decorator.
To show this at its simplest functionality, let’s trigger a one-off email event to an administrator to notify them that an event has been added or edited.
Let’s start by adding a simple email method that passes the current Event object which is being published along with the LiveItem status. The LiveItem basically represents the content item as-is before the publish. Passing the IsPublished property will essentially tell us if this item was live before, meaning if it’s a newly published event or a live one that’s currently being updated. With that information we can send two different emails out: one for an updated event and one for a fresh one.
You can use whatever email system you’d like, but in this particular case we just used Sitefinity’s built in FormHelper.
Keep in mind, all validation has been completed for the event item about to be published so unless we have an error here in our custom code, the item will absolutely be published; ensuring the email will be a valid response.
Creating a page for our new content item
A very powerful ability the decorator provides us is the ability to create new pages outside of standard content detail pages. You may find that you want your very own urls and content for the newly created page, especially if you plan to automatically send emails directing users to the front-end of the site to view your event; complete with all the information, images, and specifics of your specified content.
I won’t go into strong detail on using the Sitefinity API to create pages, rather I’ll explain how it works from the decorator. More documentation about the page API can be found here.
So first we’ll create a method to fire inside of the Publish method:
We then utilize the Fluent API to pull in a page template and create the page based on our event details.
Notice most of the information drives from the event item itself. To top it off we redirect the admin user who published the page to the newly created page for further editing in the WYSIWYG (denoted by the “/action/edit”). This will give a smooth transition to the user as opposed to making them navigate to the new page manually.
Keep in mind there’s a lot more you can do in page creation like placing layouts and content widgets. You could do this directly after creating the page and utilizing ids from a formally created page template:
The possibilities for page creation are truly endless for maximizing administration work effort.
Working with Remote Services
In some cases its import to integrate Sitefinity and its content with other outside services like social media or a CRM. In this example I’ll show how we can call a third party CRM like Intellipad to record the event in its system and record an incoming id to the event itself.
Let’s start by making another method to handle the call to Intellipad:
In this case we expect to get an id back from Intellipad to signify the new record in its system. Ahead of time we created a custom field just for this called “IntellipadEventId”. If the id isn’t higher than ‘0’ we know something failed with the call.
As you can see we can create an event modeled after our own to record in Intellipad for future transactions:
*For demoing purposes we are grabbing a random user with last name “Christopher” to act as the user committing the transaction and has no real coding value in this demo.
After a DTO is mapped we can send it off to our IntellipadEvent API to be upserted. An Id will be returned to us which will be set on the Event itself before the base.ExecuteOnPublish method is called, ultimately saving the intellipad Id to the event. I recommend wrapping events like these in try-catches as third party calls may fail due to service outages or remote errors. We wouldn’t want to disrupt the publishing process.
Wrapping up the Lifecycle
Once your various method events have fired in your overridden ExecuteOnPublish method, the publish will complete as normal. What I showed was just a taste of complexity you can bring into the decorator; you can even fire off other decorators to match data across multiple content types. Be sure to thoroughly test your code before deploying first, however, as errant erroring could cause major issues if you or your client can’t properly publish the content items. On the other hand, Experimentation is highly recommended!
I hope you enjoyed and learned some techniques from this series focusing on the various ways you can customize the Sitefinity Content Admin.
When I started this series last year the current Sitefinity version was 7.5. With 9.0 on the horizon I thought I’d pass on some new features that have come out since that first post and those coming out in the near future to help customize your admin experience. Here are some links and descriptions that provide a little food-for-thought:
An engaging webinar that recently aired discussing a plethora of new features coming to Sitefinity 9, including Audience administration and a fresh admin UI:
An in-depth look at some of the new MVC widgets released in the last year, completed with new admin editors:
Another big change coming to Sitefinity, Continuous Delivery. This Blog post from Sitefinity talks about their new approach to site marketing and performance in the form of Digital Business Agility:
Much of this blog series focused on direct customization of content fields in the admin. With newer focus on MVC from Sitefinity, it’s even easier to implement and customize both fields and their widget designers: