Skip to content

Commit

Permalink
Merge pull request #71 from Lombiq/issue/OSOE-623
Browse files Browse the repository at this point in the history
OSOE-623: Add MainMenuNavigationProvider
  • Loading branch information
Psichorex authored Jun 15, 2023
2 parents 4316615 + c3a1e7a commit b813bdb
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ wwwroot
node_modules
.pnpm-debug.log
/Lombiq.BaseTheme/Migrations/Lombiq.BaseTheme.LayersAndZones.recipe.json
*.orig
1 change: 1 addition & 0 deletions Lombiq.BaseTheme/Lombiq.BaseTheme.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="OrchardCore.Menu" Version="1.5.0" />
<PackageReference Include="OrchardCore.Theme.Targets" Version="1.5.0" />
<PackageReference Include="OrchardCore.ContentManagement" Version="1.5.0" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.5.0" />
Expand Down
110 changes: 110 additions & 0 deletions Lombiq.BaseTheme/Services/MainMenuNavigationProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using AngleSharp.Dom;
using AngleSharp.Html.Parser;
using Lombiq.HelpfulLibraries.OrchardCore.Navigation;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Localization;
using Newtonsoft.Json.Linq;
using OrchardCore.ContentManagement;
using OrchardCore.Menu.Models;
using OrchardCore.Navigation;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Lombiq.BaseTheme.Services;

public class MainMenuNavigationProvider : MainMenuNavigationProviderBase
{
private readonly IContentHandleManager _contentHandleManager;
private readonly IContentManager _contentManager;
private readonly IUrlHelperFactory _urlHelperFactory;
private readonly IActionContextAccessor _actionContextAccessor;

public MainMenuNavigationProvider(
IHttpContextAccessor hca,
IStringLocalizer<MainMenuNavigationProvider> stringLocalizer,
IContentHandleManager contentHandleManager,
IContentManager contentManager,
IUrlHelperFactory urlHelperFactory,
IActionContextAccessor actionContextAccessor)
: base(hca, stringLocalizer)
{
_contentHandleManager = contentHandleManager;
_contentManager = contentManager;
_urlHelperFactory = urlHelperFactory;
_actionContextAccessor = actionContextAccessor;
}

protected override async Task BuildAsync(NavigationBuilder builder)
{
if (await _contentHandleManager.GetContentItemIdAsync("alias:main-menu") is not { } id ||
await _contentManager.GetAsync(id) is not { } contentItem ||
contentItem.As<MenuItemsListPart>() is not { } menuItemsListPart)
{
return;
}

foreach (var menuItem in menuItemsListPart.MenuItems)
{
await AddAsync(builder, menuItem);
}
}

private async Task AddAsync(NavigationBuilder builder, ContentItem menuItem)
{
var text = GetTitle(menuItem);

if (menuItem.As<LinkMenuItemPart>() is { } linkMenuItemPart)
{
builder.Add(text, menu => menu.Url(linkMenuItemPart.Url));
}
else if (menuItem.As<ContentMenuItemPart>() is { } contentMenuItemPart)
{
if (contentMenuItemPart.Content.SelectedContentItem is JObject &&
contentMenuItemPart.Content.SelectedContentItem.ContentItemIds is JArray contentItemIds)
{
var ids = contentItemIds.ToObject<IEnumerable<string>>();
await AddContentMenuItemPartAsync(builder, text, ids);
}
}
else if (menuItem.As<HtmlMenuItemPart>() is { } htmlMenuItemPart)
{
var nodeList = new HtmlParser().ParseFragment($"<div>{htmlMenuItemPart.Html}</div>", contextElement: null!);
var textContent = string.Concat(nodeList.Select(x => x.Text()));
builder.Add(new LocalizedString(textContent, textContent), menu => menu.Url("#").LocalNav());
}
else if (menuItem.As<MenuItemsListPart>() is { } menuItemsListPart)
{
await builder.AddAsync(text, menu =>
menuItemsListPart.MenuItems.AwaitEachAsync(child => AddAsync(menu, child)));
}
}

private async Task AddContentMenuItemPartAsync(NavigationBuilder builder, LocalizedString text, IEnumerable<string> ids)
{
var contentItems = (await _contentManager.GetAsync(ids)).AsList();
var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext!);

if (contentItems.Count == 1)
{
var contentItem = contentItems.Single();
if (string.IsNullOrEmpty(text.Value)) text = GetTitle(contentItem);
builder.Add(text, menu => menu.Url(urlHelper.DisplayContentItem(contentItem)));
}
else
{
builder.Add(text, menu =>
{
foreach (var contentItem in contentItems)
{
menu.Add(GetTitle(contentItem), child => child.Url(urlHelper.DisplayContentItem(contentItem)));
}
});
}
}

private static LocalizedString GetTitle(ContentItem contentItem) =>
new(contentItem.DisplayText, contentItem.DisplayText);
}
2 changes: 2 additions & 0 deletions Lombiq.BaseTheme/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OrchardCore.Modules;
using OrchardCore.Navigation;
using OrchardCore.ResourceManagement;
using System;

Expand All @@ -30,6 +31,7 @@ public override void ConfigureServices(IServiceCollection services)
services.AddScoped<IResourceFilterProvider, ResourceFilters>();

PerTenantShapeTableManager.ReplaceDefaultShapeTableManager(services);
services.AddScoped<INavigationProvider, MainMenuNavigationProvider>();
}

public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) =>
Expand Down

0 comments on commit b813bdb

Please sign in to comment.