Previously we have looked at what Razor class libraries are and how you can use them to build new Umbraco packages, Now we are going to go over the steps you can take to convert an existing Umbraco package to use Razor class libraries :
This post is part of a series:
- Part 1: Intro to Razor class library packages in Umbraco
- Part 2: Creating an Umbraco Razor class library package
- Part 3: Converting an existing Umbraco package (this)
- Part 4: Things I now do differently 🌟 New 🌟
1. Convert your csproj file.
First thing we need to do is convert our project from an 'standard' c# library to a razor class library project.
change :
<Project Sdk="Microsoft.NET.Sdk">
to :
<Project Sdk="Microsoft.NET.Sdk.Razor">
2. Add A StaticWebAssetsBasePath value
By default all Razor Class library files will be served into the root of wwwroot
folder of your project - but the StaticWebAssetBasePath
value in the csproj file lets you change this to something more like what Umbraco expects for a package.
<StaticWebAssetBasePath>App_Plugins/MyPackage</StaticWebAssetBasePath>
3. Remove the build .targets from the project
Using a RCL you no longer need the .targets file that forms part of how packages work in Umbraco so you can:
- delete the build folder from your solutions
- remove the 'build' elements from the csproj file.
When you are done with the .csproj file it should look something like this :
4. Rename your existing app_plugins/myproject
folder
While Razor class library assets can be made to look like they are not in the root of wwwroot. The files themselves must be in a wwwroot frolder of the library. So we need to rename/move our folder
Files should be moved from /app_pluigns/mysuperproject
to /wwwroot
inside your package project
5. Load the package.manifest in code
One last thing we have to do is tell umbraco how to load the package.manifest
.
Soon 🤞 we should get something Umbraco codebase that means
package.manifest
files will be picked up by Umbraco and we won't need to do either of the methods below - but as of v10.0.0 of Umbraco you have to do this
At the moment - You need to programmatically load the package via a Manifest filter. We covered this in part 1 but to quickly go over it here.
Method 1 - define the package manifest in code
you need a to load your package manifest via a composer: and you can define it all in code if that is easier for you:
public class StyledTextComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.ManifestFilters().Append<MyManifestFilter>();
}
}
internal class MyManifestFilter: IManifestFilter
{
public void Filter(List<PackageManifest> manifests)
{
manifests.Add(new PackageManifest
{
PackageName = "MyPackage",
Scripts = new []
{
"/App_Plugins/MyPackage/my.controller.js"
},
Stylesheets = new []
{
"/App_Plugins/MyPackage/mystyles.css"
}
});
}
}
Method 2 - load an embedded package.manifest file
Jason Elkin did most of the work here (and above) - but if you want (and this is easier for more complex package.manifest files with property editors and default values in them) - You can embedd your package manifest as a resource in your project and then load it in and use the existing package parsers in Umbraco to load it.
You can see how Jason has done this in his repo here:
https://github.com/JasonElkin/Umbraco-Together-RCL-Demo-Package/tree/main/src/FontAwesome5Picker/Startup
the clever bit (well its all quite clever!) is reading the resource :
using System.IO;
using System.Reflection;
namespace FontAwesome5Picker.Startup
{
public class ManifestReader
{
public static string ReadManifest()
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "package.manifest";
using Stream stream = assembly.GetManifestResourceStream(resourceName);
using StreamReader reader = new(stream);
string result = reader.ReadToEnd();
return result;
}
}
}
and passing it into the parser :
using System.Collections.Generic;
using Umbraco.Cms.Core.Manifest;
namespace FontAwesome5Picker.Startup
{
public class ManifestFilter : IManifestFilter
{
private readonly IManifestParser parser;
public ManifestFilter(IManifestParser parser)
{
this.parser = parser;
}
void IManifestFilter.Filter(List<PackageManifest> manifests)
{
var manifestJson = ManifestReader.ReadManifest();
var manifest = parser.ParseManifest(manifestJson);
manifest.PackageName = "Font Awesome 5 Picker";
manifests.Add(manifest);
}
}
}
Top comments (0)