EditorModel Events
The EditorModelEventManager
class is used to emit events that enable you to manipulate the model used by the backoffice before it is loaded into an editor. For example the SendingContentModel event fires right before a content item is loaded into the backoffice for editing. It is therefore the perfect event to use to set a default value for a particular property, or perhaps to hide a property/tab/Content App from a certain editor.
Usage
Example usage of the EditorModelEventManager
'SendingContentModel' event - eg set the default PublishDate for a new NewsArticle to be today's date:
using System;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Web.Editors;
using Umbraco.Web.Models.ContentEditing;
namespace My.Website
{
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class SubscribeToEditorModelEventsComposer : ComponentComposer<SubscribeToEditorModelEvents>
{
// This automatically adds the component to the Components collection of the Umbraco composition
}
public class SubscribeToEditorModelEvents : IComponent
{
// Initialize: runs once when Umbraco starts
public void Initialize()
{
EditorModelEventManager.SendingContentModel += EditorModelEventManager_SendingContentModel;
}
// Terminate: runs once when Umbraco stops
public void Terminate()
{
// Unsubscribe during shutdown
EditorModelEventManager.SendingContentModel -= EditorModelEventManager_SendingContentModel;
}
private void EditorModelEventManager_SendingContentModel(System.Web.Http.Filters.HttpActionExecutedContext sender, EditorModelEventArgs<Umbraco.Web.Models.ContentEditing.ContentItemDisplay> e)
{
// Set a default value for a NewsArticle's PublishDate property, the editor can override this, but we will suggest it should be today's date
if (e.Model.ContentTypeAlias == "newsArticle")
{
//access the property you want to pre-populate
//in V8 each content item can have 'variations' - each variation is represented by the `ContentVariantDisplay` class.
//if your site uses variants, then you need to decide whether to set the default value for all variants or a specific variant
// eg. set by variant name:
// var variant = e.Model.Variants.FirstOrDefault(f => f.Name == "specificVariantName");
// OR loop through all the variants:
foreach (var variant in e.Model.Variants){
//check if variant is a 'new variant' - we only want to set the default value when the content item is first created
if (variant.State == ContentSavedState.NotCreated){
// each variant has an IEnumerable of 'Tabs' (property groupings) and each of these contain an IEnumerable of `ContentPropertyDisplay` properties
var pubDateProperty = variant.Tabs.SelectMany(f => f.Properties).FirstOrDefault(f => f.Alias.InvariantEquals("publishDate"));
if (pubDateProperty!=null){
// set default value of the publish date property if it exists
pubDateProperty.Value = DateTime.UtcNow;
}
}
}
}
}
}
}
Another example could be to set the default Member Group for a specific Member Type using SendingMemberModel
:
public class SubscribeToEditorModelEvents : IComponent
{
private readonly IMemberGroupService _memberGroupService;
public SubscribeToEditorModelEvents(IMemberGroupService memberGroupService)
{
_memberGroupService = memberGroupService;
}
public void Initialize()
{
EditorModelEventManager.SendingMemberModel += EditorModelEventManager_SendingMemberModel;
}
public void Terminate()
{
EditorModelEventManager.SendingMemberModel -= EditorModelEventManager_SendingMemberModel;
}
private void EditorModelEventManager_SendingMemberModel(System.Web.Http.Filters.HttpActionExecutedContext sender, EditorModelEventArgs<Umbraco.Web.Models.ContentEditing.MemberDisplay> e)
{
bool isNew = !int.TryParse(e.Model.Id?.ToString(), out int id) || id == 0;
// We only want to set the default member group when the member is initially created, eg doesn't have an Id yet
if (isNew == false)
return;
// Set a default value member group for the member type `Member`
if (e.Model.ContentTypeAlias == "Member")
{
// Find a specific member group
var mg = _memberGroupService.GetByName("Customer");
if (mg == null)
return;
// Find member group property on member model
var prop = e.Model.Properties.FirstOrDefault(x => x.Alias == $"{Umbraco.Core.Constants.PropertyEditors.InternalGenericPropertiesPrefix}membergroup");
if (prop != null)
{
// Assign a default value for member group property
prop.Value = new Dictionary<string, object>
{
{ mg.Name, true }
};
}
}
}
}
Events
Event | Signature | Description |
---|---|---|
SendingContentModel | (HttpActionExecutedContext sender, EditorModelEventArgs<ContentItemDisplay> e) |
Raised right before the editor model is sent for editing in the content section NOTE: 'e' contains a model property of *Umbraco.Web.Models.ContentEditing.ContentItemDisplay* type which in turn contains the tabs and properties of the elements about to be loaded for editing |
SendingMediaModel | (HttpActionExecutedContext sender, EditorModelEventArgs<MediaItemDisplay> e) |
Raised right before the editor model is sent for editing in the media section NOTE: 'e' contains a model property of *Umbraco.Web.Models.ContentEditing.MediaItemDisplay* type which in turn contains the tabs and properties of the elements about to be loaded for editing |
SendingMemberModel | (HttpActionExecutedContext sender, EditorModelEventArgs<MemberDisplay> e) |
Raised right before the editor model is sent for editing in the member section. NOTE: 'e' contains a model property of *Umbraco.Web.Models.ContentEditing.MemberDisplay* type which in turn contains the tabs and properties of the elements about to be loaded for editing |
SendingUserModel | (HttpActionExecutedContext sender, EditorModelEventArgs<UserDisplay> e) |
Raised right before the editor model is sent for editing in the user section. NOTE: 'e' contains a model property of *Umbraco.Web.Models.ContentEditing.UserDisplay* type which in turn contains the tabs and properties of the elements about to be loaded for editing |
SendingDashboardModel | (HttpActionExecutedContext sender, EditorModelEventArgs<IEnumerable<Tab<IDashboardSlim>>> e) |
Raised right before the a dashboard is retrieved in a section. NOTE: 'e' contains a model property that is an IEnumerable of *Umbraco.Web.Models.ContentEditing.Tab |
EditorModelEventArgs
The EditorModelEventArgs class has two properties, one 'Model' representing the type of Model being sent, eg 'ContentItemDisplay' and an 'UmbracoContext' property representing the current context.
ContentItemDisplay
A model representing a content item to be displayed in the backoffice
- TemplateAlias
- Urls
- AllowPreview - Determines whether previewing is allowed for this node, By default this is true but by using events developers can toggle this off for certain documents if there is nothing to preview
- AllowedActions - The allowed 'actions' based on the user's permissions - Create, Update, Publish, Send to publish
- IsBlueprint
- Tabs - Defines the tabs containing display properties
- Properties - properties based on the properties in the tabs collection
MediaItemDisplay
A model representing a media item to be displayed in the backoffice
- Tabs - Defines the tabs containing display properties
- Properties - properties based on the properties in the tabs collection
MemberDisplay
A model representing a member to be displayed in the backoffice
- Username
- MembershipScenario
- MemberProviderFieldMapping - This is used to indicate how to map the membership provider properties to the save model, this mapping will change if a developer has opted to have custom member property aliases specified in their membership provider config, or if we are editing a member that is not an Umbraco member (custom provider)
- Tabs - Defines the tabs containing display properties
- Properties - properties based on the properties in the tabs collection
Samples
The events exposed by the EditorModelEventManager
class gives you a lot of options to customize the backoffice experience. You can find inspiration from the various samples provided below: