Instead of an isBreadcrumb parameter we now use BreadcrumbMenuItemPart to distinguish breadcrumb-only menu items

This commit is contained in:
Lombiq
2016-01-29 17:03:07 +01:00
parent cce9b3172e
commit f44ddc623c
11 changed files with 112 additions and 94 deletions

View File

@@ -1,6 +1,7 @@
using Orchard.Data.Migration;
using Orchard.ContentManagement.MetaData;
using Orchard.Environment.Extensions;
using Orchard.Core.Navigation.Models;
namespace Orchard.Alias {
[OrchardFeature("Orchard.Alias.BreadcrumbLink")]
@@ -8,6 +9,7 @@ namespace Orchard.Alias {
public int Create() {
ContentDefinitionManager.AlterTypeDefinition("AliasBreadcrumbMenuItem",
cfg => cfg
.WithPart("BreadcrumbMenuItemPart")
.WithPart("MenuPart")
.WithPart("CommonPart")
.WithIdentity()

View File

@@ -27,93 +27,94 @@ namespace Orchard.Alias.Navigation {
_hca = hca;
}
public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items, bool isBreadcrumb = false) {
public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items) {
foreach (var item in items) {
if (item.Content != null && item.Content.ContentItem.ContentType == "AliasBreadcrumbMenuItem") {
if (isBreadcrumb) {
var request = _hca.Current().Request;
var path = request.Path;
var appPath = request.ApplicationPath ?? "/";
var requestUrl = (path.StartsWith(appPath) ? path.Substring(appPath.Length) : path).TrimStart('/');
var endsWithSlash = requestUrl.EndsWith("/");
var request = _hca.Current().Request;
var path = request.Path;
var appPath = request.ApplicationPath ?? "/";
var requestUrl = (path.StartsWith(appPath) ? path.Substring(appPath.Length) : path).TrimStart('/');
var endsWithSlash = requestUrl.EndsWith("/");
var menuPosition = item.Position;
var menuPosition = item.Position;
var urlLevel = endsWithSlash ? requestUrl.Count(l => l == '/') - 1 : requestUrl.Count(l => l == '/');
var menuLevel = menuPosition.Count(l => l == '.');
var urlLevel = endsWithSlash ? requestUrl.Count(l => l == '/') - 1 : requestUrl.Count(l => l == '/');
var menuLevel = menuPosition.Count(l => l == '.');
// Checking menu item if it's the leaf element or it's an intermediate element
// or it's an unneccessary element according to the url.
RouteValueDictionary contentRoute;
if (menuLevel == urlLevel) {
// Checking menu item if it's the leaf element or it's an intermediate element
// or it's an unneccessary element according to the url.
RouteValueDictionary contentRoute;
if (menuLevel == urlLevel) {
contentRoute = request.RequestContext.RouteData.Values;
}
else {
// If menuLevel doesn't equal with urlLevel it can mean that this menu item is
// an intermediate element (the difference is a positive value) or this menu
// item is lower in the navigation hierarchy according to the url (negative
// value). If the value is negative, removing the menu item, if the value
// is positive finding its place in the hierarchy.
var levelDifference = urlLevel - menuLevel;
if (levelDifference > 0) {
if (endsWithSlash) {
levelDifference += levelDifference;
}
for (int i = 0; i < levelDifference; i++) {
requestUrl = requestUrl.Remove(requestUrl.LastIndexOf('/'));
path = path.Remove(path.LastIndexOf('/'));
}
contentRoute = _aliasService.Get(requestUrl);
if (contentRoute == null) {
// After the exact number of segments is cut out from the url and the
// currentRoute is still null, trying another check with the added slash,
// because we don't know if the alias was created with a slash at the end or not.
contentRoute = _aliasService.Get(requestUrl.Insert(requestUrl.Length, "/"));
path = path.Insert(path.Length, "/");
if (contentRoute == null) {
contentRoute = new RouteValueDictionary();
}
}
}
else {
// If menuLevel doesn't equal with urlLevel it can mean that this menu item is
// an intermediate element (the difference is a positive value) or this menu
// item is lower in the navigation hierarchy according to the url (negative
// value). If the value is negative, removing the menu item, if the value
// is positive finding its place in the hierarchy.
var levelDifference = urlLevel - menuLevel;
if (levelDifference > 0) {
if (endsWithSlash) {
levelDifference += levelDifference;
}
for (int i = 0; i < levelDifference; i++) {
requestUrl = requestUrl.Remove(requestUrl.LastIndexOf('/'));
path = path.Remove(path.LastIndexOf('/'));
}
contentRoute = _aliasService.Get(requestUrl);
if (contentRoute == null) {
// After the exact number of segments is cut out from the url and the
// currentRoute is still null, trying another check with the added slash,
// because we don't know if the alias was created with a slash at the end or not.
contentRoute = _aliasService.Get(requestUrl.Insert(requestUrl.Length, "/"));
path = path.Insert(path.Length, "/");
}
}
else {
contentRoute = new RouteValueDictionary();
}
contentRoute = new RouteValueDictionary();
}
}
object id;
contentRoute.TryGetValue("Id", out id);
int contentId;
int.TryParse(id as string, out contentId);
if (contentId == 0) {
// If failed to get the Id's value from currentRoute, transform the alias to the virtual path
// and try to get the content item's id from there. E.g. "Blogs/Blog/Item?blogId=12" where
// the last digits represents the content item's id. If there is a match in the path we get
// the digits after the equality sign.
// There is an another type of the routes: like "Contents/Item/Display/13", but when the
// content item's route is in this form we already have the id from contentRoute.TryGetValue("Id", out id).
var virtualPath = _aliasService.LookupVirtualPaths(contentRoute, _hca.Current()).FirstOrDefault();
int.TryParse(virtualPath != null ? virtualPath.VirtualPath.Substring(virtualPath.VirtualPath.LastIndexOf('=') + 1) : "0", out contentId);
}
if (contentId != 0) {
var currentContentItem = _contentManager.Get(contentId);
if (currentContentItem != null) {
var menuText = _contentManager.GetItemMetadata(currentContentItem).DisplayText;
var routes = _contentManager.GetItemMetadata(currentContentItem).DisplayRouteValues;
object id;
contentRoute.TryGetValue("Id", out id);
int contentId;
int.TryParse(id as string, out contentId);
if (contentId == 0) {
// If failed to get the Id's value from currentRoute, transform the alias to the virtual path
// and try to get the content item's id from there. E.g. "Blogs/Blog/Item?blogId=12" where
// the last digits represents the content item's id. If there is a match in the path we get
// the digits after the equality sign.
// There is an another type of the routes: like "Contents/Item/Display/13", but when the
// content item's route is in this form we already have the id from contentRoute.TryGetValue("Id", out id).
var virtualPath = _aliasService.LookupVirtualPaths(contentRoute, _hca.Current()).FirstOrDefault();
int.TryParse(virtualPath != null ? virtualPath.VirtualPath.Substring(virtualPath.VirtualPath.LastIndexOf('=') + 1) : "0", out contentId);
}
if (contentId != 0) {
var currentContentItem = _contentManager.Get(contentId);
if (currentContentItem != null) {
var menuText = _contentManager.GetItemMetadata(currentContentItem).DisplayText;
var routes = _contentManager.GetItemMetadata(currentContentItem).DisplayRouteValues;
var inserted = new MenuItem {
Text = new LocalizedString(menuText),
IdHint = item.IdHint,
Classes = item.Classes,
Url = path,
Href = item.Href,
LinkToFirstChild = false,
RouteValues = routes,
LocalNav = item.LocalNav,
Items = Enumerable.Empty<MenuItem>(),
Position = menuPosition,
Permissions = item.Permissions,
Content = currentContentItem
};
var inserted = new MenuItem {
Text = new LocalizedString(menuText),
IdHint = item.IdHint,
Classes = item.Classes,
Url = path,
Href = item.Href,
LinkToFirstChild = false,
RouteValues = routes,
LocalNav = item.LocalNav,
Items = Enumerable.Empty<MenuItem>(),
Position = menuPosition,
Permissions = item.Permissions,
Content = item.Content
};
yield return inserted;
}
yield return inserted;
}
}
}

View File

@@ -21,7 +21,7 @@ namespace Orchard.Projections.Navigation {
_projectionManager = projectionManager;
}
public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items, bool isBreadcrumb) {
public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items) {
foreach (var item in items) {
if (item.Content != null && item.Content.ContentItem.ContentType == "NavigationQueryMenuItem") {

View File

@@ -24,7 +24,7 @@ namespace Orchard.Taxonomies.Navigation {
_taxonomyService = taxonomyService;
}
public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items, bool isBreadcrumb) {
public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items) {
foreach (var item in items) {
if (item.Content != null && item.Content.ContentItem.ContentType == "TaxonomyNavigationMenuItem") {