Розробка кастомного пакету Umbraco

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка кастомного пакету Umbraco
Складна
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розробка користувацького пакета 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 тижні.