diff --git a/uTPro/Common/uTPro.Common/Models/CMS/UTpro__ContentLayout.generated.cs b/uTPro/Common/uTPro.Common/Models/CMS/UTpro__ContentLayout.generated.cs new file mode 100644 index 0000000..a6f70f4 --- /dev/null +++ b/uTPro/Common/uTPro.Common/Models/CMS/UTpro__ContentLayout.generated.cs @@ -0,0 +1,93 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Umbraco.ModelsBuilder.Embedded v16.5.0+8b2c22a +// +// Changes to this file will be lost if the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Linq.Expressions; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Infrastructure.ModelsBuilder; +using Umbraco.Cms.Core; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Web.Common.PublishedModels +{ + // Mixin Content Type with alias "uTPro__ContentLayout" + /// Content Layout + public partial interface IUTpro__ContentLayout : IPublishedContent + { + /// Bottom Component + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel BottomComponent { get; } + + /// Top Component + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel TopComponent { get; } + } + + /// Content Layout + [PublishedModel("uTPro__ContentLayout")] + public partial class UTpro__ContentLayout : PublishedContentModel, IUTpro__ContentLayout + { + // helpers +#pragma warning disable 0109 // new is redundant + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + public new const string ModelTypeAlias = "uTPro__ContentLayout"; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + public new const PublishedItemType ModelItemType = PublishedItemType.Content; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public new static IPublishedContentType GetModelContentType(IPublishedContentTypeCache contentTypeCache) + => PublishedModelUtility.GetModelContentType(contentTypeCache, ModelItemType, ModelTypeAlias); + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public static IPublishedPropertyType GetModelPropertyType(IPublishedContentTypeCache contentTypeCache, Expression> selector) + => PublishedModelUtility.GetModelPropertyType(GetModelContentType(contentTypeCache), selector); +#pragma warning restore 0109 + + private IPublishedValueFallback _publishedValueFallback; + + // ctor + public UTpro__ContentLayout(IPublishedContent content, IPublishedValueFallback publishedValueFallback) + : base(content, publishedValueFallback) + { + _publishedValueFallback = publishedValueFallback; + } + + // properties + + /// + /// Bottom Component + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType("bottomComponent")] + public virtual global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel BottomComponent => GetBottomComponent(this, _publishedValueFallback); + + /// Static getter for Bottom Component + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public static global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel GetBottomComponent(IUTpro__ContentLayout that, IPublishedValueFallback publishedValueFallback) => that.Value(publishedValueFallback, "bottomComponent"); + + /// + /// Top Component + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType("topComponent")] + public virtual global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel TopComponent => GetTopComponent(this, _publishedValueFallback); + + /// Static getter for Top Component + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public static global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel GetTopComponent(IUTpro__ContentLayout that, IPublishedValueFallback publishedValueFallback) => that.Value(publishedValueFallback, "topComponent"); + } +} diff --git a/uTPro/Common/uTPro.Common/Models/CMS/UTpro__PageHome.generated.cs b/uTPro/Common/uTPro.Common/Models/CMS/UTpro__PageHome.generated.cs index a1637a7..f712792 100644 --- a/uTPro/Common/uTPro.Common/Models/CMS/UTpro__PageHome.generated.cs +++ b/uTPro/Common/uTPro.Common/Models/CMS/UTpro__PageHome.generated.cs @@ -20,7 +20,7 @@ namespace Umbraco.Cms.Web.Common.PublishedModels { /// Page Home [PublishedModel("uTPro__PageHome")] - public partial class UTpro__PageHome : PublishedContentModel, IGlobalPageHeadMetaSetting, IGlobalPageHeadSocialMetaSetting, IGlobalPageNavigationConfigSettingForHomePage, IGlobalPageNavigationSetting, IGlobalPageScriptSetting, IGlobalPageSitemapSetting + public partial class UTpro__PageHome : PublishedContentModel, IGlobalPageHeadMetaSetting, IGlobalPageHeadSocialMetaSetting, IGlobalPageNavigationConfigSettingForHomePage, IGlobalPageNavigationSetting, IGlobalPageScriptSetting, IGlobalPageSitemapSetting, IUTpro__ContentLayout { // helpers #pragma warning disable 0109 // new is redundant @@ -284,5 +284,21 @@ public UTpro__PageHome(IPublishedContent content, IPublishedValueFallback publis [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] [ImplementPropertyType("sitemapXmlPriority")] public virtual decimal SitemapXmlPriority => global::Umbraco.Cms.Web.Common.PublishedModels.GlobalPageSitemapSetting.GetSitemapXmlPriority(this, _publishedValueFallback); + + /// + /// Bottom Component + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType("bottomComponent")] + public virtual global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel BottomComponent => global::Umbraco.Cms.Web.Common.PublishedModels.UTpro__ContentLayout.GetBottomComponent(this, _publishedValueFallback); + + /// + /// Top Component + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType("topComponent")] + public virtual global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel TopComponent => global::Umbraco.Cms.Web.Common.PublishedModels.UTpro__ContentLayout.GetTopComponent(this, _publishedValueFallback); } } diff --git a/uTPro/Common/uTPro.Common/Models/CMS/UTpro__PageStandard.generated.cs b/uTPro/Common/uTPro.Common/Models/CMS/UTpro__PageStandard.generated.cs index b747086..1029759 100644 --- a/uTPro/Common/uTPro.Common/Models/CMS/UTpro__PageStandard.generated.cs +++ b/uTPro/Common/uTPro.Common/Models/CMS/UTpro__PageStandard.generated.cs @@ -20,7 +20,7 @@ namespace Umbraco.Cms.Web.Common.PublishedModels { /// Page Standard [PublishedModel("uTPro__PageStandard")] - public partial class UTpro__PageStandard : PublishedContentModel, IGlobalPageHeadMetaSetting, IGlobalPageHeadSocialMetaSetting, IGlobalPageScriptSetting, IGlobalPageSitemapSetting + public partial class UTpro__PageStandard : PublishedContentModel, IGlobalPageHeadMetaSetting, IGlobalPageHeadSocialMetaSetting, IGlobalPageScriptSetting, IGlobalPageSitemapSetting, IUTpro__ContentLayout { // helpers #pragma warning disable 0109 // new is redundant @@ -236,5 +236,21 @@ public UTpro__PageStandard(IPublishedContent content, IPublishedValueFallback pu [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] [ImplementPropertyType("sitemapXmlPriority")] public virtual decimal SitemapXmlPriority => global::Umbraco.Cms.Web.Common.PublishedModels.GlobalPageSitemapSetting.GetSitemapXmlPriority(this, _publishedValueFallback); + + /// + /// Bottom Component + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType("bottomComponent")] + public virtual global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel BottomComponent => global::Umbraco.Cms.Web.Common.PublishedModels.UTpro__ContentLayout.GetBottomComponent(this, _publishedValueFallback); + + /// + /// Top Component + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder.Embedded", "16.5.0+8b2c22a")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType("topComponent")] + public virtual global::Umbraco.Cms.Core.Models.Blocks.BlockGridModel TopComponent => global::Umbraco.Cms.Web.Common.PublishedModels.UTpro__ContentLayout.GetTopComponent(this, _publishedValueFallback); } } diff --git a/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentItemExtension.cs b/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentItemExtension.cs index 1b0b5f6..a077ca3 100644 --- a/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentItemExtension.cs +++ b/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentItemExtension.cs @@ -24,7 +24,10 @@ public interface ICurrentItemExtension IPublishedContent? PageHome { get; } IPublishedContent? PageErrors { get; } } - internal class CurrentItemExtension : ICurrentItemExtension, IDisposable + internal class CurrentItemExtension( + ILogger logger, + ICurrentSiteExtension currentSite + ) : ICurrentItemExtension, IDisposable { ~CurrentItemExtension() { @@ -46,19 +49,8 @@ protected virtual void Dispose(bool disposing) // free native resources if there are any. } - readonly ICurrentSiteExtension _currentSite; - readonly ILogger _logger; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public CurrentItemExtension( - ILogger logger, - ICurrentSiteExtension currentSite) -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - { - _logger = logger; - _currentSite = currentSite; - - } + readonly ICurrentSiteExtension _currentSite = currentSite; + readonly ILogger _logger = logger; public GlobalRoot Root { @@ -73,10 +65,7 @@ public GlobalFolderSites FolderSite get { var folderSite = this.PageHome?.Parent() ?? null; - if (folderSite == null) - { - folderSite = (GlobalFolderSites)GetItemByAlias(this.PageHome, GlobalFolderSites.ModelTypeAlias, true); - } + folderSite ??= (GlobalFolderSites)GetItemByAlias(this.PageHome, GlobalFolderSites.ModelTypeAlias, true); return folderSite ?? throw new Exception(nameof(GlobalFolderSites) + " is null"); } } @@ -105,19 +94,12 @@ public IPublishedContent? Current { get { - IPublishedContent? currentItem = null; - if (_currentSite.UContext.PublishedRequest?.PublishedContent != null) - { - currentItem = _currentSite.UContext.PublishedRequest?.PublishedContent; - } - else - { - currentItem = this.PageHome; - } - return currentItem; + var published = _currentSite.UContext.PublishedRequest?.PublishedContent; + return published ?? this.PageHome; } } + public IPublishedContent? PageHome { get @@ -181,9 +163,7 @@ public IPublishedContent? PageErrors private IPublishedContent GetItemByAlias(IPublishedContent? item, string alias, bool isFirst) { // Start from provided item - var current = item; - if (current == null) - throw new Exception("Not found item: " + alias); + var current = item ?? throw new Exception("Not found item: " + alias); // quick check if (string.Equals(current.ContentType?.Alias, alias, StringComparison.OrdinalIgnoreCase)) @@ -231,7 +211,7 @@ private static (string, string?) GetIdParent(string pathId, bool isRoot = false) if (pathId.StartsWith("-1", StringComparison.Ordinal)) { int firstComma = pathId.IndexOf(','); - pathIds = (firstComma >= 0 && firstComma + 1 < pathId.Length) ? pathId.Substring(firstComma + 1) : string.Empty; + pathIds = (firstComma >= 0 && firstComma + 1 < pathId.Length) ? pathId[(firstComma + 1)..] : string.Empty; } if (string.IsNullOrEmpty(pathIds)) @@ -240,7 +220,7 @@ private static (string, string?) GetIdParent(string pathId, bool isRoot = false) if (isRoot) { int firstComma = pathIds.IndexOf(','); - var root = firstComma >= 0 ? pathIds.Substring(0, firstComma) : pathIds; + var root = firstComma >= 0 ? pathIds[..firstComma] : pathIds; return (root ?? string.Empty, pathIds); } @@ -257,7 +237,7 @@ private static (string, string?) GetIdParent(string pathId, bool isRoot = false) } else { - parent = pathIds.Substring(0, lastComma); + parent = pathIds[..lastComma]; } return (parent, pathIds); } diff --git a/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentSiteExtension.cs b/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentSiteExtension.cs index 1aca9b9..17184f2 100644 --- a/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentSiteExtension.cs +++ b/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentSiteExtension.cs @@ -77,10 +77,7 @@ public CultureInfo CurrentCulture { get { - if (this._currentCulture == null) - { - this._currentCulture = Thread.CurrentThread.CurrentCulture; - } + this._currentCulture ??= Thread.CurrentThread.CurrentCulture; return this._currentCulture; } } @@ -129,10 +126,7 @@ public IUmbracoContext UContext { get { - if (this._umbracoContext == null) - { - this._umbracoContext = _umbracoContextFactory.EnsureUmbracoContext().UmbracoContext; - } + this._umbracoContext ??= _umbracoContextFactory.EnsureUmbracoContext().UmbracoContext; return this._umbracoContext ?? throw new Exception("UmbracoContext is null"); } @@ -166,8 +160,8 @@ public string GetDictionaryValue(string key, string valueDefault = "", bool show } // Simple in-memory cache for all domains to reduce repeated UContext access - private static readonly object _domainsLock = new object(); - private static IEnumerable _cachedAllDomains = Enumerable.Empty(); + private static readonly Lock _domainsLock = new(); + private static IEnumerable _cachedAllDomains = []; private static DateTime _cachedAllDomainsExpires = DateTime.MinValue; private const int CachedAllDomainsSeconds = 60; @@ -181,7 +175,7 @@ public Task> GetDomains(bool isGetAll) return Task.FromResult(_cachedAllDomains); } - var all = UContext?.Domains?.GetAll(true) ?? new List(); + var all = UContext?.Domains?.GetAll(true) ?? []; lock (_domainsLock) { _cachedAllDomains = all; @@ -192,7 +186,7 @@ public Task> GetDomains(bool isGetAll) var idItem = this.GetItem().Current?.Id; var domain = UContext?.Domains?.GetAssigned(idItem ?? 0, true); - return Task.FromResult(domain ?? new List()); + return Task.FromResult(domain ?? []); } public void SetCurrentCulture(CultureInfo cul) => this._currentCulture = cul; @@ -205,11 +199,11 @@ public string GetUrlWithCulture(IPublishedContent content, string? culture = nul if (domain != null) { - var domainUrl = domain.Name.StartsWith("/") - || domain.Name.StartsWith("http://", StringComparison.OrdinalIgnoreCase) - || domain.Name.StartsWith("https://", StringComparison.OrdinalIgnoreCase) - ? domain.Name - : "https://" + domain.Name; + var domainUrl = !(domain.Name.StartsWith('/') + || domain.Name.StartsWith("http://", StringComparison.OrdinalIgnoreCase) + || domain.Name.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) + ? "https://" + domain.Name + : domain.Name; var uri = new Uri(domainUrl, UriKind.RelativeOrAbsolute); var segment = uri.AbsolutePath.Trim('/'); diff --git a/uTPro/Extension/uTPro.Extension/ContentExtensions.cs b/uTPro/Extension/uTPro.Extension/ContentExtensions.cs new file mode 100644 index 0000000..db76439 --- /dev/null +++ b/uTPro/Extension/uTPro.Extension/ContentExtensions.cs @@ -0,0 +1,21 @@ +using System.Net.NetworkInformation; +using Umbraco.Cms.Core.Models.PublishedContent; +using System.Linq; + +namespace uTPro.Extension +{ + public static class ContentExtensions + { + public static T? GetInherited(this IPublishedContent content, string alias) + { + var node = content.AncestorsOrSelf() + .FirstOrDefault(x => x.HasValue(alias)); + + if (node == null) + return default; + + return node.Value(alias); + } + } + +} diff --git a/uTPro/Project/uTPro.Project.Web.Configure/CustomBlockPreviewLocationExpander.cs b/uTPro/Project/uTPro.Project.Web.Configure/CustomBlockPreviewLocationExpander.cs index 4fb931b..c0f3b0a 100644 --- a/uTPro/Project/uTPro.Project.Web.Configure/CustomBlockPreviewLocationExpander.cs +++ b/uTPro/Project/uTPro.Project.Web.Configure/CustomBlockPreviewLocationExpander.cs @@ -25,29 +25,25 @@ namespace uTPro.Project.Web.Configure { - public class CustomBlockPreviewService : BlockPreviewService + public class CustomBlockPreviewService( + ITempDataProvider tempDataProvider, + IViewComponentHelperWrapper viewComponentHelperWrapper, + IRazorViewEngine razorViewEngine, + ITypeFinder typeFinder, + BlockEditorConverter blockEditorConverter, + IViewComponentSelector viewComponentSelector, + IPublishedValueFallback publishedValueFallback, + IOptions options, + IJsonSerializer jsonSerializer, + IContentTypeService contentTypeService, + IDataTypeService dataTypeService, + AppCaches appCaches, + IWebHostEnvironment webHostEnvironment, + IBlockEditorElementTypeCache elementTypeCache, + ILogger logger) : BlockPreviewService(tempDataProvider, viewComponentHelperWrapper, razorViewEngine, typeFinder, blockEditorConverter, viewComponentSelector, publishedValueFallback, options, jsonSerializer, contentTypeService, dataTypeService, appCaches, webHostEnvironment, elementTypeCache, logger) { - IRazorViewEngine _razorViewEngine; - public CustomBlockPreviewService( - ITempDataProvider tempDataProvider, - IViewComponentHelperWrapper viewComponentHelperWrapper, - IRazorViewEngine razorViewEngine, - ITypeFinder typeFinder, - BlockEditorConverter blockEditorConverter, - IViewComponentSelector viewComponentSelector, - IPublishedValueFallback publishedValueFallback, - IOptions options, - IJsonSerializer jsonSerializer, - IContentTypeService contentTypeService, - IDataTypeService dataTypeService, - AppCaches appCaches, - IWebHostEnvironment webHostEnvironment, - IBlockEditorElementTypeCache elementTypeCache, - ILogger logger) - : base(tempDataProvider, viewComponentHelperWrapper, razorViewEngine, typeFinder, blockEditorConverter, viewComponentSelector, publishedValueFallback, options, jsonSerializer, contentTypeService, dataTypeService, appCaches, webHostEnvironment, elementTypeCache, logger) - { - _razorViewEngine = razorViewEngine; - } + readonly IRazorViewEngine _razorViewEngine = razorViewEngine; + protected override ViewEngineResult? GetViewResult(BlockPreviewContext context) { var blockGrid = CustomPathViews.GetPathViewBlockGridPreview("~/Views/Partials/blockgrid/Components/" + context.ContentAlias, isCheckSiteName: false); @@ -168,7 +164,7 @@ public static class CustomPathViews { // Basic sanitization: remove leading slashes and keep only filename part to avoid traversal fileName = fileName.TrimStart('/', '\\'); - if (fileName.IndexOfAny(new[] { '\\', '/' }) >= 0) + if (fileName.IndexOfAny(['\\', '/']) >= 0) { fileName = Path.GetFileName(fileName); } @@ -217,8 +213,8 @@ public static (string, string) GetSiteAndFileName(string viewName, string siteNa var idx = viewName.IndexOf(prefix, StringComparison.OrdinalIgnoreCase); if (idx > 0) { - var parsedSite = viewName.Substring(0, idx); - var parsedFile = idx + prefix.Length < viewName.Length ? viewName.Substring(idx + prefix.Length) : string.Empty; + var parsedSite = viewName[..idx]; + var parsedFile = idx + prefix.Length < viewName.Length ? viewName[(idx + prefix.Length)..] : string.Empty; if (isCheckSiteName) { diff --git a/uTPro/Project/uTPro.Project.Web/Views/Partials/blockgrid/uTPro.cshtml b/uTPro/Project/uTPro.Project.Web/Views/Partials/blockgrid/uTPro.cshtml index 6b107ba..14c77ad 100644 --- a/uTPro/Project/uTPro.Project.Web/Views/Partials/blockgrid/uTPro.cshtml +++ b/uTPro/Project/uTPro.Project.Web/Views/Partials/blockgrid/uTPro.cshtml @@ -2,11 +2,34 @@ @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage @{ if (Model?.Any() != true) { return; } + var currentPage = Umbraco.AssignedContentItem; + var top = currentPage?.GetInherited("topComponent"); + var bottom = currentPage?.GetInherited("bottomComponent"); } -
- @* @await Html.GetBlockGridItemsHtmlAsync(Model) *@ - @await Html.GetPreviewBlockGridItemsHtmlAsync(Model, $"{CurrentSite.GetItem().Root.Name}{Prefix.PrefixData}items") -
+@if (top != null) +{ +
+ @await Html.GetPreviewBlockGridItemsHtmlAsync(top, $"{CurrentSite.GetItem().Root.Name}{Prefix.PrefixData}items") +
+} +@if (Model != null) +{ +
+ @* @await Html.GetBlockGridItemsHtmlAsync(Model) *@ + @await Html.GetPreviewBlockGridItemsHtmlAsync(Model, $"{CurrentSite.GetItem().Root.Name}{Prefix.PrefixData}items") +
+ +} +@if (bottom != null) +{ +
+ @await Html.GetPreviewBlockGridItemsHtmlAsync(bottom, $"{CurrentSite.GetItem().Root.Name}{Prefix.PrefixData}items") +
+} \ No newline at end of file diff --git a/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml b/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml index 931351f..67c3095 100644 --- a/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml +++ b/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml @@ -37,7 +37,11 @@ var url = CurrentSite.GetUrlWithCulture(Model, item.Culture, UrlMode.Auto); if (url == "#" || string.IsNullOrEmpty(url)) { - url = CurrentSite.GetUrlWithCulture(CurrentSite.GetItem().PageHome, item.Culture, UrlMode.Auto); + var pageHome = CurrentSite.GetItem().PageHome; + if (pageHome != null) + { + url = CurrentSite.GetUrlWithCulture(pageHome, item.Culture, UrlMode.Auto); + } } if (string.IsNullOrEmpty(url)) continue; @@ -93,7 +97,7 @@ @optionHtml -