Skip to content

Report 22: Component Views Side-by-Side Comparison

Scope: ALL v8 DocTypeGridEditor component views and grid sub-components compared to their v17 BlockGrid equivalents.

Date: 2026-02-27


1. Overview

Architecture Change: DTGE to BlockGrid

The migration from Umbraco v8 to v17 fundamentally changes how grid component views work:

Aspect v8 (DocTypeGridEditor) v17 (BlockGrid)
Base class @inherits UmbracoViewPage<ContentModels.TypeName> @inherits UmbracoViewPage<BlockGridItem>
Model access Model.Value<T>("alias") directly Model.Content.Value<T>("alias") via content variable
Media types IPublishedContent MediaWithCrops (single-pick) or IEnumerable<MediaWithCrops> (multi)
Media URL media.Url (property) media.MediaUrl() (extension method)
Image cropping Url.GetCropUrl(media, w, h, quality:n) $"{url}?width={w}&height={h}&mode=crop&quality={n}"
Links IEnumerable<Link> from Umbraco.Web.Models IEnumerable<Link> from Umbraco.Cms.Core.Models
CSS/JS includes Html.RequiresCss() / Html.RequiresJs() (ClientDependency) Html.AddScript() / static <link> tags
Dictionary Umbraco.GetDictionaryValue("key") @inject IDictionaryService Dictionary + Dictionary.GetValue("key")
Null handling if (x != null) with manual .ToString() ?? "" null-coalescing pattern
Dropdown values Model.Value<string>("alias") (plain string) try { content.Value<string>("alias") } catch { } (JSON array in v17)
ColorPicker style="color:#@textColor" (no hash stored) FormatColor() helper with TrimStart('#') or StartsWith("#") check
Nested Content IEnumerable<IPublishedContent> IEnumerable<BlockListItem> with block.Content access

Key Migration Patterns Applied

  1. MediaPicker3 Single-Pick: content.Value<MediaWithCrops>("alias")?.MediaUrl() -- NOT IPublishedContent
  2. DropDown.Flexible try-catch: All dropdown properties wrapped in try-catch because v8 stores plain strings but v17 expects JSON arrays
  3. ColorPicker TrimStart: c.StartsWith("#") ? c : "#" + c to handle double-hash bug
  4. BlockList iteration: content.Value<IEnumerable<BlockListItem>>("alias") with block.Content.Value<T>() for each item
  5. Unique IDs: Guid.NewGuid().ToString("N")[..8] replaces new Random().Next(0, 100000)

2. Side-by-Side Comparisons

2A. heroItem.cshtml -- Hero Component

Shows: MediaPicker3 single-pick, DropDown.Flexible try-catch, Link collection, image crop URL

v8 (DocTypeGridEditor/heroItem.cshtml, 270 lines):

@inherits UmbracoViewPage<ContentModels.HeroItem>
@using ContentModels = Umbraco.Web.PublishedModels;
@using Umbraco.Web.Models
@{
    var heading = "";
    var link = Model.Value<IEnumerable<Link>>("link");
    var image = "";
    var imageLocation = "Left";

    if (Model.Value<string>("imageLocation") != null)
    {
        imageLocation = Model.Value<string>("imageLocation").ToString();
        imageLocation = imageLocation.ToLower();
    }
    if (Model.Value<IPublishedContent>("firstCurve") != null)
    {
        firstCurve = Model.Value<IPublishedContent>("firstCurve").Url.ToString();
    }
    if (Model.Value<IPublishedContent>("image") != null)
    {
        image = Model.Value<IPublishedContent>("image").Url.ToString();
    }
    // ...
    <div class="halfleft col-bgr-cover lazyload"
         style="background-image: url('@Url.GetCropUrl(Model.Image, 1000, 516, quality:5)');"
         data-bg="@Url.GetCropUrl(Model.Image, 1000, 516, quality:80)"></div>
}

v17 (blockgrid/Components/heroItem.cshtml, 163 lines):

@inherits UmbracoViewPage<BlockGridItem>
@using Umbraco.Cms.Core.Models
@using Progress.Umbraco.Helpers
@{
    var content = Model.Content;
    var heading = content.Value<string>("heading") ?? "";
    var links = content.Value<IEnumerable<Link>>("link") ?? Enumerable.Empty<Link>();

    // MediaPicker3 single-pick returns MediaWithCrops (not IPublishedContent)
    var imageMedia = content.Value<MediaWithCrops>("image");
    var image = imageMedia?.MediaUrl() ?? "";

    // imageLocation/gradient are Umbraco.DropDown.Flexible - try-catch for JSON
    var imageLocation = "left";
    try { imageLocation = (content.Value<string>("imageLocation") ?? "Left").ToLowerInvariant(); } catch { }

    var firstCurveMedia = content.Value<MediaWithCrops>("firstCurve");
    var firstCurve = firstCurveMedia?.MediaUrl() ?? "";

    // Image URLs with query-string cropping
    lowQualityImage = $"{image}?width=1000&height=516&mode=crop&quality=5";
    highQualityImage = $"{image}?width=1000&height=516&mode=crop&quality=80";

    var uniqueId = Guid.NewGuid().ToString("N")[..8];
    Html.AddScript("~/Scripts/heroItem.js", async: true);
}

What Changed:

Aspect v8 v17
Base class UmbracoViewPage<ContentModels.HeroItem> UmbracoViewPage<BlockGridItem>
Media access IPublishedContent + .Url property MediaWithCrops + .MediaUrl()
Image cropping Url.GetCropUrl(Model.Image, 1000, 516, quality:5) Query string ?width=1000&height=516&mode=crop&quality=5
Dropdown Direct Model.Value<string>() try-catch wrapper for JSON array deserialization
Unique IDs new Random().Next(0, 100000) Guid.NewGuid().ToString("N")[..8]
JS include Not present (inline <script>) Html.AddScript("~/Scripts/heroItem.js")
Null checks if (x != null) verbose pattern ?? "" null-coalescing
Line count 270 163 (40% reduction)

2B. videoFullWidth.cshtml -- Full Width Video

Shows: ColorPicker TrimStart pattern, media URL changes, simplified structure

v8 (DocTypeGridEditor/videoFullWidth.cshtml, 46 lines):

@inherits UmbracoViewPage<ContentModels.VideoFullWidth>
@using Dawoe.OEmbedPickerPropertyEditor.Models;
@{
    var description = Model.Value<string>("text");
    var textColor = Model.Value<string>("textColour");
    var internalVideo = Model.Value<IPublishedContent>("internalVideo");
    var cssClassVideo = "";
    if (Model.Value<string>("cssClassVideo") != null)
    {
        cssClassVideo = Model.Value<string>("cssClassVideo").ToString();
    }
}

<div class="@cssClassVideo">
    <section id="VFWSection">
        <p class="@pToadd col-md-12" style="color:#@textColor">@description</p>
        <video id="videobcg" preload="auto" autoplay loop="loop" muted="muted" volume="0">
            <source src="@internalVideo.Url" type="video/mp4">

v17 (blockgrid/Components/videoFullWidth.cshtml, 36 lines):

@inherits UmbracoViewPage<BlockGridItem>
@{
    var content = Model.Content;
    var description = content.Value<string>("text") ?? "";
    var textColor = content.Value<string>("textColour") ?? "";
    var cssClassVideo = content.Value<string>("cssClassVideo") ?? "";
    var internalVideo = content.Value<IPublishedContent>("internalVideo");
    var videoUrl = internalVideo?.Url() ?? "";

    // Ensure color has exactly one # prefix
    string FormatColor(string? c) => string.IsNullOrEmpty(c) ? "" : (c.StartsWith("#") ? c : "#" + c);
    var formattedTextColor = FormatColor(textColor);
}

<div class="@cssClassVideo">
    <section id="VFWSection">
        @if (!string.IsNullOrWhiteSpace(description))
        {
            <p class="@pToadd col-md-12" style="color:@formattedTextColor">@description</p>
        }
        <video id="videobcg" preload="auto" autoplay loop="loop" muted="muted" volume="0">
            <source src="@videoUrl" type="video/mp4">

What Changed:

Aspect v8 v17
Color handling style="color:#@textColor" (hardcoded #) FormatColor() helper ensures single # prefix
Video URL @internalVideo.Url (property) internalVideo?.Url() (extension, null-safe)
Null safety Manual null checks ?? "" throughout
OEmbed dependency Dawoe.OEmbedPickerPropertyEditor.Models Removed (not needed in v17)

2C. cardGridControls.cshtml -- Card Grid with Nested Items

Shows: BlockList iteration pattern replacing Nested Content

v8 (DocTypeGridEditor/cardGridControls.cshtml, 123 lines):

@inherits UmbracoViewPage<CardGridControls>
@{
    var items = Model.CardGridItems?.Where(x => x.IsVisible());
    var layoutShow = Model.Layout;
}

@foreach (var item in items.Where(x => x.Value<int>("Disable") != 1))
{
    var heading = item.Heading;           // Strongly-typed ModelsBuilder property
    var paragraph = item.Paragraph.ToString();
    var link = item.Link;                 // Strongly-typed
    var image = item.Image?.Url() ?? "";  // Strongly-typed
}

v17 (blockgrid/Components/cardGridControls.cshtml, 134 lines):

@inherits UmbracoViewPage<BlockGridItem>
@using Umbraco.Cms.Core.Models.Blocks
@{
    var content = Model.Content;
    var items = content.Value<IEnumerable<BlockListItem>>("cardGridItems")?.Where(x => x.Content.IsVisible());
    var layoutShow = content.Value<int>("layout");
}

@foreach (var block in items.Where(x => x.Content.Value<int>("Disable") != 1))
{
    var item = block.Content;
    var heading = item.Value<string>("heading");       // Dynamic property access
    var paragraph = item.Value<string>("paragraph");
    var link = item.Value<IEnumerable<Link>>("link");  // Dynamic
    var image = item.Value<IPublishedContent>("image")?.Url() ?? "";
}

What Changed:

Aspect v8 v17
Model type CardGridControls (ModelsBuilder) BlockGridItem (generic)
Nested items Model.CardGridItems (strongly-typed) content.Value<IEnumerable<BlockListItem>>("cardGridItems")
Item access item.Heading (property) item.Value<string>("heading") (dynamic)
Link access item.Link (strongly-typed) item.Value<IEnumerable<Link>>("link")
HTML structure Identical Identical (preserved)

2D. Calculator Icon Partial

Shows: Complete architectural redesign -- v8 inline CMS queries replaced by DI service layer

v8 (calculators/calcIcon/calculator.cshtml, ~560 lines):

@inherits UmbracoViewPage<calculatorViewModelIcon>
@using Progress.Core.ViewModels;
@using ClientDependency.Core.Mvc
@{
    Html.RequiresJs("/vendor/jquery-ui/jquery-ui.min.js", 4);
    Html.RequiresJs("/Scripts/calculatorIcon.js", 35, new { async = "async" });
    Html.RequiresCss("/vendor/jquery-ui/jquery-ui.min.css", 8);

    var currencySymbol = Umbraco.GetDictionaryValue("calculator.CurrencySymbol");
    var calcHeding = Umbraco.GetDictionaryValue("widget.calculatorHeading");
    // ... 15+ dictionary lookups inline

    var items = Model.Items;
    foreach (var item in items) {
        // Each loan item rendered with inline Razor + JS
    }
}

v17 (calculators/calculatorIcon.cshtml, ~298 lines):

@using Progress.Umbraco.Helpers
@inject www.Services.ICalculatorService CalculatorService
@inject Umbraco.Cms.Core.Web.IUmbracoContextAccessor UmbracoContextAccessor
@inject IDictionaryService Dictionary
@{
    var culture = System.Globalization.CultureInfo.CurrentCulture.ToString();
    var currencySymbol = culture.StartsWith("en-GB") ? "\u00a3" : "\u20ac";

    var typeOfLoanLabel = Dictionary.GetValue("Calc.TypeOfLoan") ?? "Type of Loan";
    // ...

    var config = CalculatorService.GetConfiguration(isHomepage);
    var loans = config?.Loans ?? new List<www.Services.LoanTypeDetails>();
    var selectedLoan = CalculatorService.GetLoanByHeading(dropdownSelectedValue, isHomepage);

    Html.AddScript("~/Scripts/calculatorIcon.js", async: true);
}

What Changed:

Aspect v8 v17
Model calculatorViewModelIcon (ViewModel) No model -- uses DI services
Data access Model.Items from controller CalculatorService.GetConfiguration() via DI
Dictionary Umbraco.GetDictionaryValue() @inject IDictionaryService
JS/CSS Html.RequiresJs() ClientDependency Html.AddScript()
Architecture Monolithic view with all logic Service layer (ICalculatorService) + thin view
Line count ~560 ~298 (47% reduction)

3. Complete DTGE Component Mapping

All 55 v8 DocTypeGridEditor front-end views (excluding Previews/ subfolder which contains backoffice-only preview templates) mapped to their v17 equivalents.

# v8 DocTypeGridEditor File v17 BlockGrid Component Status Key Patterns Notes
1 accordionButton.cshtml accordionButtonMain.cshtml Migrated BlockList, ColorPicker Renamed; also accordionButtonElement.cshtml split out
2 accordionControls.cshtml accordionControls.cshtml Migrated BlockList iteration Same name
3 anchor.cshtml anchor.cshtml Migrated Simple text prop Same name
4 announcementControls.cshtml announcementControls.cshtml Migrated BlockList, ColorPicker Same name
5 announcementItemScrollControls.cshtml announcementItemScrollControls.cshtml Migrated BlockList, animation Same name
6 barChart.cshtml barChart.cshtml Migrated BlockList of barChartItem Same name
7 barChartItem.cshtml barChartItem.cshtml Migrated ColorPicker, numeric Same name
8 buttonModal.cshtml buttonModal.cshtml Migrated RTE, modal, Links Same name
9 buttonWidgetControl.cshtml buttonWidgetControl.cshtml Migrated Links, ColorPicker Same name
10 cTAItem.cshtml cTAItem.cshtml Migrated MediaPicker3, Links, ColorPicker Same name
11 cardGridControls.cshtml cardGridControls.cshtml Migrated BlockList, MediaPicker, Links Same name; see Section 2C
12 CardItem.cshtml cardItem.cshtml Migrated MediaPicker3, Links, DropDown Case change: C to c
13 coOrdinate.cshtml coOrdinate.cshtml Migrated Lat/Long, Google Maps Same name
14 contactUsWidget.cshtml contactUsWidget.cshtml Migrated Site settings inject Same name
15 counter.cshtml counter.cshtml Migrated Numeric, animation Same name
16 ctaCurves.cshtml ctaCurves.cshtml Migrated MediaPicker3, Links, ColorPicker Same name
17 ctaText.cshtml ctaText.cshtml Migrated RTE, MediaPicker3, ColorPicker Same name
18 donutChart.cshtml donutChart.cshtml Migrated ColorPicker, numeric Same name
19 donutChartList.cshtml donutChartList.cshtml Migrated BlockList of donutChart Same name
20 facebookControls.cshtml facebookControls.cshtml Migrated Embed URL Same name
21 faqControls.cshtml faqControls.cshtml Migrated BlockList, accordion Same name
22 FaqItems.cshtml faqItems.cshtml Migrated BlockList child items Case change: F to f
23 faqWithSchema.cshtml faqWithSchemaList.cshtml Migrated Schema.org JSON-LD Renamed with List suffix
24 featureGridEditor.cshtml featureControls.cshtml Migrated BlockList, accordion UI Renamed: featureGridEditor to featureControls
25 flipCardControls.cshtml flipCardControls.cshtml Migrated BlockList, CSS 3D flip Same name
26 footerListControl.cshtml footerListControl.cshtml Migrated BlockList, Links Same name
27 headingItem.cshtml headingItem.cshtml Migrated Simple text/style Same name
28 heroItem.cshtml heroItem.cshtml Migrated MediaPicker3, DropDown, Links Same name; see Section 2A
29 iconListOptContactInfoControl.cshtml iconListOptContactInfoControl.cshtml Migrated BlockList, FA icons Same name
30 imageGalleryControl.cshtml imageGalleryControl.cshtml Migrated MediaPicker3 multi Same name
31 imageListControl.cshtml imageListControl.cshtml Migrated BlockList of images Same name
32 imageWithLink.cshtml imageWithLink.cshtml Migrated MediaPicker3, Link Same name
33 InstagramControls.cshtml instagramControls.cshtml Migrated Embed/API Case change: I to i
34 linkListControl.cshtml linkListControl.cshtml Migrated BlockList, Links Same name
35 LoanInputCTA.cshtml loanInputCTA.cshtml Migrated Calculator link, amount input Case change: L to l
36 loginStatusWidget.cshtml loginStatusWidget.cshtml Migrated Member auth inject Same name; delegates to loginStatusElement.cshtml
37 loginWidget.cshtml loginWidget.cshtml Migrated Member auth inject Same name; delegates to loginElement.cshtml
38 mainLoanBoxWidget.cshtml mainLoanBoxWidget.cshtml Migrated Dispatcher to loanbox modes Same name
39 numberedListControl.cshtml numberedListControl.cshtml Migrated BlockList, ordered list Same name
40 parallaxImageItem.cshtml parallaxImageItem.cshtml Migrated MediaPicker3, scroll effect Same name
41 qrCodeItem.cshtml qrCodeItem.cshtml Migrated URL to QR Same name
42 quickLinkDropDownControl.cshtml quickLinkDropDownControl.cshtml Migrated Links, dropdown UI Same name
43 releaseNotesWidget.cshtml releaseNotesWidget.cshtml Migrated Dynamic content query Same name
44 slider.cshtml gridslider.cshtml Migrated Slick carousel, MediaPicker3 Renamed to gridslider to avoid clash with other slider.cshtml
45 spotlightControls.cshtml spotlightControls.cshtml Migrated BlockList, image/link grid Same name
46 spotlightGridControls.cshtml spotlightGridControls.cshtml Migrated Multi-column spotlight Same name
47 staffMemberControl.cshtml staffMemberControl.cshtml Migrated MediaPicker3, staff bio Same name
48 stickyNav.cshtml stickyNav.cshtml Migrated Scroll-based navigation Same name
49 stripedList.cshtml stripedListControl.cshtml Migrated BlockList, alternating rows Renamed with Control suffix
50 testimonialCardItem.cshtml testimonialCardItem.cshtml Migrated MediaPicker3, quote text Same name
51 trustpilotWidget.cshtml trustpilotWidget.cshtml Migrated Trustpilot embed Same name
52 twitterControls.cshtml twitterControls.cshtml Migrated Twitter embed Same name
53 videoFullWidth.cshtml videoFullWidth.cshtml Migrated MediaPicker3, ColorPicker Same name; see Section 2B
54 videoPopOut.cshtml videoPopout.cshtml Migrated Video modal popup Case change: O to o in "Popout"
55 youTubeControls.cshtml youTubeControls.cshtml Migrated YouTube embed Same name

Summary Statistics

  • Total v8 DTGE front-end views: 55
  • Migrated to v17: 55 (100%)
  • Same name: 43 (78%)
  • Renamed: 7 (13%) -- featureGridEditor to featureControls, slider to gridslider, stripedList to stripedListControl, faqWithSchema to faqWithSchemaList, accordionButton to accordionButtonMain
  • Case changes only: 5 (9%) -- CardItem, FaqItems, InstagramControls, LoanInputCTA, videoPopOut

Previews Subfolder

The Previews/ subfolder contains 36 backoffice-only preview templates. These are not needed in v17 because BlockGrid has its own built-in block preview system. They are intentionally not migrated.


4. Grid Sub-Component Mapping

4a. Calculator Partials

v8 calculators used a ViewModel pattern (calculatorViewModelXxx) with controller-provided data. v17 uses ICalculatorService DI injection.

# v8 File (calculators/) v17 File (calculators/) Status Notes
1 calcIcon/calculator.cshtml calculatorIcon.cshtml Migrated See Section 2D; service layer rewrite
2 calcInput/calculator.cshtml calculatorInput.cshtml Migrated Input-based calculator with sliders
3 calcInputSmall/calculator.cshtml calculatorInputSmall.cshtml Migrated Compact input variant
4 calcInputVarRate/calculator.cshtml calculatorInputVarRate.cshtml Migrated Variable rate calculator
5 calcLarge/calculator.cshtml calculatorLarge.cshtml Migrated Full-size calculator
6 calcSmall/calculator.cshtml CalculatorSmall.cshtml Migrated Small widget calculator
-- (no v8 equivalent) _calculatorTab.cshtml New Shared tab partial extracted from calculators

Key Architecture Change: v8 had each calculator in its own subfolder (calcIcon/calculator.cshtml), v17 flattens to a single directory with descriptive names (calculatorIcon.cshtml). All v8 Progress.Core.ViewModels.calculatorViewModelXxx view models replaced by ICalculatorService DI.

4b. LoanBox Partials

v8 uses a dispatcher (LoanBoxesWidgetNew.cshtml) that routes to sub-partials based on Model.value. v17 dispatcher is grid_element_loanboxescompletegrideditor.cshtml.

# v8 File (Grid/Editors/LoanBoxes/) v17 File (loanboxes/) Status Notes
1 LoanBoxesWidgetNew.cshtml (dispatcher in grid_element_loanboxescompletegrideditor.cshtml) Migrated Dispatcher logic moved to grid element view
2 Boxes.cshtml _LoanBoxesBoxes.cshtml Migrated Card grid with modals
3 Flipcards.cshtml _LoanBoxesFlipCards.cshtml Migrated CSS 3D flip cards
4 Tabs.cshtml (inline in grid_element_loanboxescompletegrideditor.cshtml) Migrated Tabs mode built into dispatcher
5 accordion.cshtml _LoanBoxesAccordion.cshtml Migrated Bootstrap collapse panels
6 accordionContact.cshtml _accordionContact.cshtml Migrated Contact info sub-partial

Key Change: v8 LoanBoxesWidgetNew.cshtml dispatched via @Html.Partial() calls. v17 grid_element_loanboxescompletegrideditor.cshtml dispatches via @await Html.PartialAsync().

4c. News Partials

v8 dispatcher is newsWidgetNew.cshtml routing by Model.value.image property. v17 dispatcher is grid_element_newscompletegrideditor.cshtml.

# v8 File (Grid/Editors/News/) v17 File (news/) Status Notes
1 newsWidgetNew.cshtml (dispatcher in grid_element_newscompletegrideditor.cshtml) Migrated Dispatcher logic in grid element
2 slider.cshtml slider.cshtml Migrated News slider carousel
3 sliderDetailed.cshtml sliderDetailed.cshtml Migrated Detailed slider variant
4 sliderImage.cshtml sliderImage.cshtml Migrated Image-focused slider
5 NewsList.cshtml NewsList.cshtml Migrated List view of news items
6 topStory.cshtml topStory.cshtml Migrated Top story highlight layout
7 topStory5Articles.cshtml topStory5Articles.cshtml Migrated Top story + 5 articles
8 4AcrossNews.cshtml 4AcrossNews.cshtml Migrated 4-column news grid

All news sub-partials preserved with identical names.

4d. Testimonial Partials

v8 dispatcher is TestimonialsWidgetNew.cshtml routing by layout alias. v17 dispatcher is grid_element_testimonialcompletegrideditor.cshtml.

# v8 File (Grid/Editors/Testimonials/) v17 Equivalent Status Notes
1 TestimonialsWidgetNew.cshtml grid_element_testimonialcompletegrideditor.cshtml Migrated Dispatcher consolidated
2 list.cshtml (inline in dispatcher) Migrated List mode rendered within grid element
3 slider.cshtml (inline in dispatcher) Migrated Slider mode rendered within grid element
4 sliderInner.cshtml testimonialCardItem.cshtml Migrated Individual testimonial card

Key Change: v8 had separate sub-partials for each layout mode. v17 consolidates the testimonial rendering logic into the dispatcher view (grid_element_testimonialcompletegrideditor.cshtml), with testimonialCardItem.cshtml for individual cards.

4e. GlobalAddress Partials

v8 dispatcher is GlobalAddressWidget.cshtml. v17 dispatcher is grid_element_globaladdresscompletegrideditor.cshtml.

# v8 File (Grid/Editors/GlobalAddress/) v17 File (blockgrid/Components/GlobalAddress/) Status Notes
1 GlobalAddressWidget.cshtml (dispatcher in grid_element_globaladdresscompletegrideditor.cshtml) Migrated Dispatcher in parent dir
2 AddressList.cshtml AddressList.cshtml Migrated Address list display
3 addressNoLables.cshtml addressNoLables.cshtml Migrated Address without labels (typo preserved)
4 footerOld.cshtml footerOld.cshtml Migrated Legacy footer format
5 OpeningTimesNoLabels.cshtml OpeningTimesNoLabels.cshtml Migrated Opening times compact
6 slider.cshtml slider.cshtml Migrated Address slider carousel
7 twoCol.cshtml twoCol.cshtml Migrated Two-column layout

All GlobalAddress sub-partials preserved with identical names in a GlobalAddress/ subfolder under Components. Also includes GlobalAddressWidget.cshtml in the v17 subfolder for the inner dispatcher.

4f. Calculator Slider Components (calcGridSlider)

These are slide types used within the grid slider carousel (DTGE slider.cshtml / v17 gridslider.cshtml).

# v8 File (calcGridSlider/) v17 File (calcGridSlider/) Status Notes
1 pictureSlide.cshtml pictureSlide.cshtml Migrated Image slide
2 pictureTextBox.cshtml pictureTextBox.cshtml Migrated Image + text overlay
3 splitPictureSlide.cshtml splitPictureSlide.cshtml Migrated Split layout slide
4 internalVideo.cshtml internalVideo.cshtml Migrated Self-hosted video slide
5 vimeoVideo.cshtml vimeoVideo.cshtml Migrated Vimeo embed slide
6 youTubeVideo.cshtml youTubeVideo.cshtml Migrated YouTube embed slide
7 splitPictureSlidePrevew.cshtml (not migrated) Skipped Backoffice preview only; not needed in v17

All front-end slider partials preserved with identical names. Preview file intentionally excluded.

4g. Home Slider Components

v8 home slider sub-partials mapped to v17 home/ directory.

# v8 File (home/) v17 File (home/) Status Notes
1 slider.cshtml slider.cshtml Migrated Home page carousel dispatcher
2 pictureSlide.cshtml pictureSlide.cshtml Migrated Picture slide
3 pictureTextBox.cshtml pictureTextBox.cshtml Migrated Picture + text slide
4 internalVideo.cshtml internalVideo.cshtml Migrated Self-hosted video slide
5 vimeoVideo.cshtml vimeoVideo.cshtml Migrated Vimeo slide
6 youTubeVideo.cshtml youTubeVideo.cshtml Migrated YouTube slide

All home slider sub-partials preserved with identical names.


5. V17-Only Components

These v17 BlockGrid component views have no direct v8 DTGE equivalent. They were either created by the migration tool for grid element types, converted from v8 macros, or are new architectural additions.

5a. Grid Element Types (migration-generated)

Created by the migration tool's GenerateForContentElementType() to wrap v8 grid editors that stored content as macro parameters or raw JSON rather than as DTGE doc types.

v17 File Origin Purpose
grid_element_calculatorsgrideditor.cshtml v8 Calculators grid editor macro Calculator dispatcher
grid_element_newscompletegrideditor.cshtml v8 News grid editor macro News dispatcher
grid_element_loanboxescompletegrideditor.cshtml v8 LoanBoxes grid editor macro LoanBox dispatcher
grid_element_testimonialcompletegrideditor.cshtml v8 Testimonials grid editor macro Testimonial dispatcher
grid_element_globaladdresscompletegrideditor.cshtml v8 GlobalAddress grid editor macro Address dispatcher
grid_element_faq_accordion_home.cshtml v8 psFaqAccordion macro Home FAQ accordion widget
grid_element_largegooglemap.cshtml v8 largeGoogleMap grid editor Large Google Map widget
grid_element_largeleafletmap.cshtml v8 largeLeafletMap grid editor Leaflet map widget
grid_element_socialfooter.cshtml v8 socialFooter grid editor Social media footer links
grid_element_stickysocial.cshtml v8 stickySocial grid editor Sticky social sharing bar
grid_element_cardcontrol.cshtml v8 cardControl grid editor Simple card with content
grid_element_services_list.cshtml v8 services grid editor Dynamic child page list
grid_element_services_list_image.cshtml v8 services_list_image grid editor Services with images
grid_element_psdataprotectionname.cshtml v8 Data Protection macro GDPR: controller name
grid_element_psdataprotectiondpo.cshtml v8 Data Protection macro GDPR: DPO details
grid_element_psdataprotectionspecificstatements.cshtml v8 Data Protection macro GDPR: specific statements
grid_element_psdataprotectionsummarytable.cshtml v8 Data Protection macro GDPR: summary table
grid_element_psdataprotectionweare.cshtml v8 Data Protection macro GDPR: "We Are" section

5b. Grid Built-in Editor Types

Created for v8's built-in grid editors (RTE, Media, Embed, Quote) which had no DTGE view -- they were rendered inline by the grid framework.

v17 File Origin
grid_builtin_rte.cshtml v8 built-in Rich Text Editor grid cell
grid_builtin_media.cshtml v8 built-in Media grid cell
grid_builtin_embed.cshtml v8 built-in Embed grid cell
grid_builtin_quote.cshtml v8 built-in Quote grid cell
grid_builtin_submenu.cshtml v8 SubMenu grid editor

5c. Macro-to-Element Conversions

v8 macros that were converted to BlockGrid element types as part of the migration.

v17 File v8 Macro Origin Purpose
audioTagElement.cshtml AudioTag macro Audio player
cookiesElement.cshtml Cookies macro Cookie consent widget
ctaElement.cshtml CTA macro Call-to-action block
embedElement.cshtml Embed macro oEmbed content
faqElement.cshtml FAQ macro FAQ block
headingElement.cshtml Heading macro Section heading
heroElement.cshtml Hero macro Hero banner block
linkListElement.cshtml LinkList macro Link list block
loginElement.cshtml Login macro Member login form
loginStatusElement.cshtml LoginStatus macro Logged-in member status
mediaElement.cshtml Media macro Media display
registerElement.cshtml Register macro Member registration form
rteElement.cshtml RTE macro Rich text block
umbracoFormElement.cshtml renderUmbracoForm macro Umbraco Forms rendering

5d. New v17 Components (no v8 source)

Entirely new components created for v17 functionality or refactoring.

v17 File Purpose
_GridLayout.cshtml Grid layout renderer (framework component)
_CardIcon.cshtml Card icon sub-partial (extracted helper)
_CardItemContent.cshtml Card content sub-partial (extracted helper)
_CardText.cshtml Card text sub-partial (extracted helper)
blockListCallToAction.cshtml BlockList-based CTA element type
calculatorControls.cshtml Calculator controls container
mainCalculatorControls.cshtml Top-level calculator container
careerWidgetControl.cshtml Career listings widget
careerWidgetListControl.cshtml Career listings list mode
comparsionTable.cshtml Comparison table (typo preserved from v8 alias)
fancyVideo.cshtml Video with poster image overlay
footerLinks.cshtml Footer navigation links
googleMap.cshtml Single Google Map component
header.cshtml Simple header block
spotlightControl.cshtml Spotlight wrapper (singular, no layout)
staffMembersControl.cshtml Staff members collection wrapper
styledListControl.cshtml Styled list with heading/paragraph items
textSlide.cshtml Text overlay slide (from calcGridSlider/pictureTextBox)
PictureSlideGrid.cshtml Grid variant of pictureSlide
splitPictureSlider.cshtml Split picture slider element type
gridVimeoSlide.cshtml Grid-context Vimeo slide variant
gridinternalvideoslide.cshtml Grid-context internal video slide variant
youTubeSlideGrid.cshtml Grid-context YouTube slide variant
vimeoSlide.cshtml Vimeo slide for slider context
youTubeSlide.cshtml YouTube slide for slider context
internalVideoSlide.cshtml Internal video slide for slider context
accordionButtonElement.cshtml Accordion button element (split from v8 accordionButton)
faqWithSchemaList.cshtml FAQ with Schema.org (renamed from faqWithSchema)
donutChartItem.cshtml Individual donut chart item (nested in donutChartList)
loanInputCTA.cshtml Loan input call-to-action

6. Gaps Analysis

6a. V8 Files NOT Migrated (Intentional)

v8 File Reason
DocTypeGridEditor/Previews/*.cshtml (36 files) Backoffice preview templates -- v17 BlockGrid has built-in preview system
calcGridSlider/splitPictureSlidePrevew.cshtml Backoffice preview -- typo in name, not needed in v17

6b. V8 Dispatcher Files (Logic Absorbed)

These v8 files are not directly present in v17 because their dispatching logic was absorbed into grid_element_* views:

v8 File Absorbed Into
LoanBoxes/LoanBoxesWidgetNew.cshtml grid_element_loanboxescompletegrideditor.cshtml + mainLoanBoxWidget.cshtml
News/newsWidgetNew.cshtml grid_element_newscompletegrideditor.cshtml
Testimonials/TestimonialsWidgetNew.cshtml grid_element_testimonialcompletegrideditor.cshtml
GlobalAddress/GlobalAddressWidget.cshtml grid_element_globaladdresscompletegrideditor.cshtml

6c. V8 Sub-Partials Consolidated

v8 File Consolidation
Testimonials/list.cshtml Logic inline in grid_element_testimonialcompletegrideditor.cshtml
Testimonials/slider.cshtml Logic inline in grid_element_testimonialcompletegrideditor.cshtml
Testimonials/sliderInner.cshtml Became testimonialCardItem.cshtml
LoanBoxes/Tabs.cshtml Logic inline in grid_element_loanboxescompletegrideditor.cshtml

6d. Coverage Summary

Category v8 Count v17 Count Coverage
DTGE front-end views 55 55 100%
DTGE preview views 36 0 N/A (intentionally skipped)
Calculator partials 6 7 (+1 shared tab) 100%
LoanBox partials 6 4 (+dispatcher) 100% (consolidated)
News partials 8 7 (+dispatcher) 100%
Testimonial partials 4 2 (+dispatcher) 100% (consolidated)
GlobalAddress partials 7 7 (+dispatcher) 100%
calcGridSlider partials 7 6 (preview excluded) 100%
Home slider partials 6 6 100%
TOTAL front-end 99 94 + dispatchers 100%
V17-only new components -- ~49 New functionality

All v8 front-end component views have been migrated. Zero gaps in user-facing functionality.

Migration documentation by Double for Progress Credit Union