Made changes to enable resolving of urls for menu items on the front end.

Supported examples:
~/something <-- app relative url
/something <-- site relative url
something <-- app relative url
http(s)://something <-- absolute url

--HG--
branch : dev
This commit is contained in:
Erik Porter
2010-02-15 17:13:31 -08:00
parent a8eb9f6328
commit cb89bf818c
5 changed files with 49 additions and 19 deletions

View File

@@ -1,11 +1,11 @@
using System; using System.Linq;
using System.Collections.Generic; using System.Web.Mvc;
using System.Linq; using System.Web.Routing;
using System.Text;
using NUnit.Framework; using NUnit.Framework;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Security; using Orchard.Security;
using Orchard.Security.Permissions; using Orchard.Security.Permissions;
using Orchard.Tests.Stubs;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
namespace Orchard.Tests.UI.Navigation { namespace Orchard.Tests.UI.Navigation {
@@ -13,7 +13,7 @@ namespace Orchard.Tests.UI.Navigation {
public class NavigationManagerTests { public class NavigationManagerTests {
[Test] [Test]
public void EmptyMenuIfNameDoesntMatch() { public void EmptyMenuIfNameDoesntMatch() {
var manager = new NavigationManager(new[] { new StubProvider() }, new StubAuth()); var manager = new NavigationManager(new[] { new StubProvider() }, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())));
var menuItems = manager.BuildMenu("primary"); var menuItems = manager.BuildMenu("primary");
Assert.That(menuItems.Count(), Is.EqualTo(0)); Assert.That(menuItems.Count(), Is.EqualTo(0));
@@ -30,7 +30,7 @@ namespace Orchard.Tests.UI.Navigation {
[Test] [Test]
public void NavigationManagerShouldUseProvidersToBuildNamedMenu() { public void NavigationManagerShouldUseProvidersToBuildNamedMenu() {
var manager = new NavigationManager(new[] { new StubProvider() }, new StubAuth()); var manager = new NavigationManager(new[] { new StubProvider() }, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())));
var menuItems = manager.BuildMenu("admin"); var menuItems = manager.BuildMenu("admin");
Assert.That(menuItems.Count(), Is.EqualTo(2)); Assert.That(menuItems.Count(), Is.EqualTo(2));
@@ -42,7 +42,7 @@ namespace Orchard.Tests.UI.Navigation {
[Test] [Test]
public void NavigationManagerShouldMergeAndOrderNavigation() { public void NavigationManagerShouldMergeAndOrderNavigation() {
var manager = new NavigationManager(new INavigationProvider[] { new StubProvider(), new Stub2Provider() }, new StubAuth()); var manager = new NavigationManager(new INavigationProvider[] { new StubProvider(), new Stub2Provider() }, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())));
var menuItems = manager.BuildMenu("admin"); var menuItems = manager.BuildMenu("admin");
Assert.That(menuItems.Count(), Is.EqualTo(3)); Assert.That(menuItems.Count(), Is.EqualTo(3));

View File

@@ -14,15 +14,10 @@
if (counter == count) if (counter == count)
sbClass.Append("last "); sbClass.Append("last ");
var url = !string.IsNullOrEmpty(menuItem.Url) if (string.Equals(menuItem.Href, Request.Url.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
? menuItem.Url
: Url.RouteUrl(menuItem.RouteValues);
if (string.Equals(url, Request.Url.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
sbClass.Append("current "); sbClass.Append("current ");
%> %>
<li class="<%=sbClass.ToString().TrimEnd() %>"><%=Html.Link(menuItem.Text, url) %></li><% <li class="<%=sbClass.ToString().TrimEnd() %>"><%=Html.Link(menuItem.Text, menuItem.Href) %></li><%
++counter; ++counter;
} %> } %>
</ul> </ul>

View File

@@ -12,6 +12,8 @@ namespace Orchard.Mvc {
// Locate the container this route is bound against // Locate the container this route is bound against
var container = GetRequestContainer(routeData); var container = GetRequestContainer(routeData);
container.Build(cb => cb.Register(new UrlHelper(requestContext)));
// Determine the area name for the request, and fall back to stock orchard controllers // Determine the area name for the request, and fall back to stock orchard controllers
var areaName = GetAreaName(routeData) ?? "Orchard"; var areaName = GetAreaName(routeData) ?? "Orchard";
@@ -35,7 +37,7 @@ namespace Orchard.Mvc {
return null; return null;
} }
public static IContext GetRequestContainer(RouteData routeData) { public static IContainer GetRequestContainer(RouteData routeData) {
object dataTokenValue; object dataTokenValue;
if (routeData != null && if (routeData != null &&
routeData.DataTokens != null && routeData.DataTokens != null &&

View File

@@ -11,6 +11,7 @@ namespace Orchard.UI.Navigation {
public string Text { get; set; } public string Text { get; set; }
public string Url { get; set; } public string Url { get; set; }
public string Href { get; set; }
public string Position { get; set; } public string Position { get; set; }
public RouteValueDictionary RouteValues { get; set; } public RouteValueDictionary RouteValues { get; set; }
public IEnumerable<MenuItem> Items { get; set; } public IEnumerable<MenuItem> Items { get; set; }

View File

@@ -1,5 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Web;
using System.Web.Mvc;
using JetBrains.Annotations; using JetBrains.Annotations;
using Orchard.Security; using Orchard.Security;
using Orchard.Security.Permissions; using Orchard.Security.Permissions;
@@ -8,16 +10,44 @@ namespace Orchard.UI.Navigation {
public class NavigationManager : INavigationManager { public class NavigationManager : INavigationManager {
private readonly IEnumerable<INavigationProvider> _providers; private readonly IEnumerable<INavigationProvider> _providers;
private readonly IAuthorizationService _authorizationService; private readonly IAuthorizationService _authorizationService;
private readonly UrlHelper _urlHelper;
public NavigationManager(IEnumerable<INavigationProvider> providers, IAuthorizationService authorizationService) { public NavigationManager(IEnumerable<INavigationProvider> providers, IAuthorizationService authorizationService, UrlHelper urlHelper) {
_providers = providers; _providers = providers;
_authorizationService = authorizationService; _authorizationService = authorizationService;
_urlHelper = urlHelper;
} }
protected virtual IUser CurrentUser { get; [UsedImplicitly] private set; } protected virtual IUser CurrentUser { get; [UsedImplicitly] private set; }
public IEnumerable<MenuItem> BuildMenu(string menuName) { public IEnumerable<MenuItem> BuildMenu(string menuName) {
return Crop(Reduce(Merge(AllSources(menuName)))).ToArray(); return FinishMenu(Crop(Reduce(Merge(AllSources(menuName)))).ToArray());
}
private IEnumerable<MenuItem> FinishMenu(IEnumerable<MenuItem> menuItems) {
foreach (var menuItem in menuItems) {
var url = string.IsNullOrEmpty(menuItem.Url) && (menuItem.RouteValues == null || menuItem.RouteValues.Count == 0)
? null
: !string.IsNullOrEmpty(menuItem.Url)
? menuItem.Url
: _urlHelper.RouteUrl(menuItem.RouteValues);
if (!string.IsNullOrEmpty(url) && _urlHelper.RequestContext.HttpContext != null &&
!(url.StartsWith("http://") || url.StartsWith("https://") || url.StartsWith("/"))) {
if (url.StartsWith("~/")) {
url = url.Substring(2);
}
var appPath = _urlHelper.RequestContext.HttpContext.Request.ApplicationPath;
if (appPath == "/")
appPath = "";
url = string.Format("{0}/{1}", appPath, url);
}
menuItem.Href = url;
menuItem.Items = FinishMenu(menuItem.Items.ToArray());
}
return menuItems;
} }
private IEnumerable<MenuItem> Crop(IEnumerable<MenuItem> items) { private IEnumerable<MenuItem> Crop(IEnumerable<MenuItem> items) {
@@ -39,7 +69,8 @@ namespace Orchard.UI.Navigation {
Position = item.Position, Position = item.Position,
RouteValues = item.RouteValues, RouteValues = item.RouteValues,
Text = item.Text, Text = item.Text,
Url = item.Url Url = item.Url,
Href = item.Href
}; };
} }
} }
@@ -71,10 +102,11 @@ namespace Orchard.UI.Navigation {
var joined = new MenuItem { var joined = new MenuItem {
Text = items.First().Text, Text = items.First().Text,
Url = items.First().Url, Url = items.First().Url,
Href = items.First().Href,
RouteValues = items.First().RouteValues, RouteValues = items.First().RouteValues,
Items = Merge(items.Select(x => x.Items)).ToArray(), Items = Merge(items.Select(x => x.Items)).ToArray(),
Position = SelectBestPositionValue(items.Select(x => x.Position)), Position = SelectBestPositionValue(items.Select(x => x.Position)),
Permissions = items.SelectMany(x => x.Permissions), Permissions = items.SelectMany(x => x.Permissions)
}; };
return joined; return joined;
} }