Skip to content

BlockPreview + ModelsBuilder Plan

Date: 2026-02-26 Status: PLANNED Priority: Post-migration refactoring (after migration tool + frontend done) Depends on: Migration tool working correctly, all views created


Goal

Install Umbraco.Community.BlockPreview (v5.2.1) for backoffice block previews. This requires strongly-typed ModelsBuilder models compiled into the application.


Current State

Setting Value
Production ModelsMode Nothing (appsettings.json)
Development ModelsMode SourceCodeManual (appsettings.Development.json)
Configured Namespace dbl.Progress.umbracoModels
Models Directory src/www/umbraco/models/ (default)
Generated Models NONE — generation failed due to corrupt DataType 1816 (MediaPicker3)
BlockPreview installed No

Architecture Decision: Where Do Models Live?

src/Progress.Baseline.Core/
├── Adapters/           # existing
├── Extensions/         # existing
├── Interfaces/         # existing
├── Services/           # existing
└── Models/             # NEW — ModelsBuilder output
    ├── Home.generated.cs
    ├── StandardPage.generated.cs
    ├── ... (455+ element types + document types)
    └── _ModelsBuilderNote.txt

Pros: - Already has Umbraco dependency - Already referenced by www - Models available to services (ISiteSettingsService could use typed models) - No new project needed

Cons: - 455+ generated files adds bulk to the core library - Core library purpose shifts from "services" to "services + models"

Option B: Dedicated Progress.Umbraco.Models Project

src/Progress.Umbraco.Models/
├── Progress.Umbraco.Models.csproj
└── Models/
    ├── Home.generated.cs
    └── ...

Pros: - Clean separation - Clear single responsibility - Can be referenced independently

Cons: - One more project in solution - Extra DI wiring

Recommendation: Option A (Progress.Baseline.Core)

The user's future goal is NuGet RCL packaging — at that point, models become part of the shared baseline package. Putting them in Core now aligns with that direction.


Implementation Steps

Step 1: Fix DataType 1816 (MediaPicker3)

The ModelsBuilder currently fails because DT 1816 has invalid configuration.

Failed to build models.
The configuration for data type 1816 : Umbraco.MediaPicker3 is invalid

Action: After running a fresh migration, check the backoffice for DT 1816 and fix or recreate its configuration.

Step 2: Configure ModelsBuilder

Update appsettings.Development.json:

{
  "Umbraco": {
    "CMS": {
      "ModelsBuilder": {
        "ModelsMode": "SourceCodeManual",
        "ModelsNamespace": "Progress.Baseline.Core.Models",
        "ModelsDirectory": "~/../Progress.Baseline.Core/Models",
        "AcceptUnsafeModelsDirectory": true
      }
    }
  }
}

Key settings: - SourceCodeManual — generate on demand from backoffice dashboard - ~/../Progress.Baseline.Core/Models — generates into the class library (~ = www content root) - AcceptUnsafeModelsDirectory: true — required when output is outside web root - Production stays ModelsMode: "Nothing" — models are compiled from committed source

Step 3: Generate Models

  1. Run the site locally in Development mode
  2. Navigate to Settings → Models Builder in backoffice
  3. Click "Generate Models"
  4. Verify 455+ .generated.cs files appear in src/Progress.Baseline.Core/Models/
  5. Build solution — fix any compilation errors

Step 4: Update _ViewImports.cshtml

- @using Umbraco.Cms.Web.Common.PublishedModels
+ @using Progress.Baseline.Core.Models

Step 5: Install BlockPreview

dotnet add src/www/www.csproj package Umbraco.Community.BlockPreview --version 5.2.1

Step 6: Register BlockPreview in Program.cs

builder.CreateUmbracoBuilder()
    .AddBackOffice()
    .AddWebsite()
    .AddBlockPreview(options =>
    {
        options.EnableBlockGridPreview = true;
        options.EnableBlockListPreview = true;
    })
    .AddDeliveryApi()
    .AddComposers()
    .Build();

Step 7: Add Preview-Aware Logic to Views (optional)

For views that need different rendering in backoffice vs frontend:

@using Umbraco.Community.BlockPreview.Extensions

@if (Context.Request.IsBlockPreviewRequest())
{
    <!-- Simplified preview rendering -->
}
else
{
    <!-- Full frontend rendering with JS, animations, etc. -->
}

Step 8: Verify

  1. Build solution — 0 errors
  2. Run site
  3. Edit a page with BlockGrid/BlockList in backoffice
  4. Verify block previews render correctly

Impact Assessment

Views Impact

All existing views continue to work as-is. ModelsBuilder models are additive — they extend IPublishedContent with strongly-typed properties but don't break string-based Model.Value<T>("alias") calls.

Optionally, views can be refactored from:

var title = content.Value<string>("title") ?? "";
To:
var typedContent = (MyElementType)content;
var title = typedContent.Title ?? "";

This refactoring is optional and can be done incrementally.

Build Impact

  • 455+ new .cs files in Progress.Baseline.Core
  • Increased build time (~5-10 seconds)
  • Models must be regenerated when content types change in backoffice

Workflow Change

Developers must: 1. Make content type changes in backoffice 2. Click "Generate Models" in Settings → Models Builder 3. Rebuild solution 4. Commit updated model files


Effort Estimate

Task Effort
Fix DT 1816 0.5 day
Configure + generate models 0.5 day
Install + configure BlockPreview 0.5 day
Test all block types preview 1 day
Fix preview-specific rendering issues 1-2 days
Total ~3-4.5 days

Dependencies

  • Migration tool must be producing correct data (DT 1816 fix)
  • All component views must exist (Phase 4 of REVISED_PLAN)
  • Site must run successfully before adding BlockPreview
Migration documentation by Double for Progress Credit Union