Changing MenuItem .Text to LocalizedString

Updating comparer to avoid collapsing url and routevalue items together
Flattened the navigation admin controller to avoid using MenuItem class in editor model
HtmlEncode the text of the menu item to be displayed
Updated TheMenu templates to use .text and .hinttext properties of LocalizedString

--HG--
branch : dev
This commit is contained in:
Louis DeJardin
2011-02-26 18:29:00 -08:00
parent 10bba3b135
commit 4a4ac2ef07
16 changed files with 80 additions and 72 deletions

View File

@@ -63,8 +63,8 @@ namespace Orchard.Tests.UI.Navigation {
} }
private static Mock<INavigationManager> GetNavigationManager() { private static Mock<INavigationManager> GetNavigationManager() {
var mainMenu = new[] { new MenuItem { Text = "The Main Menu" } }; var mainMenu = new[] { new MenuItem { Text = new LocalizedString("The Main Menu") } };
var adminMenu = new[] { new MenuItem { Text = "The Admin Menu" } }; var adminMenu = new[] { new MenuItem { Text = new LocalizedString("The Admin Menu") } };
var navigationManager = new Mock<INavigationManager>(); var navigationManager = new Mock<INavigationManager>();
navigationManager.Setup(x => x.BuildMenu("main")).Returns(mainMenu); navigationManager.Setup(x => x.BuildMenu("main")).Returns(mainMenu);
navigationManager.Setup(x => x.BuildMenu("admin")).Returns(adminMenu); navigationManager.Setup(x => x.BuildMenu("admin")).Returns(adminMenu);

View File

@@ -1,5 +1,6 @@
using System.Web.Routing; using System.Web.Routing;
using NUnit.Framework; using NUnit.Framework;
using Orchard.Localization;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
namespace Orchard.Tests.UI.Navigation { namespace Orchard.Tests.UI.Navigation {
@@ -7,50 +8,50 @@ namespace Orchard.Tests.UI.Navigation {
public class MenuItemComparerTests { public class MenuItemComparerTests {
[Test] [Test]
public void TextShouldCauseDifferenceAndNullRouteValuesAreEqual() { public void TextShouldCauseDifferenceAndNullRouteValuesAreEqual() {
var item1 = new MenuItem { TextHint = "hello" }; var item1 = new MenuItem { Text = new LocalizedString("hello") };
var item2 = new MenuItem { TextHint = "hello" }; var item2 = new MenuItem { Text = new LocalizedString("hello") };
var item3 = new MenuItem { TextHint = "hello3" }; var item3 = new MenuItem { Text = new LocalizedString("hello3") };
AssertSameSameDifferent(item1, item2, item3); AssertSameSameDifferent(item1, item2, item3);
} }
[Test] [Test]
public void NullRouteValuesShouldEqualEmptyRouteValues() { public void NullRouteValuesShouldEqualEmptyRouteValues() {
var item1 = new MenuItem { TextHint = "hello" }; var item1 = new MenuItem { Text = new LocalizedString("hello") };
var item2 = new MenuItem { TextHint = "hello" }; var item2 = new MenuItem { Text = new LocalizedString("hello") };
var item3 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary() }; var item3 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary() };
var item4 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary() }; var item4 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary() };
AssertSameSameSame(item1, item2, item3); AssertSameSameSame(item1, item2, item3);
AssertSameSameSame(item3, item4, item1); AssertSameSameSame(item3, item4, item1);
} }
[Test] [Test]
public void AdditionalPropertiesShouldMismatch() { public void AdditionalPropertiesShouldMismatch() {
var item1 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = 1 }) }; var item1 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = 1 }) };
var item2 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = 1 }) }; var item2 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = 1 }) };
var item3 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = 1, two = 2 }) }; var item3 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = 1, two = 2 }) };
AssertSameSameDifferent(item1, item2, item3); AssertSameSameDifferent(item1, item2, item3);
} }
[Test] [Test]
public void ValueTypeShouldMismatch() { public void ValueTypeShouldMismatch() {
var item1 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = 1 }) }; var item1 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = 1 }) };
var item2 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = 1 }) }; var item2 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = 1 }) };
var item3 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = "1" }) }; var item3 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = "1" }) };
AssertSameSameDifferent(item1, item2, item3); AssertSameSameDifferent(item1, item2, item3);
} }
[Test] [Test]
public void ValuesShouldMismatch() { public void ValuesShouldMismatch() {
var item1 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) }; var item1 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) };
var item2 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) }; var item2 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) };
var item3 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "3" }) }; var item3 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = "1", two = "3" }) };
AssertSameSameDifferent(item1, item2, item3); AssertSameSameDifferent(item1, item2, item3);
} }
[Test] [Test]
public void PositionAndChildrenDontMatter() { public void PositionAndChildrenDontMatter() {
var item1 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) }; var item1 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) };
var item2 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }), Position = "4.0" }; var item2 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }), Position = "4.0" };
var item3 = new MenuItem { TextHint = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }), Items = new[] { new MenuItem() } }; var item3 = new MenuItem { Text = new LocalizedString("hello"), RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }), Items = new[] { new MenuItem() } };
AssertSameSameSame(item1, item2, item3); AssertSameSameSame(item1, item2, item3);
} }

View File

@@ -56,19 +56,19 @@ namespace Orchard.Tests.UI.Navigation {
var item2 = menuItems.Skip(1).First(); var item2 = menuItems.Skip(1).First();
var item3 = menuItems.Skip(2).First(); var item3 = menuItems.Skip(2).First();
Assert.That(item1.TextHint, Is.EqualTo("Foo")); Assert.That(item1.Text, Is.EqualTo("Foo"));
Assert.That(item1.Position, Is.EqualTo("1.0")); Assert.That(item1.Position, Is.EqualTo("1.0"));
Assert.That(item2.TextHint, Is.EqualTo("Bar")); Assert.That(item2.Text, Is.EqualTo("Bar"));
Assert.That(item2.Position, Is.EqualTo("2.0")); Assert.That(item2.Position, Is.EqualTo("2.0"));
Assert.That(item3.TextHint, Is.EqualTo("Frap")); Assert.That(item3.Text, Is.EqualTo("Frap"));
Assert.That(item3.Position, Is.EqualTo("3.0")); Assert.That(item3.Position, Is.EqualTo("3.0"));
Assert.That(item2.Items.Count(), Is.EqualTo(2)); Assert.That(item2.Items.Count(), Is.EqualTo(2));
var subitem1 = item2.Items.First(); var subitem1 = item2.Items.First();
var subitem2 = item2.Items.Last(); var subitem2 = item2.Items.Last();
Assert.That(subitem1.TextHint, Is.EqualTo("Quad")); Assert.That(subitem1.Text, Is.EqualTo("Quad"));
Assert.That(subitem1.Position, Is.EqualTo("1.a")); Assert.That(subitem1.Position, Is.EqualTo("1.a"));
Assert.That(subitem2.TextHint, Is.EqualTo("Frap")); Assert.That(subitem2.Text, Is.EqualTo("Frap"));
Assert.That(subitem2.Position, Is.EqualTo("1.b")); Assert.That(subitem2.Position, Is.EqualTo("1.b"));
} }

View File

@@ -42,7 +42,7 @@ namespace Orchard.Core.Navigation.Controllers {
model = new NavigationManagementViewModel(); model = new NavigationManagementViewModel();
if (model.MenuItemEntries == null || model.MenuItemEntries.Count() < 1) if (model.MenuItemEntries == null || model.MenuItemEntries.Count() < 1)
model.MenuItemEntries = _menuService.Get().Select(CreateMenuItemEntries).OrderBy(menuPartEntry => menuPartEntry.MenuItem.Position, new FlatPositionComparer()).ToList(); model.MenuItemEntries = _menuService.Get().Select(CreateMenuItemEntries).OrderBy(menuPartEntry => menuPartEntry.Position, new FlatPositionComparer()).ToList();
// need action name as this action is referenced from another action // need action name as this action is referenced from another action
return View("Index", model); return View("Index", model);
@@ -58,10 +58,10 @@ namespace Orchard.Core.Navigation.Controllers {
foreach (var menuItemEntry in menuItemEntries) { foreach (var menuItemEntry in menuItemEntries) {
MenuPart menuPart = _menuService.Get(menuItemEntry.MenuItemId); MenuPart menuPart = _menuService.Get(menuItemEntry.MenuItemId);
menuPart.MenuText = menuItemEntry.MenuItem.Text; menuPart.MenuText = menuItemEntry.Text;
menuPart.MenuPosition = menuItemEntry.MenuItem.Position; menuPart.MenuPosition = menuItemEntry.Position;
if (menuPart.Is<MenuItemPart>()) if (menuPart.Is<MenuItemPart>())
menuPart.As<MenuItemPart>().Url = menuItemEntry.MenuItem.Url; menuPart.As<MenuItemPart>().Url = menuItemEntry.Url;
} }
} }
@@ -70,15 +70,13 @@ namespace Orchard.Core.Navigation.Controllers {
private MenuItemEntry CreateMenuItemEntries(MenuPart menuPart) { private MenuItemEntry CreateMenuItemEntries(MenuPart menuPart) {
return new MenuItemEntry { return new MenuItemEntry {
MenuItem = new MenuItem { MenuItemId = menuPart.Id,
IsMenuItem = menuPart.Is<MenuItemPart>(),
Text = menuPart.MenuText, Text = menuPart.MenuText,
Position = menuPart.MenuPosition, Position = menuPart.MenuPosition,
Url = menuPart.Is<MenuItemPart>() Url = menuPart.Is<MenuItemPart>()
? menuPart.As<MenuItemPart>().Url ? menuPart.As<MenuItemPart>().Url
: _navigationManager.GetUrl(null, _services.ContentManager.GetItemMetadata(menuPart).DisplayRouteValues) : _navigationManager.GetUrl(null, _services.ContentManager.GetItemMetadata(menuPart).DisplayRouteValues),
},
MenuItemId = menuPart.Id,
IsMenuItem = menuPart.Is<MenuItemPart>()
}; };
} }

View File

@@ -1,4 +1,5 @@
using JetBrains.Annotations; using System.Web;
using JetBrains.Annotations;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Core.Navigation.Models; using Orchard.Core.Navigation.Models;
using Orchard.Localization; using Orchard.Localization;
@@ -23,11 +24,11 @@ namespace Orchard.Core.Navigation.Services {
if (part.Is<MenuItemPart>()) if (part.Is<MenuItemPart>())
builder.Add( builder.Add(
menu => menu.Add(new LocalizedString(part.MenuText), part.MenuPosition, nib => nib.Url(part.As<MenuItemPart>().Url))); menu => menu.Add(new LocalizedString(HttpUtility.HtmlEncode(part.MenuText)), part.MenuPosition, nib => nib.Url(part.As<MenuItemPart>().Url)));
else else
builder.Add( builder.Add(
menu => menu =>
menu.Add(new LocalizedString(part.MenuText), part.MenuPosition, menu.Add(new LocalizedString(HttpUtility.HtmlEncode(part.MenuText)), part.MenuPosition,
nib => nib =>
nib.Action(_contentManager.GetItemMetadata(part.ContentItem).DisplayRouteValues))); nib.Action(_contentManager.GetItemMetadata(part.ContentItem).DisplayRouteValues)));
} }

View File

@@ -2,8 +2,11 @@
namespace Orchard.Core.Navigation.ViewModels { namespace Orchard.Core.Navigation.ViewModels {
public class MenuItemEntry { public class MenuItemEntry {
public MenuItem MenuItem { get; set; }
public int MenuItemId { get; set; } public int MenuItemId { get; set; }
public bool IsMenuItem { get; set; } public bool IsMenuItem { get; set; }
public string Text { get; set; }
public string Url { get; set; }
public string Position { get; set; }
} }
} }

View File

@@ -26,9 +26,9 @@
foreach (var menuPartEntry in Model.MenuItemEntries) { foreach (var menuPartEntry in Model.MenuItemEntries) {
var i = menuPartEntryIndex; var i = menuPartEntryIndex;
<tr> <tr>
<td><input type="text" class="text-box" name="@Html.NameOf(m => m.MenuItemEntries[i].MenuItem.Text)" value="@menuPartEntry.MenuItem.Text" /></td> <td><input type="text" class="text-box" name="@Html.NameOf(m => m.MenuItemEntries[i].Text)" value="@menuPartEntry.Text" /></td>
<td><input type="text" class="text-box" name="@Html.NameOf(m => m.MenuItemEntries[i].MenuItem.Position)" value="@menuPartEntry.MenuItem.Position" /></td> <td><input type="text" class="text-box" name="@Html.NameOf(m => m.MenuItemEntries[i].Position)" value="@menuPartEntry.Position" /></td>
<td>@if (!menuPartEntry.IsMenuItem) {<input type="text" class="text-box disabled" disabled="disabled" value="@menuPartEntry.MenuItem.Url" /> } else {<input type="text" class="text-box" name="@Html.NameOf(m => m.MenuItemEntries[i].MenuItem.Url)" value="@menuPartEntry.MenuItem.Url" />}</td> <td>@if (!menuPartEntry.IsMenuItem) {<input type="text" class="text-box disabled" disabled="disabled" value="@menuPartEntry.Url" /> } else {<input type="text" class="text-box" name="@Html.NameOf(m => m.MenuItemEntries[i].Url)" value="@menuPartEntry.Url" />}</td>
<td><input type="hidden" name="@Html.NameOf(m => m.MenuItemEntries[i].MenuItemId)" value="@menuPartEntry.MenuItemId" /><a href="@Html.AntiForgeryTokenGetUrl(Url.Action("Delete", new {id = menuPartEntry.MenuItemId}))" class="remove">@T("Remove")</a></td> <td><input type="hidden" name="@Html.NameOf(m => m.MenuItemEntries[i].MenuItemId)" value="@menuPartEntry.MenuItemId" /><a href="@Html.AntiForgeryTokenGetUrl(Url.Action("Delete", new {id = menuPartEntry.MenuItemId}))" class="remove">@T("Remove")</a></td>
</tr> </tr>
++menuPartEntryIndex; ++menuPartEntryIndex;

View File

@@ -9,7 +9,7 @@
@tag.StartElement @tag.StartElement
@foreach(var firstLevelMenuItem in Model) { @foreach(var firstLevelMenuItem in Model) {
if (firstLevelMenuItem.LocalNav) { if (firstLevelMenuItem.LocalNav) {
string sectionHeaderText = firstLevelMenuItem.Text; string sectionHeaderText = firstLevelMenuItem.Text.Text;
var sectionHeaderMarkup = firstLevelMenuItem.RouteValues != null || HasText(firstLevelMenuItem.Url) var sectionHeaderMarkup = firstLevelMenuItem.RouteValues != null || HasText(firstLevelMenuItem.Url)
? Html.Link(sectionHeaderText, (string)firstLevelMenuItem.Href) ? Html.Link(sectionHeaderText, (string)firstLevelMenuItem.Href)

View File

@@ -16,8 +16,8 @@
@foreach(var firstLevelMenuItem in Model) { @foreach(var firstLevelMenuItem in Model) {
IEnumerable<dynamic> secondLevelMenuItems = firstLevelMenuItem; IEnumerable<dynamic> secondLevelMenuItems = firstLevelMenuItem;
string sectionHeaderText = firstLevelMenuItem.Text; string sectionHeaderText = firstLevelMenuItem.Text.Text;
string sectionHeaderTextHint = firstLevelMenuItem.TextHint; string sectionHeaderTextHint = firstLevelMenuItem.Text.TextHint;
var firstOfTheSecond = secondLevelMenuItems.FirstOrDefault(); var firstOfTheSecond = secondLevelMenuItems.FirstOrDefault();
var itemClassName = HasText(sectionHeaderTextHint) var itemClassName = HasText(sectionHeaderTextHint)
@@ -64,7 +64,7 @@
if (secondLevelMenuItems.Where(menuItem => !menuItem.LocalNav).Count() > 1 || !firstLevelMenuItem.LinkToFirstChild) { if (secondLevelMenuItems.Where(menuItem => !menuItem.LocalNav).Count() > 1 || !firstLevelMenuItem.LinkToFirstChild) {
<ul class="menuItems"> <ul class="menuItems">
@foreach (var secondLevelMenuItem in secondLevelMenuItems.Where(menuItem => !menuItem.LocalNav)) { @foreach (var secondLevelMenuItem in secondLevelMenuItems.Where(menuItem => !menuItem.LocalNav)) {
string secondLevelTextHint = secondLevelMenuItem.TextHint; string secondLevelTextHint = secondLevelMenuItem.Text.TextHint;
var secondLevelItemClassName = HasText(secondLevelTextHint) var secondLevelItemClassName = HasText(secondLevelTextHint)
? "subnavicon-" + secondLevelTextHint.HtmlClassify() ? "subnavicon-" + secondLevelTextHint.HtmlClassify()
: "subnavicon"; : "subnavicon";

View File

@@ -8,8 +8,9 @@ namespace Orchard.Localization {
private readonly string _textHint; private readonly string _textHint;
private readonly object[] _args; private readonly object[] _args;
public LocalizedString(string localized) { public LocalizedString(string languageNeutral) {
_localized = localized; _localized = languageNeutral;
_textHint = languageNeutral;
} }
public LocalizedString(string localized, string scope, string textHint, object[] args) { public LocalizedString(string localized, string scope, string textHint, object[] args) {

View File

@@ -194,7 +194,6 @@ namespace Orchard.UI.Navigation {
protected dynamic BuildMenuItemShape(dynamic shapeFactory, dynamic parentShape, dynamic menu, MenuItem menuItem) { protected dynamic BuildMenuItemShape(dynamic shapeFactory, dynamic parentShape, dynamic menu, MenuItem menuItem) {
return shapeFactory.MenuItem() return shapeFactory.MenuItem()
.Text(menuItem.Text) .Text(menuItem.Text)
.TextHint(menuItem.TextHint)
.IdHint(menuItem.IdHint) .IdHint(menuItem.IdHint)
.Href(menuItem.Href) .Href(menuItem.Href)
.LinkToFirstChild(menuItem.LinkToFirstChild) .LinkToFirstChild(menuItem.LinkToFirstChild)
@@ -217,7 +216,6 @@ namespace Orchard.UI.Navigation {
protected dynamic BuildLocalMenuItemShape(dynamic shapeFactory, dynamic parentShape, dynamic menu, MenuItem menuItem) { protected dynamic BuildLocalMenuItemShape(dynamic shapeFactory, dynamic parentShape, dynamic menu, MenuItem menuItem) {
return shapeFactory.LocalMenuItem() return shapeFactory.LocalMenuItem()
.Text(menuItem.Text) .Text(menuItem.Text)
.TextHint(menuItem.TextHint)
.IdHint(menuItem.IdHint) .IdHint(menuItem.IdHint)
.Href(menuItem.Href) .Href(menuItem.Href)
.LinkToFirstChild(menuItem.LinkToFirstChild) .LinkToFirstChild(menuItem.LinkToFirstChild)

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Web.Routing; using System.Web.Routing;
using Orchard.Localization;
using Orchard.Security.Permissions; using Orchard.Security.Permissions;
namespace Orchard.UI.Navigation { namespace Orchard.UI.Navigation {
@@ -10,8 +11,7 @@ namespace Orchard.UI.Navigation {
LinkToFirstChild = true; LinkToFirstChild = true;
} }
public string Text { get; set; } public LocalizedString Text { get; set; }
public string TextHint { get; set; }
public string IdHint { get; set; } public string IdHint { get; set; }
public string Url { get; set; } public string Url { get; set; }
public string Href { get; set; } public string Href { get; set; }

View File

@@ -4,9 +4,12 @@ using System.Linq;
namespace Orchard.UI.Navigation { namespace Orchard.UI.Navigation {
public class MenuItemComparer : IEqualityComparer<MenuItem> { public class MenuItemComparer : IEqualityComparer<MenuItem> {
public bool Equals(MenuItem x, MenuItem y) { public bool Equals(MenuItem x, MenuItem y) {
if (!string.Equals(x.TextHint, y.TextHint)) { if (x.Text != null && y.Text != null) {
if (!string.Equals(x.Text.TextHint, y.Text.TextHint)) {
return false; return false;
} }
}
if (!string.IsNullOrWhiteSpace(x.Url) && !string.IsNullOrWhiteSpace(y.Url)) { if (!string.IsNullOrWhiteSpace(x.Url) && !string.IsNullOrWhiteSpace(y.Url)) {
if (!string.Equals(x.Url, y.Url)) { if (!string.Equals(x.Url, y.Url)) {
return false; return false;
@@ -26,13 +29,20 @@ namespace Orchard.UI.Navigation {
} }
} }
if (!string.IsNullOrWhiteSpace(x.Url) && y.RouteValues != null) {
return false;
}
if (!string.IsNullOrWhiteSpace(y.Url) && x.RouteValues != null) {
return false;
}
return true; return true;
} }
public int GetHashCode(MenuItem obj) { public int GetHashCode(MenuItem obj) {
var hash = 0; var hash = 0;
if (obj.TextHint != null) { if (obj.Text != null && obj.Text.TextHint != null) {
hash ^= obj.TextHint.GetHashCode(); hash ^= obj.Text.TextHint.GetHashCode();
} }
return hash; return hash;
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Web;
using Orchard.Localization; using Orchard.Localization;
namespace Orchard.UI.Navigation { namespace Orchard.UI.Navigation {

View File

@@ -13,10 +13,7 @@ namespace Orchard.UI.Navigation {
} }
public NavigationItemBuilder Caption(LocalizedString caption) { public NavigationItemBuilder Caption(LocalizedString caption) {
if (caption != null) { _item.Text = caption;
_item.Text = caption.Text;
_item.TextHint = caption.TextHint;
}
return this; return this;
} }

View File

@@ -74,7 +74,6 @@ namespace Orchard.UI.Navigation {
RouteValues = item.RouteValues, RouteValues = item.RouteValues,
LocalNav = item.LocalNav, LocalNav = item.LocalNav,
Text = item.Text, Text = item.Text,
TextHint = item.TextHint,
IdHint = item.IdHint, IdHint = item.IdHint,
Url = item.Url, Url = item.Url,
LinkToFirstChild = item.LinkToFirstChild, LinkToFirstChild = item.LinkToFirstChild,
@@ -116,7 +115,7 @@ namespace Orchard.UI.Navigation {
// order position groups by position // order position groups by position
.OrderBy(positionGroup => positionGroup.Key, orderer) .OrderBy(positionGroup => positionGroup.Key, orderer)
// ordered by item text in the postion group // ordered by item text in the postion group
.SelectMany(positionGroup => positionGroup.OrderBy(item => item.Text)); .SelectMany(positionGroup => positionGroup.OrderBy(item => item.Text == null ? "" : item.Text.TextHint));
} }
static MenuItem Join(IEnumerable<MenuItem> items) { static MenuItem Join(IEnumerable<MenuItem> items) {
@@ -125,7 +124,6 @@ namespace Orchard.UI.Navigation {
var joined = new MenuItem { var joined = new MenuItem {
Text = items.First().Text, Text = items.First().Text,
TextHint = items.First().TextHint,
IdHint = items.Select(x => x.IdHint).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), IdHint = items.Select(x => x.IdHint).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)),
Url = items.Select(x => x.Url).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), Url = items.Select(x => x.Url).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)),
Href = items.Select(x => x.Href).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), Href = items.Select(x => x.Href).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)),