How do you assign default values to a Content entity?

One of the first things you might notice when using the Content Hub, is an awesome and sleek design. But after a while, we all might notice a few cracks. Today I want to discuss the lack of assigning a default to a property or a relation. If have tried to first look into the schema, since there is where all the magic happens. But I couldn't find anything that relates to a default value. We can make it a required field, this ensures that the client will not forget to fill in the field. But that is only a half solution. Because you can't make any adjustments to system fields. Only an administrator is allowed to make that change. This is done with an important reason. It will ensure you won't screw up the environment too much ;).

So how can we assign a default value then? Well, let us take a moment to see what other options we've got. We could always check the pages, but unfortunately, they also don't allow us to set a default value. The other option was to try and solve this through code. What about using a trigger on entity creation and then have a script being executed. If the field was left empty by the client, fill it with a default value. This could work I though. And indeed after a small puzzle, I connected the dots and now have it working. 

For this example, I used the M.Content definition. By default the Localization relation is not a required field, nor can we make changes to it. Because it's a system relation within the schema. A perfect example to fill it with a default value.

For this to work we're going to need a couple of things:

  • Trigger, to be activated when a new entity is created of M.Content
  • Action, to be activated by the trigger and executed it's action
  • Script, to be activated by the action and sets the default value of the Localization relation if not already filled in.
If you look at the above three things we need, you really tend to do this from trigger, to action, to script. But I prefer to do it the other way around. The main reason why I do this is that you need a script for an action and an action for a trigger. So why not start with the script?

Go to your Content Hub instance, to Manage and then to Script. Create a new script. Make sure to give it a descriptive name. Always make sure to think of this before writing your script. It should be very clear by its name what it's doing. I've chosen for "CMP - M.Content - Set default localization value". When you're finished writing a script or adjusting it, always make sure to look at the name and description. If they don't tell the whole story, update them! Then, set the Type to Action and finish by adding a proper description for the Script. Your colleagues will thank you later when you do. When finished, click on Create.

For the Script, we are going to set the Localization relation to English. Below you'll find the complete script that you'll need for this to do.

const string EnglishLocalizationIdentifier = "M.Localization.enEN";

var contentId = Context.TargetId;
if (!contentId.HasValue)
{
MClient.Logger.Debug("The TargetId was empty. Abort process");
return;
}

var entityId = contentId.Value;

// configure loading profile
var contentLoadConfiguration = new EntityLoadConfiguration(
CultureLoadOption.None,
PropertyLoadOption.None,
new RelationLoadOption("LocalizationToContent"));

// load entity based on loading profile
IEntity contentEntity = await MClient.Entities.GetAsync(entityId, contentLoadConfiguration);
if (contentEntity == null)
{
MClient.Logger.Debug($"Could not load entity with id {entityId}. Abort process");
return;
}

IChildToOneParentRelation localizationRelation = contentEntity.GetRelation<IChildToOneParentRelation>("LocalizationToContent");
if (localizationRelation.Parent != null && localizationRelation.Parent.HasValue)
{
MClient.Logger.Debug($"Entity {entityId} already has a localization. Abort process");
return;
}

var englishEntity = await MClient.Entities.GetAsync(EnglishLocalizationIdentifier, EntityLoadConfiguration.Minimal);
if (englishEntity == null)
{
throw new InvalidOperationException("Could not load default English language...");
}

// set localization to default English
localizationRelation.SetId(englishEntity.Id);
await MClient.Entities.SaveAsync(contentEntity);

When copy / pasting in the script, make sure to enable Minimum log level. This will help you to verify that the script is working properly and if there are any errors. Press Build to start building the script and wait for it to succeed. Then click on Publish to activate the Script.

Now that we have the script we can create an Action for it. Go to the management portal and open up the Actions section. Click on New action. Also give this action a proper name, for this example, I've named it "CMP - M.Content - Set default localization value". Set the Type to Action and select your just created script. Hit Save when finished.

Last but not least, we should hook it up to a trigger. Go to the Triggers section in the Management portal. Click on New trigger to create a new one. Once more, assign a proper name and description. For the objective, select Entity creation. Setting up this way, make sure our trigger is activated when a new Content entity is created and only then. We don't want to override the default value if a client has cleared out the field. For the execution type, we want to select In process. We want to finish setting the default value before anyone can make changes to this.

Continue to the Conditions tab. Make sure to create a match on the content definition M.Content. The last thing we need to do is select the action we want to execute and also important when do we want to execute this. Add your action within the Post actions section. This will ensure the entity is created before our script is run.

Hit save and verify if all is working by creating a new Content entity. If as goes well, you will see that your newly created Content entity has set Localization to English.

Happy codin'! Until next time.