Розробка користувацького пакета Umbraco
Пакет Umbraco — це NuGet-пакет, який розширює CMS: додає нові типи властивостей, дашборди, секції backoffice, Composers, міграції, API-ендпоїнти. Розповсюджується через NuGet або Our.Umbraco.Org. Архітектурно це звичайна бібліотека .NET з реєстрацією через Composer-паттерн.
Структура пакета
MyPackage/
├── MyPackage.Core/
│ ├── Composers/
│ │ └── MyPackageComposer.cs
│ ├── Services/
│ │ ├── IMyService.cs
│ │ └── MyService.cs
│ ├── Models/
│ ├── Migrations/
│ │ └── AddMyTableMigration.cs
│ ├── NotificationHandlers/
│ └── MyPackage.Core.csproj
├── MyPackage.StaticAssets/
│ ├── App_Plugins/
│ │ └── MyPackage/
│ │ ├── my-property-editor.js
│ │ ├── my-dashboard.js
│ │ └── package.manifest
│ └── MyPackage.StaticAssets.csproj
└── MyPackage.sln
Composer — точка входу
// Composers/MyPackageComposer.cs
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Migrations;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
[assembly: ComposeAfter(typeof(ICoreComposer))]
public class MyPackageComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
// реєстрація сервісів
builder.Services.AddSingleton<IMyService, MyService>();
// реєстрація обробників подій
builder.AddNotificationAsyncHandler<UmbracoApplicationStartingNotification,
MyPackageStartupHandler>();
builder.AddNotificationHandler<ContentPublishedNotification,
ContentPublishedHandler>();
// реєстрація міграцій
builder.AddNotificationAsyncHandler<UmbracoApplicationStartingNotification,
RunPackageMigrationsHandler>();
// реєстрація типу властивості
builder.PropertyEditors()
.Add<MyCustomPropertyEditor>();
}
}
Міграція бази даних
// Migrations/AddMyTableMigration.cs
using Umbraco.Cms.Infrastructure.Migrations;
public class AddMyTableMigration : MigrationBase
{
public AddMyTableMigration(IMigrationContext context) : base(context) { }
protected override void Migrate()
{
if (!TableExists("MyPackageData"))
{
Create.Table<MyPackageDataDto>().Do();
}
else
{
// ідемпотентне додавання колонки
if (!ColumnExists("MyPackageData", "ExtraField"))
{
Alter.Table("MyPackageData")
.AddColumn("ExtraField")
.AsString(512)
.Nullable()
.Do();
}
}
}
}
[TableName("MyPackageData")]
[PrimaryKey("Id", AutoIncrement = true)]
public class MyPackageDataDto
{
[Column("Id")]
public int Id { get; set; }
[Column("ContentId")]
public int ContentId { get; set; }
[Column("Data")]
[NullSetting(NullSetting = NullSettings.Null)]
public string? Data { get; set; }
[Column("CreatedAt")]
public DateTime CreatedAt { get; set; }
}
// Запуск міграцій при старті
public class RunPackageMigrationsHandler
: INotificationAsyncHandler<UmbracoApplicationStartingNotification>
{
private readonly IMigrationPlanExecutor _migrationPlanExecutor;
private readonly ICoreScopeProvider _scopeProvider;
private readonly IKeyValueService _keyValueService;
private readonly IRuntimeState _runtimeState;
// ... конструктор
public async Task HandleAsync(
UmbracoApplicationStartingNotification notification,
CancellationToken ct)
{
if (_runtimeState.Level < RuntimeLevel.Run) return;
var plan = new MigrationPlan("MyPackage")
.From(string.Empty)
.To<AddMyTableMigration>("v1.0.0");
using var scope = _scopeProvider.CreateCoreScope();
var upgrader = new Upgrader(plan);
upgrader.Execute(_migrationPlanExecutor, _scopeProvider, _keyValueService);
scope.Complete();
await Task.CompletedTask;
}
}
NuGet-пакет
<!-- MyPackage.Core.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<PackageId>MyCompany.UmbracoMyPackage</PackageId>
<Version>1.0.0</Version>
<Authors>MyCompany</Authors>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<Description>Custom package for Umbraco 13+</Description>
<PackageTags>umbraco;cms;plugin</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Umbraco.Cms.Core" Version="13.*" />
</ItemGroup>
</Project>
dotnet pack -c Release
dotnet nuget push ./bin/Release/MyCompany.UmbracoMyPackage.1.0.0.nupkg \
--source https://api.nuget.org/v3/index.json \
--api-key $NUGET_API_KEY
Терміни розробки
Простий пакет (сервіс + Composer + міграція): 3–5 днів. Пакет з користувацьким типом властивості, дашбордом та API-контролером: 1–2 тижні. Складний пакет з користувацьким розділом панелі, зовнішнім API та кешуванням: 3–4 тижні.







