Report 21: Page Templates Side-by-Side Comparison¶
Date: 2026-02-27 Scope: All root
.cshtmlfiles inViews/(page templates and master layouts), excludingPartials/subdirectories. V8 source:psCreditUnion/Progress.Web/Views/V17 target:dbl.Progress/src/www/Views/
1. Overview¶
| Metric | Count |
|---|---|
| V8 root .cshtml files | 48 |
| V17 root .cshtml files | 46 |
| Migrated (1:1 or consolidated) | 44 |
| V8-only (not migrated) | 3 (LoanBoxContactControl, NewsCategoryItems, TrustpilotWidget) |
| V17-only (new) | 1 (_ViewImports.cshtml) |
| Consolidated | 1 (masterNoHeaderNoFooter.cshtml merged into masterNoHeaderNof.cshtml in v17) |
Migration Pattern Summary¶
Every migrated template applies the same set of repeating transformation patterns:
| ID | Pattern | V8 | V17 |
|---|---|---|---|
| P1 | Base class | @inherits Umbraco.Web.Mvc.UmbracoViewPage |
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage |
| P2 | Strongly-typed model | @inherits ...UmbracoViewPage<ContentModels.Xyz> |
Removed; use Model.Value<T>() directly |
| P3 | Settings lookup | Umbraco.ContentSingleAtXPath("//...") |
@inject ISiteSettingsService SiteSettings |
| P4 | CSS/JS bundling | Html.RequiresCss() / Html.RequiresJs() / Html.RenderCssHere() / Html.RenderJsHere() |
<link> / <script> tags + Html.AddScript() / Html.RenderScripts() / Html.RenderCss() |
| P5 | Cached partials | Html.CachedPartial("...", Model, 3600, true) |
await Html.CachedPartialAsync("...", Model, TimeSpan.FromHours(1), cacheByPage: true) |
| P6 | Sync partials | Html.Partial("...") / Html.RenderPartial("...") |
await Html.PartialAsync("...") |
| P7 | Grid rendering | Html.GetGridHtml(Model, "grid", "template", ...) |
Model.Value<BlockGridModel>("grid") + Html.PartialAsync("blockgrid/...") |
| P8 | BlockList rendering | Html.GetBlockListHtml(Model, "Blocks") |
Model.Value<BlockListModel>("blocks") + Html.PartialAsync("blocklist/default", ...) |
| P9 | Dictionary values | Umbraco.GetDictionaryValue("key") |
@inject IDictionaryService Dictionary + Dictionary.GetValue("key") |
| P10 | Color picker | #@color (double-hash bug) |
.TrimStart('#') applied to all color values |
| P11 | Bool properties | Model.Value<String>("x") == "True" |
Model.Value<bool>("x") |
| P12 | Bootstrap data attrs | data-spy, data-target, data-offset |
data-bs-spy, data-bs-target, data-bs-offset |
| P13 | Macro rendering | Umbraco.RenderMacro("...") |
Replaced with BlockGrid/BlockList content or ViewComponents |
| P14 | Surface controllers | Html.RenderAction("...", "...Surface") |
await Component.InvokeAsync("...") |
| P15 | Umbraco Forms | Html.RenderUmbracoFormDependencies() |
Removed (v17 Forms handles its own dependencies) |
2. Side-by-Side Comparisons¶
A. master.cshtml -- The Main Layout¶
The most important file. Controls HTML shell, CSS/JS loading, header/footer, GTM, fonts, and search for every page.
Inherits and Imports¶
v8 (Umbraco 8)¶
@inherits Umbraco.Web.Mvc.UmbracoViewPage
@using ClientDependency.Core.Mvc
@using Progress.Core.Helpers
@using System.Web.Configuration
@using System.Text.RegularExpressions
@using Umbraco.Forms.Mvc
v17 (Umbraco 17)¶
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@using Umbraco.Cms.Core.Models.PublishedContent
@using System.Text.RegularExpressions
@using Progress.Umbraco.Helpers
@inject ISiteSettingsService SiteSettings
@inject IDictionaryService Dictionary
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment WebHostEnvironment
What changed:
- P1: Base class namespace changed from
Umbraco.Web.MvctoUmbraco.Cms.Web.Common.Views - P3:
ClientDependency.Core.Mvcremoved entirely; replaced by DI-injected services - P3:
System.Web.Configuration(ASP.NET 4.x) removed; noWebConfigurationManagerin .NET Core - P3:
Umbraco.Forms.Mvcremoved; Forms handles its own dependencies in v17 - P3: Three
@injectdirectives replace all XPath content queries
Settings Resolution¶
v8 (Umbraco 8)¶
var settings = Umbraco.ContentSingleAtXPath("//websiteConfiguration");
string domainName = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
var Mobile = Request.Browser["IsMobile"];
var gtsettings = Umbraco.ContentSingleAtXPath("//googleTagManagerConfiguration");
var googleTagManagerHeader = gtsettings.Value<string>("googleTagManagerHeader");
var stylesSettings = Umbraco.ContentSingleAtXPath("//siteStyleConfiguration");
var menuSettings = Umbraco.ContentSingleAtXPath("//menuConfiguration");
var menuStyle = menuSettings.Value<string>("menuStyle");
var cookieNotice = Umbraco.GetDictionaryValue("cookieNotice");
string searchUrl = Umbraco.ContentAtXPath("//search")
.Single(c => c.Parent.Id == Model.Root().Id)
.Url();
v17 (Umbraco 17)¶
var website = SiteSettings.Website;
var styles = SiteSettings.Styles;
var menu = SiteSettings.Menu;
var gtm = SiteSettings.GoogleTagManager;
var gtmHeader = gtm?.GoogleTagManagerHeader;
var menuStyle = menu?.MenuStyle?.ToLowerInvariant();
var searchUrl = SiteSettings.SearchPage?.Url();
var cookieNotice = Dictionary.GetValue("cookieNotice");
var gotoTop = Dictionary.GetValue("GotoTop");
What changed:
- P3: Five separate
ContentSingleAtXPath()calls replaced by a singleISiteSettingsServiceinjection (cached per request) - P9:
Umbraco.GetDictionaryValue()replaced byDictionary.GetValue() HttpContext.Currentremoved (not available in .NET Core)Request.Browser["IsMobile"]removed (responsive CSS replaces server-side mobile detection)- Null-safe operators (
?.) used throughout for robustness
CSS and JS Loading¶
v8 (Umbraco 8)¶
Html.RequiresCss("~/vendor/bootstrap/css/bootstrap.min.css", 0);
Html.RequiresCss("~/vendor/slick/slick.css", 3);
Html.RequiresCss($"~/content/common{commonCssVersion}.css", 10);
Html.RequiresJs("/vendor/bootstrap/js/bootstrap.bundle.min.js", 1, new { defer = "defer" });
Html.RequiresJs("/vendor/lazysizes/lazySizes.min.js", 12, new { async = "async" });
// In <head>:
@Html.RenderCssHere()
// Before </body>:
@Html.RenderJsHere()
v17 (Umbraco 17)¶
// Static <link> tags in <head>:
<link rel="stylesheet" href="~/vendor/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/vendor/slick/slick.css" />
<link rel="stylesheet" href="~/content/CommonV2.css" />
<link rel="stylesheet" href="~/css/umbraco-blockgrid.css" />
// Script helper calls before </body>:
Html.AddScript("~/vendor/bootstrap/js/bootstrap.bundle.min.js", 1, defer: true);
Html.AddScript("~/vendor/lazySizes/lazySizes.min.js", 12, true);
// Partials can contribute CSS/JS:
@Html.RenderCss()
@Html.RenderScripts()
What changed:
- P4:
ClientDependencyframework (RequiresCss/RequiresJs/RenderCssHere/RenderJsHere) replaced entirely - CSS now uses explicit
<link>tags in<head>(order matches v8 priorities) - JS uses custom
Html.AddScript()helper with named parameters (async:,defer:) - Versioned CSS file
common{version}.cssreplaced byCommonV2.css - New:
umbraco-blockgrid.cssadded for BlockGrid layout support - New:
gridSlider.cssandhomeSlider.cssloaded globally - New: jQuery UI CSS/JS added globally (was loaded per-component in v8)
- jQuery CDN fallback added:
window.jQuery || document.write(...)
Cached Partials (Header/Footer)¶
v8 (Umbraco 8)¶
@Html.CachedPartial("SiteLayout/headerMenu4", Model, 3600, true)
@Html.Partial("SiteLayout/footer")
@Html.RenderUmbracoFormDependencies()
v17 (Umbraco 17)¶
@await Html.CachedPartialAsync("SiteLayout/headerMenu4", Model,
TimeSpan.FromHours(1), cacheByPage: true)
@await Html.PartialAsync("SiteLayout/footer")
What changed:
- P5:
CachedPartialbecomesCachedPartialAsyncwithawait; cache duration usesTimeSpaninstead of seconds - P6:
Html.Partialbecomesawait Html.PartialAsync - P15:
RenderUmbracoFormDependencies()removed entirely - P12:
data-spy="scroll"becomesdata-bs-spy="scroll"(Bootstrap 5)
Body Tag and Bottom Section¶
v8 (Umbraco 8)¶
<body id="page-@strBodyTagID" data-spy="scroll" data-target="#fixedNavbar" data-offset="1">
@Html.RenderJsHere()
@RenderSection("ScriptsBottom", false)
@Html.PageScripts()
<input id="cultureAll" name="culture" type="hidden"
value="@System.Threading.Thread.CurrentThread.CurrentCulture.ToString()">
v17 (Umbraco 17)¶
<body id="page-@bodyId" data-bs-spy="scroll" data-bs-target="#fixedNavbar" data-bs-offset="1">
@Html.RenderScripts()
@RenderSection("scripts", false)
<input type="hidden" id="cultureAll" name="culture" value="@fullCulture" />
What changed:
- P12: All Bootstrap data attributes gain
bs-prefix - P4:
RenderJsHere()+PageScripts()consolidated into singleRenderScripts() - Section name changed from
"ScriptsBottom"to"scripts"for consistency - Culture uses
Model.GetCultureFromDomains()instead ofThread.CurrentThread.CurrentCulture
B. home.cshtml -- Grid to BlockGrid Conversion¶
Shows the core content rendering transformation from v8 Grid to v17 BlockGrid.
v8 (Umbraco 8)¶
@inherits Umbraco.Web.Mvc.UmbracoViewPage
@using Progress.Core.Extensions
@using Umbraco.Web
@using Umbraco.Core.PropertyEditors.ValueConverters
@using ClientDependency.Core.Mvc
@using Umbraco.Web.Models;
@{
Html.RequiresJs("~/Scripts/aosInit.js", 25, new { async = "async" });
}
@{
Layout = "master.cshtml";
}
@Html.Partial("home/slider")
<div class="container bodyStart homepage">
@Html.GetGridHtml(Model, "grid", "homePageGrid", true, false)
</div>
v17 (Umbraco 17)¶
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@using Umbraco.Cms.Core.Models.Blocks
@using Microsoft.AspNetCore.Mvc.ViewFeatures
@using www.Extensions
@using Progress.Umbraco.Helpers
@{
Layout = "master.cshtml";
}
@{
Html.AddScript("~/Scripts/aosInit.js", 25, async: true);
}
@await Html.PartialAsync("Home/slider")
<div class="container bodyStart homepage">
@{
var grid = Model.Value<BlockGridModel>("grid");
if (grid != null && grid.Any())
{
@await Html.PartialAsync("blockgrid/BootstrapGrid", grid,
new ViewDataDictionary(ViewData) {
{ "ColumnBreakpoint", "xl" },
{ "RowClasses", "row clearfix" },
{ "ColumnClasses", "column mx-0 mx-md-0" },
{ "UseContainer", false },
{ "MergeAreaClasses", true }
}, true)
}
}
</div>
What changed:
- P1: Base class namespace updated
- P4:
Html.RequiresJs()becomesHtml.AddScript()with namedasync:parameter - P6:
Html.Partial("home/slider")becomesawait Html.PartialAsync("Home/slider") - P7: Single-line
Html.GetGridHtml(Model, "grid", "homePageGrid", true, false)replaced with:Model.Value<BlockGridModel>("grid")to get the typed modelHtml.PartialAsync("blockgrid/BootstrapGrid", grid, viewData)for renderingViewDataDictionarywith layout parameters (ColumnBreakpoint,RowClasses,UseContainer, etc.)
- Null-check added (
grid != null && grid.Any()) -- v8 grid helper handled null internally - Container
<div>preserved exactly (class"container bodyStart homepage")
C. standardPage.cshtml -- Generic Page with Grid + Header Image¶
Demonstrates header image/color handling, the color picker double-hash fix, and multi-section grid rendering.
v8 (Umbraco 8)¶
@inherits Umbraco.Web.Mvc.UmbracoViewPage
@using Progress.Core.Extensions
@using Umbraco.Web
@using Umbraco.Core.PropertyEditors.ValueConverters
@{
Layout = "master.cshtml";
if (Model.Value<IPublishedContent>("headerImage") != null)
{
var myHeaderImage = Model.Value<IPublishedContent>("headerImage");
myHeaderImageUrl = myHeaderImage.Url;
var fileExtensionOne = myHeaderImage.GetProperty("UmbracoExtension").GetSourceValue();
fileExtension = fileExtensionOne.ToString();
if (fileExtension.ToString() != "mp4")
{
var headerImage = Model.Value<IPublishedContent>("headerImage").Url;
myImage = headerImage + mycrop;
style = "background-image: url('" + myImage + "')";
}
}
else
{
var backgroundColorNew = Model.Value<String>("headerColour");
if (backgroundColorNew != "")
{
backgroundColor = backgroundColorNew;
}
var solidColor = Model.Value<String>("solidColour");
if (solidColor == "True")
{
style = "background-color:#" + backgroundColor;
}
}
}
<div class="container content-page with-header">
@Html.GetGridHtml(Model, "grid", "standardPageGridBootStrap", true, false)
</div>
v17 (Umbraco 17)¶
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@using Umbraco.Cms.Core.Models.Blocks
@using Microsoft.AspNetCore.Mvc.ViewFeatures
@using www.Extensions
@{
Layout = "master.cshtml";
var headerImage = Model.Value<IPublishedContent>("headerImage");
if (headerImage != null)
{
myHeaderImageUrl = headerImage.Url();
fileExtension = headerImage.Value<string>("umbracoExtension") ?? "";
if (fileExtension.ToLowerInvariant() != "mp4")
{
myImage = myHeaderImageUrl + mycrop;
style = $"background-image: url('{myImage}')";
}
}
else
{
var backgroundColorNew = Model.Value<string>("headerColour") ?? "";
if (!string.IsNullOrEmpty(backgroundColorNew))
{
backgroundColor = backgroundColorNew.TrimStart('#');
}
var solidColor = Model.Value<bool>("solidColour");
if (solidColor)
{
style = $"background-color:#{backgroundColor}";
}
}
}
<div class="container content-page with-header">
@{
var grid = Model.Value<BlockGridModel>("grid");
if (grid != null)
{
@await Html.PartialAsync("blockgrid/_MultiSectionGrid", grid,
new ViewDataDictionary(ViewData) {
{ "PageName", Model.Name },
{ "InjectH1", true },
{ "ColumnBreakpoint", "md" },
{ "RowClasses", "row clearfix mainbody" },
{ "ColumnClasses", "column" },
{ "UseContainer", true },
{ "ContainerClass", "container" },
{ "SectionBreakpoint", "lg" }
}, true)
}
}
</div>
What changed:
- P1: Base class namespace updated
- P10: Color values get
.TrimStart('#')to prevent double-hash bug (##e47d51) - P11:
Model.Value<String>("solidColour") == "True"becomesModel.Value<bool>("solidColour") - Media property access:
myHeaderImage.GetProperty("UmbracoExtension").GetSourceValue()becomesheaderImage.Value<string>("umbracoExtension") .Urlproperty becomes.Url()method call- Null-safe patterns:
?? ""and!string.IsNullOrEmpty()replace bare!= "" - String interpolation:
$"background-color:#{backgroundColor}"replaces concatenation - P7:
Html.GetGridHtml()replaced with_MultiSectionGridpartial (supports v8 multi-section layout structure) - Grid partial receives layout config via
ViewDataDictionary(InjectH1,UseContainer,ContainerClass, etc.)
3. Complete File Mapping Table¶
Master Layouts¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 1 | master.cshtml |
master.cshtml |
MIGRATED | P1,P3,P4,P5,P6,P9,P12,P15 | Main layout; XPath to DI; ClientDependency to static tags |
| 2 | masterNoHeaderNoFooter.cshtml |
masterNoHeaderNoFooter.cshtml |
CONSOLIDATED | P1,P3,P4 | Was 4 lines in v8 (Layout=null); v17 is full standalone layout identical to masterNoHeaderNof |
| 3 | masterNoHeaderNof.cshtml |
masterNoHeaderNof.cshtml |
MIGRATED | P1,P3,P4 | Full standalone layout with CSS/JS but no header/footer; v17 identical to masterNoHeaderNoFooter |
| 4 | MasterThirdParty.cshtml |
MasterThirdParty.cshtml |
MIGRATED | P1,P3,P4,P5,P6,P9,P12 | Near-identical to master.cshtml; same transformation patterns |
| 5 | MasterLogin.cshtml |
MasterLogin.cshtml |
MIGRATED | P1,P3,P4,P5,P6,P9,P12 | Simplified layout for login pages; uses <cache> tag helper instead of CachedPartialAsync |
| 6 | -- | _ViewImports.cshtml |
NEW | -- | v17-only; provides global @using and @addTagHelper directives |
Home Page Templates¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 7 | home.cshtml |
home.cshtml |
MIGRATED | P1,P4,P6,P7 | Grid to BlockGrid via BootstrapGrid partial |
| 8 | homeGrid.cshtml |
homeGrid.cshtml |
MIGRATED | P1,P4,P7,P14 | Html.RenderAction to Component.InvokeAsync; homepageH1 script externalized |
| 9 | homeFullWidthSection.cshtml |
homeFullWidthSection.cshtml |
MIGRATED | P1,P4,P6,P7,P14 | Two grids (grid + bottomGrid) both converted to BlockGrid |
Standard Page Templates¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 10 | standardPage.cshtml |
standardPage.cshtml |
MIGRATED | P1,P7,P10,P11 | Header image + color picker + _MultiSectionGrid |
| 11 | StandardPageNew.cshtml |
standardPageNew.cshtml |
MIGRATED | P1,P4,P7,P8 | BlockList header + Grid body; case normalized in v17 |
| 12 | standardPageWow.cshtml |
standardPageWow.cshtml |
MIGRATED | P1,P4,P7,P10,P11 | AOS animations; height dropdown wrapped in try-catch for Flexible.Dropdown bug |
| 13 | standardPageWithImageText.cshtml |
standardPageWithImageText.cshtml |
MIGRATED | P1,P4,P7,P10,P11 | Similar to standardPageWow with image+text header |
| 14 | StandardPageNewNoHeaderNoFooter.cshtml |
StandardPageNewNoHeaderNoFooter.cshtml |
MIGRATED | P1,P4,P7,P8 | Uses masterNoHeaderNoFooter layout |
| 15 | StandardPageThirdParty.cshtml |
StandardPageThirdParty.cshtml |
MIGRATED | P1,P7,P8 | Uses MasterThirdParty layout |
Article Templates¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 16 | article.cshtml |
article.cshtml |
MIGRATED | P1,P6,P10,P11 | Color picker fix; renders ArticleContent partial |
| 17 | articleList.cshtml |
articleList.cshtml |
MIGRATED | P1,P7,P10,P11 | Article listing page |
| 18 | articleListPaging.cshtml |
articleListPaging.cshtml |
MIGRATED | P1,P7 | Paginated article list |
| 19 | articleType2.cshtml |
articleType2.cshtml |
MIGRATED | P1,P6,P7 | Alternate article layout |
| 20 | ArticleContentType2.cshtml |
ArticleContentType2.cshtml |
MIGRATED | P1,P6,P7 | Alternate article content type |
| 21 | LatestArticlesPaging.cshtml |
LatestArticlesPaging.cshtml |
MIGRATED | P1,P7 | Latest articles with pagination |
FAQ Templates¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 22 | Faq.cshtml |
Faq.cshtml |
MIGRATED | P1,P4,P7,P8 | BlockList + Grid; uses _MultiSectionGrid |
| 23 | Faq1.cshtml |
Faq1.cshtml |
MIGRATED | P1,P4,P7,P8 | Alternate FAQ layout |
| 24 | FaqWithSchema.cshtml |
FaqWithSchema.cshtml |
MIGRATED | P1,P4,P7,P8 | FAQ with JSON-LD schema markup |
Functional Templates¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 25 | search.cshtml |
search.cshtml |
MIGRATED | P1,P3,P9,P10,P11 | Umbraco.ContentQuery.Search replaced with Examine fluent API; form-group to mb-3; no-gutters to g-0 |
| 26 | contactus.cshtml |
contactus.cshtml |
MIGRATED | P1,P7,P10,P11 | ContactUsGrid to _MultiSectionGrid |
| 27 | error.cshtml |
error.cshtml |
MIGRATED | P1,P7,P10,P11 | Error page with grid content |
| 28 | sitemap.cshtml |
sitemap.cshtml |
MIGRATED | P1 | XML sitemap; @helper syntax replaced with @functions returning IHtmlContent; HttpContext.Current replaced with Context.Request |
| 29 | robots.cshtml |
robots.cshtml |
MIGRATED | P1 | text/plain output; Request.Url replaced with Context.Request.Scheme/Host; v8-only paths removed |
| 30 | cookies.cshtml |
cookies.cshtml |
MIGRATED | P1,P7 | Cookie policy page |
| 31 | privacyPolicy.cshtml |
privacyPolicy.cshtml |
MIGRATED | P1,P7 | Privacy policy page |
| 32 | termsAndConditions.cshtml |
termsAndConditions.cshtml |
MIGRATED | P1,P7 | Terms page |
Login and Authentication Templates¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 33 | Login1.cshtml |
Login1.cshtml |
MIGRATED | P1,P7,P13 | Umbraco.RenderMacro("Login") replaced with BlockGrid content rendering |
| 34 | CustomerOnlyPage1.cshtml |
CustomerOnlyPage1.cshtml |
MIGRATED | P1,P3,P7,P10,P11 | Uses MasterLogin layout; grid content |
| 35 | TokenAuthentication.cshtml |
TokenAuthentication.cshtml |
MIGRATED | P1,P4,P7,P8 | BlockList + Grid; same pattern as StandardPageNew |
Special Templates¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 36 | SPALoader.cshtml |
SPALoader.cshtml |
MIGRATED | P1,P3,P9 | HtmlAgilityPack parsing; Server.MapPath to WebHostEnvironment.WebRootPath; Dictionary injection |
| 37 | popUpForms.cshtml |
popUpForms.cshtml |
MIGRATED | P1,P2,P13 | Macro form rendering; v17 has TODO placeholder for Umbraco.Forms integration |
| 38 | NoPreviewAvailable.cshtml |
NoPreviewAvailable.cshtml |
MIGRATED | P1 | Standalone info page; v17 simplified with flexbox layout |
| 39 | TestimonialsBlock.cshtml |
TestimonialsBlock.cshtml |
MIGRATED | P1,P7 | Testimonials display page |
| 40 | testimonials.cshtml |
testimonials.cshtml |
MIGRATED | P1,P7 | Alternate testimonials template |
| 41 | gallery.cshtml |
gallery.cshtml |
MIGRATED | P1,P7,P10 | Photo gallery page |
| 42 | galleryList.cshtml |
galleryList.cshtml |
MIGRATED | P1,P7 | Gallery listing page |
| 43 | help.cshtml |
help.cshtml |
MIGRATED | P1,P7 | Help/support page |
| 44 | loanInputCTA.cshtml |
loanInputCTA.cshtml |
MIGRATED | P1,P7 | Loan calculator CTA page |
| 45 | releaseNotesWidget.cshtml |
releaseNotesWidget.cshtml |
MIGRATED | P1,P2 | Release notes dropdown; strongly-typed model removed |
| 46 | TermsAndConditionsMobile.cshtml |
TermsAndConditionsMobile.cshtml |
MIGRATED | P1 | Mobile T&C view |
V8-Only (Not Migrated to V17)¶
| # | v8 File | v17 File | Status | Patterns | Notes |
|---|---|---|---|---|---|
| 47 | LoanBoxContactControl.cshtml |
-- | OBSOLETE | -- | Empty template (Layout = null only); content type unused in active databases |
| 48 | NewsCategoryItems.cshtml |
-- | OBSOLETE | -- | Empty template (Layout = null only); content type unused in active databases |
| 49 | TrustpilotWidget.cshtml |
-- | OBSOLETE | -- | Empty template (Layout = null only); content type unused in active databases |
4. Gaps and Notable Differences¶
Templates Not Migrated (3)¶
| v8 File | Reason |
|---|---|
LoanBoxContactControl.cshtml |
Empty stub template (4 lines: @inherits + Layout = null). No content rendering. Content type appears unused. |
NewsCategoryItems.cshtml |
Empty stub template (3 lines). No content rendering. Content type appears unused. |
TrustpilotWidget.cshtml |
Empty stub template (3 lines). No content rendering. Content type appears unused. |
All three are empty templates that only set Layout = null with no body content. They were likely created by ModelsBuilder but never implemented. Per the shared codebase policy, these should be cross-validated against all client databases before removal from the codebase.
V17-Only Template (1)¶
| v17 File | Purpose |
|---|---|
_ViewImports.cshtml |
Global @using directives and @addTagHelper registrations. ASP.NET Core convention (no v8 equivalent). Imports: Umbraco.Extensions, Umbraco.Cms.Web.Common.PublishedModels, Progress.Baseline.Core.Services, Progress.Umbraco.Extensions, www.Services, Umbraco.Community.UmbNav.Core. |
Consolidated Template (1)¶
| v8 Files | v17 Result |
|---|---|
masterNoHeaderNoFooter.cshtml (4 lines) + masterNoHeaderNof.cshtml (159 lines) |
Both exist in v17 with identical full layout code. The v8 masterNoHeaderNoFooter.cshtml was a minimal 4-line file; v17 expanded it to a full standalone layout matching masterNoHeaderNof.cshtml. |
Key Architectural Differences¶
-
Grid to BlockGrid: Every
@Html.GetGridHtml(Model, ...)call is replaced withModel.Value<BlockGridModel>(...)+Html.PartialAsync("blockgrid/..."). Two partial renderers are used:blockgrid/BootstrapGrid-- for simple single-section pages (home, homeGrid)blockgrid/_MultiSectionGrid-- for multi-section pages with H1 injection (standardPage, contactus, error, etc.)
-
Macro Elimination: All
Umbraco.RenderMacro()calls removed. Login macro replaced with BlockGrid content. Form macro has a TODO placeholder. -
Surface Controller Elimination:
Html.RenderAction("...", "...Surface")replaced withComponent.InvokeAsync("...")ViewComponents. -
popUpForms.cshtml: The Umbraco Forms rendering is currently a TODO placeholder in v17. The v8 version used
Umbraco.RenderMacro("renderUmbracoForm", ...)which is not available in v17. This needs the Umbraco.Forms v17 package integration. -
Search Implementation: v8 used
Umbraco.ContentQuery.Search()which is removed in v17. Replaced with direct Examine index querying viaIExamineManagerwith fluent API.