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:
- MacroPartials (9 files) -- macros are removed from Umbraco v17 entirely
- 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
- Grid/ (11 files) -- replaced entirely by
blockgrid/ with component-per-element architecture
This is the primary site header partial. It demonstrates the core migration patterns.
@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>
@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/... |
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>
| 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.
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 |
| 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.