February 19, 2024 / 2 minutes

Package: Relations Manager

A powerful Backoffice extension for managing Umbraco relations

Umbraco Relation Types are Amazing

Umbraco Relations allow you to relate almost any object in Umbraco to almost any other Umbraco object - under a defined Relation Type.

Often forgotten about, this feature allows us to relate Umbraco entities such as content, media and members in a light-weight manner.

On the surface this may not sound like anything ground-breaking but this empowers developers to implement bespoke functionality that can deliver meaningful business value.

A basic example

Suppose I have an Article document type with an Author content picker.

For any given Article I can easily get the Author by doing something like this:

var author = Model.Author

But what if I want to get all the Articles associated to an Author?

  • Iterate over all Article published content to get a list of all authors
    • This is inefficient and could cause performance issues
  • Use Examine to query the external index
    • Requires a lot of boilerplate code
  • Directly query the database for property data
    • Let's not go there...

Or, use Relation Types!

The (not-so-best-practice) code example below shows how you use the relation service upon content published to relate an Author Id to Article. You will also need to ensure a Relation Type with an alias of authorToArticle in order for the relation service to create the relation.

    public class Handler(IUmbracoContextFactory umbracoContextFactory, IRelationService relationService) : INotificationHandler
{
    public void Handle(ContentPublishedNotification notification)
    {
        using var umbracoContext = umbracoContextFactory.EnsureUmbracoContext().UmbracoContext;
        foreach (var content in notification.PublishedEntities.Where(x => x.ContentType.Alias == Article.ModelTypeAlias))
        {
            if (umbracoContext.Content?.GetById(content.Id) is Article article)
            {
                relationService.Relate(article.Author.Id, article.Id, "authorToArticle");
            }
        }
    }
}

Now it's super easy to get all Articles by Author! Despite making a direct database call, this method is extremely quick as it queries the simple umbracoRelations database table.

    public class AuthorService(IRelationService relationService)
{
    public IEnumerable? GetArticlesIds(int authorId) => relationService.GetByParentId(authorId, "authorToArticle")?.Select(x => x.ChildId);
}

Not everything is perfect.

If you're using the out of the box relation types or have defined your own, you've probably come to realise that you can't add or delete relations via the Backoffice.

I've released a package called Relations Manager, available on the Umbraco marketplace (also in the Packages tab within the Backoffice).

Now you can finally view, create and delete relations all in one section within the Backoffice!

Relations Manager

Create and manage relations for any Umbraco Relation Type directly from the Backoffice.

Learn more
💖