Skip to content

Report 23: Partials & Layout Comparison (v8 vs v17)

Generated: 2026-02-27 Scope: SiteLayout, BlockList, Forms, shared content partials, cookies, help, privacy, social, termsConditions, login, MacroPartials, Home, Notifications


1. Overview

Category v8 Count v17 Count Status
SiteLayout/ 20 18 2 removed (obsolete)
BlockList/components/ 5 6 1 added (googleMap, headerFull)
BlockList/root 1 (Default.cshtml) 1 (default.cshtml) Migrated
Root Partials 9 8 1 removed (OpeningTimes)
cookies/ 1 1 Migrated
Help/ 2 1 1 removed
privacy/ 2 2 Migrated
social/ 2 1 1 removed (Instagram)
termsConditions/ 1 1 Migrated
termsConditionsMobile/ 1 1 Migrated
Home/ 6 6 Migrated
Notifications/ 2 2 Migrated
MacroPartials/ 9 0 ALL OBSOLETE
Forms/ 79 13 66 removed (built-in defaults in v17)
Grid/ 11+ editors N/A Replaced by blockgrid/
LoginStatus/ N/A (MacroPartial) 1 Moved from MacroPartials
TOTAL ~171 ~62 ~64% reduction

The dramatic reduction is primarily from:

  1. MacroPartials (9 files) -- macros are removed from Umbraco v17 entirely
  2. Forms (66 files removed) -- Umbraco Forms v17 ships with built-in defaults for Emails, Fieldtypes, Export, and the default theme; only custom themes and custom field types need to be kept
  3. Grid/ (11 files) -- replaced entirely by blockgrid/ with component-per-element architecture

2. Side-by-Side: SiteLayout/header.cshtml

This is the primary site header partial. It demonstrates the core migration patterns.

v8 (psCreditUnion/Progress.Web/Views/Partials/SiteLayout/header.cshtml)

@inherits UmbracoViewPage
@using Umbraco.Core.Services

@{
    // XPath queries to global content nodes
    var imageSettings = Umbraco.ContentSingleAtXPath("//siteStyleConfiguration")
        as SiteStyleConfiguration;
    var menuSettings = Umbraco.ContentSingleAtXPath("//menuConfiguration")
        as MenuConfiguration;

    var logo = "";
    var altText = "";
    if (imageSettings.Logo != null)
    {
        logo = imageSettings.Logo.Url();
        altText = imageSettings.Logo.Value<string>("altText");
    }

    var backgroundCssColour = menuSettings.BackgroundCssColour;
    var style = "";
    var styleblock = "";
    if (menuSettings.FloatingMenu)
    {
        style = "float";
        styleblock = "style='display: block'";
    }

    var hideSocialLinks = menuSettings.HideSocialLinks;

    // Domain-based home route
    var homeRoute = UmbracoContext.PublishedRequest.HasDomain
        ? UmbracoContext.PublishedRequest.Domain.Name
        : "/";
}

<header>
    <nav id="navigation1" class="navigation @style @backgroundCssColour" @styleblock>
        ...
        @Html.CachedPartial("SiteLayout/navigationDynamic", Model, 3600, false)
        @Html.CachedPartial("~/Views/Partials/SiteLayout/headerSocialLinks.cshtml",
            Model, 3600, false)
        ...
        @Html.Partial("sitelayout/headerSearch")
    </nav>
</header>

v17 (dbl.Progress/src/www/Views/Partials/SiteLayout/header.cshtml)

@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@inject ISiteSettingsService SiteSettings
@using Umbraco.Cms.Core.Routing
@inject IPublishedUrlProvider UrlProvider

@{
    // DI-injected service replaces XPath queries
    var imageSettings = SiteSettings.Styles;
    var menuSettings = SiteSettings.Menu;

    var logo = "";
    var altText = "";
    if (imageSettings?.Logo != null)  // null-safe
    {
        logo = imageSettings.Logo.Url();
        altText = imageSettings.Logo.Value<string>("altText");
    }

    var backgroundCssColour = menuSettings?.BackgroundCssColour;
    var style = "";
    var styleblock = "";
    if (menuSettings?.FloatingMenu ?? false)  // null-coalescing
    {
        style = "float";
        // Bug fix: original code produced invalid HTML; removed
    }

    var hideSocialLinks = menuSettings?.HideSocialLinks ?? false;

    // Simplified home route using content tree
    var homeRoute = Model.Root()?.Url() ?? "/";
}

<header>
    <nav id="navigation1" class="navigation @style @backgroundCssColour" @styleblock>
        ...
        @await Html.CachedPartialAsync("SiteLayout/navigationDynamic", Model,
            TimeSpan.FromHours(1), cacheByPage: false)
        @await Html.CachedPartialAsync("SiteLayout/headerSocialLinks", Model,
            TimeSpan.FromHours(1), cacheByPage: false)
        ...
        @await Html.PartialAsync("SiteLayout/headerSearch", Model)
    </nav>
</header>

Key Migration Patterns Demonstrated

Pattern v8 v17
Base class @inherits UmbracoViewPage @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
Settings access Umbraco.ContentSingleAtXPath("//...") @inject ISiteSettingsService
Null safety Direct property access ?. and ?? default
Caching Html.CachedPartial(..., 3600, false) Html.CachedPartialAsync(..., TimeSpan.FromHours(1), cacheByPage: false)
Partial rendering Html.Partial(...) @await Html.PartialAsync(...)
Home URL UmbracoContext.PublishedRequest.Domain Model.Root()?.Url()
Path references ~/Views/Partials/SiteLayout/...cshtml Short name SiteLayout/...

3. Side-by-Side: Forms/Themes/General/Form.cshtml

This is a custom Forms theme used for standard contact forms.

v8

@inherits WebViewPage<Umbraco.Forms.Web.Models.FormViewModel>
@using Umbraco.Forms.Core.Enums
@using Umbraco.Forms.Mvc
@using Umbraco.Forms.Mvc.Models
@using Umbraco.Forms.Mvc.BusinessLogic

@Html.SetFormFieldClass("form-control")
@Html.SetFormFieldWrapperClass("form-group")

<div class="umbraco-forms-general umbraco-forms-page form-horizontal"
     id="@Model.CurrentPage.Id">
    ...
    @foreach (FieldViewModel f in c.Fields)
    {
        bool hidden = f.HasCondition
            && f.ConditionActionType == FieldConditionActionType.Show;

        <div class="@Html.GetFormFieldWrapperClass(f.FieldTypeName) @f.CssClass"
             @{ if (hidden) { <text> style="display: none" </text> } }>
            ...
            @Html.Partial(FormThemeResolver.GetFieldView(Model, f), f)
            ...
        </div>
    }
    ...
    @Html.Partial("Forms/Themes/default/ScrollToFormScript")
    @Html.Partial("Forms/Themes/default/psUmbracoFormsScript")
</div>

v17

@using Umbraco.Forms.Core.Enums
@using Umbraco.Forms.Web
@using Umbraco.Forms.Web.Models
@using Umbraco.Forms.Web.Services
@model Umbraco.Forms.Web.Models.FormViewModel

@inject IFormThemeResolver FormThemeResolver

@Html.SetFormFieldClass("form-control")
@Html.SetFormFieldWrapperClass("mb-3")  // Bootstrap 5: form-group -> mb-3

<div class="umbraco-forms-general umbraco-forms-page form-horizontal"
     id="@Model.CurrentPage.Id">
    ...
    @foreach (FieldViewModel f in c.Fields)
    {
        bool hidden = f.HasCondition
            && f.ConditionActionType == FieldConditionActionType.Show;

        <div class="@Html.GetFormFieldWrapperClass(f.FieldTypeName) @f.CssClass"
             @(hidden ? "style=display:none" : "")>
            ...
            @await Html.PartialAsync(FormThemeResolver.GetFieldView(Model, f), f)
            ...
        </div>
    }
    ...
    @await Html.PartialAsync("Forms/Themes/default/ScrollToFormScript", Model)
    @await Html.PartialAsync("Forms/Themes/default/psUmbracoFormsScript", Model)
</div>

Key Forms Migration Patterns

Pattern v8 v17
Model declaration @inherits WebViewPage<FormViewModel> @model FormViewModel
Namespaces Umbraco.Forms.Mvc, Umbraco.Forms.Mvc.BusinessLogic Umbraco.Forms.Web, Umbraco.Forms.Web.Services
Theme resolver Static FormThemeResolver.GetFieldView(...) @inject IFormThemeResolver + DI
Wrapper class form-group (Bootstrap 4) mb-3 (Bootstrap 5)
Hidden attribute Razor @{ if (hidden) { <text>...</text> } } @(hidden ? "style=display:none" : "")
Partial rendering Html.Partial(...) @await Html.PartialAsync(...)

4. File Mapping Tables by Subdirectory

4.1 SiteLayout (20 v8 / 18 v17)

v8 File v17 File Status
header.cshtml header.cshtml Migrated -- DI injection, async partials
footer.cshtml footer.cshtml Migrated
TopBar.cshtml TopBar.cshtml Migrated
LoginButtons.cshtml LoginButtons.cshtml Migrated
headerMenu2.cshtml headerMenu2.cshtml Migrated
headerMenu3.cshtml headerMenu3.cshtml Migrated
headerMenu4.cshtml headerMenu4.cshtml Migrated
headerSearch.cshtml headerSearch.cshtml Migrated
headerSocialLinks.cshtml headerSocialLinks.cshtml Migrated
navigationDynamic.cshtml navigationDynamic.cshtml Migrated
navigationDynamicMenu2.cshtml navigationDynamicMenu2.cshtml Migrated
navigationDynamicMenu2ButtonDropdown.cshtml navigationDynamicMenu2ButtonDropdown.cshtml Migrated
navigationDynamicMenu2CallUs.cshtml navigationDynamicMenu2CallUs.cshtml Migrated
navigationDynamicMenu2LoginButtons.cshtml navigationDynamicMenu2LoginButtons.cshtml Migrated
navigationDynamicMenu2SocialLinks.cshtml navigationDynamicMenu2SocialLinks.cshtml Migrated
navigationDynamicMenu2TopBarLinks.cshtml navigationDynamicMenu2TopBarLinks.cshtml Migrated
navigationDynamicMenu4.cshtml navigationDynamicMenu4.cshtml Migrated
seo.cshtml SEO.cshtml Migrated (case change)
navigation.cshtml -- REMOVED -- superseded by navigationDynamic.cshtml
navigationDynamicMenu2Search.cshtml -- REMOVED -- search merged into headerSearch.cshtml

4.2 BlockList (6 v8 / 7 v17)

v8 File v17 File Status
Default.cshtml default.cshtml Migrated (case change)
components/header.cshtml Components/header.cshtml Migrated
components/headerContact.cshtml Components/headerContact.cshtml Migrated
components/headerNew.cshtml Components/headerNew.cshtml Migrated
components/headerNews.cshtml Components/headerNews.cshtml Migrated
components/blockListCallToAction.cshtml Components/blockListCallToAction.cshtml Migrated
-- Components/googleMap.cshtml NEW in v17
-- Components/headerFull.cshtml NEW in v17

4.3 Root Partials (9 v8 / 8 v17)

v8 File v17 File Status
ArticleContent.cshtml ArticleContent.cshtml Migrated
ArticleContentType2.cshtml ArticleContentType2.cshtml Migrated
LatestArticles.cshtml LatestArticles.cshtml Migrated
LatestArticlesPaging.cshtml LatestArticlesPaging.cshtml Migrated
LatestGalleries.cshtml LatestGalleries.cshtml Migrated
NewsGlobalCTA.cshtml NewsGlobalCTA.cshtml Migrated
RelatedArticles.cshtml RelatedArticles.cshtml Migrated
RelatedArticlesType2.cshtml RelatedArticlesType2.cshtml Migrated
shareButtons.cshtml shareButtons.cshtml Migrated
OpeningTimes.cshtml -- REMOVED -- functionality moved to blockgrid component

4.4 cookies/

v8 File v17 File Status
_main.cshtml _main.cshtml Migrated

4.5 Help/

v8 File v17 File Status
_main.cshtml _main.cshtml Migrated
_subarticle.cshtml -- REMOVED -- content consolidated into _main.cshtml

4.6 privacy/

v8 File v17 File Status
_main.cshtml _main.cshtml Migrated
_subMenu.cshtml _subMenu.cshtml Migrated

4.7 social/

v8 File v17 File Status
_twitter.cshtml _twitter.cshtml Migrated
_instagram.cshtml -- REMOVED -- Instagram API deprecated; embed approach changed

4.8 termsConditions/

v8 File v17 File Status
_main.cshtml _main.cshtml Migrated

4.9 termsConditionsMobile/

v8 File v17 File Status
_main.cshtml _main.cshtml Migrated

4.10 Home/ (6 v8 / 6 v17)

v8 File v17 File Status
slider.cshtml slider.cshtml Migrated
pictureSlide.cshtml pictureSlide.cshtml Migrated
pictureTextBox.cshtml pictureTextBox.cshtml Migrated
internalVideo.cshtml internalVideo.cshtml Migrated
vimeoVideo.cshtml vimeoVideo.cshtml Migrated
youTubeVideo.cshtml youTubeVideo.cshtml Migrated

4.11 Notifications/ (2 v8 / 2 v17)

v8 File v17 File Status
_GlobalNotifications.cshtml _GlobalNotifications.cshtml Migrated
_GlobalNotificationsHTML.cshtml _GlobalNotificationsHTML.cshtml Migrated

4.12 calcGridSlider/ (7 v8 / 6 v17)

v8 File v17 File Status
pictureSlide.cshtml pictureSlide.cshtml Migrated
pictureTextBox.cshtml pictureTextBox.cshtml Migrated
internalVideo.cshtml internalVideo.cshtml Migrated
vimeoVideo.cshtml vimeoVideo.cshtml Migrated
youTubeVideo.cshtml youTubeVideo.cshtml Migrated
splitPictureSlide.cshtml splitPictureSlide.cshtml Migrated
splitPictureSlidePrevew.cshtml -- REMOVED -- preview-only partial, not used in production

5. MacroPartials (ALL 9 OBSOLETE)

Macros were completely removed from Umbraco starting in v13+. All 9 MacroPartials in v8 are obsolete. Their functionality has been either moved to BlockGrid components, standard partials, or removed entirely.

v8 MacroPartial Replacement in v17 Notes
Audio Tag.cshtml blockgrid/Components/audioTagElement.cshtml Converted to BlockGrid element
Budget Planner.cshtml -- Removed; functionality not reimplemented
InsertUmbracoFormWithTheme.cshtml Built-in Umbraco Forms rendering Forms are now rendered via Umb.RenderForm macro-free approach
Login.cshtml blockgrid/Components/loginWidget.cshtml Converted to BlockGrid element
LoginStatus.cshtml LoginStatus/_LoginStatus.cshtml Moved to standard partial + ViewComponent
Register.cshtml -- Removed; member registration handled differently
RenderUmbracoFormScripts.cshtml Built-in Forms script injection Handled automatically by Umbraco Forms v17
cookies.cshtml blockgrid/Components/cookiesElement.cshtml Converted to BlockGrid element
moneyadviceservice.cshtml -- Removed; external service integration changed

Why macros were removed: Umbraco v13 replaced the macro system with a simpler model where all reusable content blocks are either Razor partials, ViewComponents, or BlockGrid/BlockList elements. The macro rendering pipeline, XSLT support, and <Umbraco.RenderMacro> tag helper are all gone. Content editors now use the Block Grid/Block List editors to insert the same kinds of reusable content.


6. Forms Views (79 v8 / 13 v17)

The dramatic reduction from 79 to 13 files is because Umbraco Forms v17 ships with built-in default views for all standard field types, email templates, export templates, and the default theme. Only custom overrides need to exist in the project.

6.1 What Was Removed (66 files)

Emails/ (25 files) -- ALL REMOVED

All 25 email templates (AlturaCU, Boom-CreditorTable, EmailWithData, etc.) are client-specific email templates that were stored in the codebase. In v17, email templates are configured in the Umbraco Forms backoffice and stored in the database, not as Razor view files.

Export/ (1 file) -- REMOVED

excel.cshtml -- built-in in Umbraco Forms v17.

Fieldtypes/ (14 files at root level) -- ALL REMOVED

All 14 root-level field type views (CheckBox, DatePicker, DropDownList, etc.) are now built-in defaults shipped with Umbraco Forms v17. No need for custom overrides.

Themes/bootstrap3-horizontal/ (2 files) -- REMOVED

The bootstrap3-horizontal theme is obsolete. Bootstrap 3 horizontal form layout is replaced by Bootstrap 5 patterns.

Themes/default/ core views (5 files) -- REMOVED

v8 File Reason Removed
Form.cshtml Built-in default in Umbraco Forms v17
Render.cshtml Built-in default
Script.cshtml Built-in default
DatePicker.cshtml Built-in default
Submitted.cshtml Built-in default

Themes/default/Fieldtypes/ (19 files) -- 18 REMOVED, 1 KEPT

All standard field type overrides (CheckBox, DatePicker, DropDownList, etc.) are removed because Umbraco Forms v17 ships them. Only FieldType.FriendlyCaptcha.cshtml is kept because it is a custom field type not included in the Forms package.

6.2 What Was Kept (13 files)

v17 File Purpose
Themes/default/Fieldtypes/FieldType.FriendlyCaptcha.cshtml Custom captcha field type
Themes/default/ScrollToFormScript.cshtml Custom JS for scroll-to-form behaviour
Themes/default/ScrollToFormScriptAccordion.cshtml Custom JS for accordion-hosted forms
Themes/default/psUmbracoFormsScript.cshtml Custom Progress-specific form scripts
Themes/General/Form.cshtml Custom theme for general forms
Themes/GeneralShowHide/Form.cshtml Custom theme with show/hide conditional fields
Themes/psFormContact/Form.cshtml Custom contact form theme
Themes/psLoanBoxes/Form.cshtml Custom loan box form theme
Themes/psLoanBoxesAccordion/Form.cshtml Custom loan accordion form theme
Themes/psLostYourPin/Form.cshtml Custom "lost your PIN" form theme
Themes/psMortgageCalculator/Form.cshtml Custom mortgage calculator form theme
Themes/psPoll/Form.cshtml Custom poll form theme
Themes/psPopup/Form.cshtml Custom popup form theme

6.3 Forms API Changes Summary

Aspect v8 v17
Model declaration @inherits WebViewPage<FormViewModel> @model FormViewModel
Namespaces Umbraco.Forms.Mvc, Umbraco.Forms.Mvc.Models, Umbraco.Forms.Mvc.BusinessLogic Umbraco.Forms.Web, Umbraco.Forms.Web.Models, Umbraco.Forms.Web.Services
Theme resolver Static class FormThemeResolver DI: @inject IFormThemeResolver FormThemeResolver
CSS wrapper form-group (Bootstrap 4) mb-3 (Bootstrap 5)
Partial rendering Html.Partial(...) @await Html.PartialAsync(...)
Email templates Razor files in Forms/Emails/ Database-stored in backoffice

7. Additional v17 Directories (Not in v8)

These directories exist in v17 but have no direct equivalent in v8 because they represent the migrated Grid content:

v17 Directory File Count Origin
blockgrid/ 8 core + 70+ components Replaces v8 Grid/ editors + DTGE
blocklist/ 1 + 6 components Replaces v8 BlockList/
LoginStatus/ 1 Extracted from MacroPartials
loanboxes/ 4 Extracted from Grid/Editors/LoanBoxes
news/ 7 Extracted from Grid/Editors/News

8. Gaps and Issues

8.1 Missing in v17

File Priority Notes
Help/_subarticle.cshtml P3 Verify content is consolidated into _main.cshtml
social/_instagram.cshtml P3 Instagram embed API change; verify no content uses it

8.2 Behavioural Differences

Area Difference Risk
SiteLayout/header.cshtml styleblock output removed in v17 (invalid HTML fix) LOW -- original was broken
Forms email templates 25 templates removed from filesystem MEDIUM -- must verify all are recreated in CMS backoffice
MacroPartials All 9 removed LOW -- replacements confirmed
navigation.cshtml Removed (static nav) LOW -- navigationDynamic.cshtml handles all cases

8.3 Case Sensitivity

Several files changed casing between v8 and v17:

  • Default.cshtml -> default.cshtml (BlockList)
  • seo.cshtml -> SEO.cshtml (SiteLayout)
  • Help/ -> help/ (directory)
  • Home/ -> home/ (directory)
  • BlockList/ -> blocklist/ (directory)

This is generally fine on Windows (case-insensitive) but could cause issues on Linux deployments.

Migration documentation by Double for Progress Credit Union