DEV Community

Cover image for Server-side registering of Package Manifest in Umbraco 14
Søren Kottal
Søren Kottal

Posted on

Server-side registering of Package Manifest in Umbraco 14

Previously in Umbraco, if you had a package you wanted to register without including frontend files, you could add the package manifest as an IManifestFilter and append it to the manifest filter collection using an IComposer like this:

public class MyManifestFilter : IManifestFilter
{
    public void Filter(List<PackageManifest> manifests)
    {
        manifests.Add(new PackageManifest()
        {
            PackageName = "MyPackage"
        });
    }
}

public class MyComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.ManifestFilters().Append<ImageSharpRemoteImagesManifestFilter>();
    }
}

Enter fullscreen mode Exit fullscreen mode

This would register "MyPackage" as a package in the Umbraco installation. With the new backoffice, everything backoffice-related, including package registration, should be handled in the frontend only.

Umbraco 14 says it’s frontend only

In Umbraco 14, you now need to supply a static umbraco-package.json file in a folder inside the App_Plugins folder. This isn't a big deal, especially if your package also contains frontend components like property editors.

However, if your packages only contain backend code, you might not want to include static files.

Luckily, there's a new interface called IManifestReader, which reads and communicates all manifests in App_Plugins/*/umbraco-package.json to the backoffice. With some C#, you can use this interface to register your package in backend code.

Note: If your package has frontend components, you should register it with the JSON file approach. You won't gain anything by doing it in C#.

The interface must implement a method called ReadPackageManifestsAsync that returns a list of PackageManifests, similar to the old IManifestFilter.

Example: Registering "MyPackage" in code

Here's an example of how to register "MyPackage" in C# in Umbraco 14:

public class MyManifestReader : IManifestReader
{
    public async Task<IEnumerable<PackageManifest>> ReadPackageManifestsAsync()
    {
        return await Task.Run(() =>
        {
            return new List<PackageManifest>() {
                new PackageManifest()
                {
                    Name = "MyPackage",
                    Extensions = Array.Empty<object>()
                }
            };
        });
    }
}

public class MyComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.AddSingleton<IManifestReader, MyManifestReader>();
    }
}

Enter fullscreen mode Exit fullscreen mode

As you can see, it's similar to before, with the main difference being that Extensions is required. Extensions is the way you register all your frontend components, like dashboards, property editors etc. If your package is containing only backend code, you don’t have any extensions.

Using Package Manifests for Telemetry Data

Package manifests are also useful for showing up in Umbraco's telemetry data. If you set AllowTelemetry to true on your PackageManifest (AllowPackageTelemetry in the old IManifestFilter), data about the package will be included in Umbraco's telemetry data. This telemetry data is useful for getting an overview of which versions of Umbraco and packages are running in your projects.

I just released a package that does this

So if you want to register your package from C#, it's still possible. But if you have frontend assets in your package, you shouldn't need to do it.

By the way, one of my packages that registers this way has just been released for Umbraco 14:

Remote Image Provider for ImageSharp

Top comments (2)

Collapse
 
rsoeteman profile image
rsoeteman

This is awesome

Collapse
 
markusjoha profile image
Markus Johansson

This is a really great read! Thanks man! I can see a benefit for packages using client assets as well, with this approach you could probably control URLs and dynamically set a cache buster if needed?