--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-11-02 11:23:27 -07:00
32 changed files with 147 additions and 217 deletions

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using Orchard.UI.Navigation; using Orchard.UI;
namespace Orchard.Tests.UI.Navigation { namespace Orchard.Tests.UI.Navigation {
[TestFixture] [TestFixture]
@@ -10,7 +10,7 @@ namespace Orchard.Tests.UI.Navigation {
[SetUp] [SetUp]
public void Init() { public void Init() {
_comparer = new PositionComparer(); _comparer = new FlatPositionComparer();
} }
@@ -47,6 +47,22 @@ namespace Orchard.Tests.UI.Navigation {
AssertSame("007", "7"); AssertSame("007", "7");
} }
[Test]
public void NegativeNumericValuesAreLessThanPositive() {
AssertLess("-5", "5");
AssertSame("-5", "-5");
AssertMore("42", "-42");
}
[Test]
public void NegativeNumericValuesShouldCompareNumerically() {
AssertMore("-3", "-5");
AssertLess("-8", "-5");
AssertSame("-5", "-5");
AssertLess("-100", "-5");
AssertSame("-007", "-7");
}
[Test] [Test]
public void DotsSplitParts() { public void DotsSplitParts() {
AssertLess("0500.3", "0500.5"); AssertLess("0500.3", "0500.5");

View File

@@ -21,14 +21,18 @@ namespace Orchard.Core.Contents {
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions().OrderBy(d => d.Name); var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions().OrderBy(d => d.Name);
builder.Add(T("Content"), "2", menu => { builder.Add(T("Content"), "2",
menu.Add(T("Manage Content"), "1", item => item.Action("List", "Admin", new { area = "Contents", id = "" })); menu => menu.Add(T("Content Items"), "1", item => item.Action("List", "Admin", new {area = "Contents", id = ""})));
foreach (var contentTypeDefinition in contentTypeDefinitions.Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Creatable)) {
builder.Add(T("New"), "-1", menu => {
menu.Add(T("Content Item"), "1", item => item.Action("List", "Admin", new { area = "Contents", id = "" }));
foreach (var contentTypeDefinition in contentTypeDefinitions.Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Creatable).OrderBy(ctd => ctd.DisplayName)) {
var ci = _contentManager.New(contentTypeDefinition.Name); var ci = _contentManager.New(contentTypeDefinition.Name);
var cim = _contentManager.GetItemMetadata(ci); var cim = _contentManager.GetItemMetadata(ci);
var createRouteValues = cim.CreateRouteValues; var createRouteValues = cim.CreateRouteValues;
// review: the display name should be a LocalizedString
if (createRouteValues.Any()) if (createRouteValues.Any())
menu.Add(T("Create {0}", contentTypeDefinition.DisplayName), "1.3", item => item.Action(cim.CreateRouteValues["Action"] as string, cim.CreateRouteValues["Controller"] as string, cim.CreateRouteValues)); menu.Add(T(contentTypeDefinition.DisplayName), "5", item => item.Action(cim.CreateRouteValues["Action"] as string, cim.CreateRouteValues["Controller"] as string, cim.CreateRouteValues));
} }
}); });
} }

View File

@@ -8,8 +8,9 @@ namespace Orchard.Core.Dashboard {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Orchard"), "0", builder.Add(T("Dashboard"), "0",
menu => menu.Add(T("Dashboard"), "0", item => item.Action("Index", "Admin", new { area = "Dashboard" }).Permission(StandardPermissions.AccessAdminPanel))); menu => menu.Add(T("Orchard"), "0", item => item.Action("Index", "Admin", new { area = "Dashboard" })
.Permission(StandardPermissions.AccessAdminPanel)));
} }
} }
} }

View File

@@ -9,8 +9,8 @@ namespace Orchard.Core.Navigation {
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
//todo: - add new menu? and list menus? ...and remove hard-coded menu name here //todo: - add new menu? and list menus? ...and remove hard-coded menu name here
builder.Add(T("Navigation"), "8", builder.Add(T("Navigation"), "8",
menu => menu menu => menu.Add(T("Main Menu"), "0", item => item.Action("Index", "Admin", new { area = "Navigation" })
.Add(T("Main Menu"), "6.0", item => item.Action("Index", "Admin", new { area = "Navigation" }).Permission(Permissions.ManageMainMenu))); .Permission(Permissions.ManageMainMenu)));
} }
} }
} }

View File

@@ -8,6 +8,7 @@ using Orchard.Core.Navigation.ViewModels;
using Orchard.DisplayManagement; using Orchard.DisplayManagement;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Mvc.AntiForgery; using Orchard.Mvc.AntiForgery;
using Orchard.UI;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
using Orchard.Utility; using Orchard.Utility;
@@ -41,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 PositionComparer()).ToList(); model.MenuItemEntries = _menuService.Get().Select(CreateMenuItemEntries).OrderBy(menuPartEntry => menuPartEntry.MenuItem.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);

View File

@@ -8,8 +8,9 @@ namespace Orchard.Core.Reports {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Site Configuration"), "11", builder.Add(T("Configuration"), "50",
menu => menu.Add(T("Reports"), "15", item => item.Action("Index", "Admin", new { area = "Reports" }).Permission(StandardPermissions.AccessAdminPanel))); menu => menu.Add(T("Reports"), "20", item => item.Action("Index", "Admin", new { area = "Reports" })
.Permission(StandardPermissions.AccessAdminPanel)));
} }
} }
} }

View File

@@ -7,9 +7,9 @@ namespace Orchard.Core.Settings {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Site Configuration"), "11", builder.Add(T("Configuration"), "50",
menu => menu menu => menu.Add(T("Settings"), "10", item => item.Action("Index", "Admin", new { area = "Settings" })
.Add(T("Settings"), "10", item => item.Action("Index", "Admin", new { area = "Settings" }).Permission(Permissions.ManageSettings))); .Permission(Permissions.ManageSettings)));
} }
} }
} }

View File

@@ -16,7 +16,7 @@ namespace Orchard.Blogs {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Blogs"), "1", BuildMenu); builder.Add(T("Blogs"), "2.5", BuildMenu);
} }
private void BuildMenu(NavigationItemBuilder menu) { private void BuildMenu(NavigationItemBuilder menu) {
@@ -24,16 +24,15 @@ namespace Orchard.Blogs {
var blogCount = blogs.Count(); var blogCount = blogs.Count();
var singleBlog = blogCount == 1 ? blogs.ElementAt(0) : null; var singleBlog = blogCount == 1 ? blogs.ElementAt(0) : null;
if (blogCount > 0 && singleBlog == null) if (blogCount > 0 && singleBlog == null) {
menu.Add(T("Manage Blogs"), "1.0", menu.Add(T("List"), "3",
item => item => item.Action("List", "BlogAdmin", new {area = "Orchard.Blogs"}).Permission(Permissions.MetaListBlogs));
item.Action("List", "BlogAdmin", new {area = "Orchard.Blogs"}).Permission(Permissions.MetaListBlogs)); }
else if (singleBlog != null) else if (singleBlog != null)
menu.Add(T("Manage Blog"), "1.0", menu.Add(T("Manage Blog"), "1.0",
item => item => item.Action("Item", "BlogAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.Slug }).Permission(Permissions.MetaListBlogs));
item.Action("Item", "BlogAdmin", new {area = "Orchard.Blogs", blogSlug = singleBlog.Slug}).Permission(Permissions.MetaListBlogs));
if ( singleBlog != null ) if (singleBlog != null)
menu.Add(T("Create New Post"), "1.1", menu.Add(T("Create New Post"), "1.1",
item => item =>
item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.Slug }).Permission(Permissions.PublishBlogPost)); item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.Slug }).Permission(Permissions.PublishBlogPost));

View File

@@ -8,10 +8,9 @@ namespace Orchard.Comments {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Comments"), "3", builder.Add(T("Comments"), "10",
menu => menu menu => menu.Add(T("List"), "0", item => item.Action("Index", "Admin", new { area = "Orchard.Comments" })
.Add(T("Manage Comments"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Comments" }).Permission(Permissions.ManageComments)) .Permission(Permissions.ManageComments)));
);
} }
} }
} }

View File

@@ -10,7 +10,7 @@ namespace Orchard.ContentTypes {
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Content"), "2", builder.Add(T("Content"), "2",
menu => menu.Add(T("Manage Content Types"), "1.1", item => item.Action("Index", "Admin", new { area = "Orchard.ContentTypes" }))); menu => menu.Add(T("Content Types"), "3", item => item.Action("Index", "Admin", new {area = "Orchard.ContentTypes"})));
} }
} }
} }

View File

@@ -8,10 +8,8 @@ namespace Orchard.Experimental {
public Localizer T { get; set; } public Localizer T { get; set; }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Site Configuration"), "11", builder.Add(T("Configuration"), "50",
menu => menu menu => menu.Add(T("Experimental"), "50", item => item.Action("Index", "Home", new { area = "Orchard.Experimental" })));
.Add(T("Experimental"), "10.0", item => item.Action("Index", "Home", new { area = "Orchard.Experimental" })
));
} }
} }
} }

View File

@@ -7,10 +7,9 @@ namespace Orchard.Indexing {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Site Configuration"), "11", builder.Add(T("Configuration"), "50",
menu => menu menu => menu.Add(T("Search Index"), "15", item => item.Action("Index", "Admin", new {area = "Orchard.Indexing"})
.Add(T("Search Index"), "10.0", item => item.Action("Index", "Admin", new {area = "Orchard.Indexing"}) .Permission(Permissions.ManageSearchIndex)));
.Permission(Permissions.ManageSearchIndex)));
} }
} }
} }

View File

@@ -8,10 +8,9 @@ namespace Orchard.Media {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Media"), "4", builder.Add(T("Media"), "6",
menu => menu menu => menu.Add(T("Media"), "0", item => item.Action("Index", "Admin", new { area = "Orchard.Media" })
.Add(T("Manage Media"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Media" }).Permission(Permissions.ManageMediaFiles)) .Permission(Permissions.ManageMediaFiles)));
);
} }
} }
} }

View File

@@ -7,9 +7,8 @@ namespace Orchard.Migrations {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Developer"), "10", builder.Add(T("Developer"), "1",
menu => menu menu => menu.Add(T("Migration"), "1.0", item => item.Action("Index", "DatabaseUpdate", new { area = "Orchard.Migrations" })));
.Add(T("Migration"), "1.0", item => item.Action("Index", "DatabaseUpdate", new { area = "Orchard.Migrations" })));
} }
} }
} }

View File

@@ -8,12 +8,12 @@ namespace Orchard.Modules {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Site Configuration"), "11", builder.Add(T("Configuration"), "50",
menu => menu menu => menu
.Add(T("Features"), "5.0", item => item.Action("Features", "Admin", new { area = "Orchard.Modules" }) .Add(T("Features"), "0", item => item.Action("Features", "Admin", new { area = "Orchard.Modules" })
.Permission(Permissions.ManageFeatures)) .Permission(Permissions.ManageFeatures))
.Add(T("Modules"), "5.1", item => item.Action("Index", "Admin", new { area = "Orchard.Modules" }) .Add(T("Modules"), "5", item => item.Action("Index", "Admin", new { area = "Orchard.Modules" })
.Permission(Permissions.ManageModules))); .Permission(Permissions.ManageModules)));
} }
} }
} }

View File

@@ -18,10 +18,9 @@ namespace Orchard.MultiTenancy {
if ( _shellSettings.Name != "Default" ) if ( _shellSettings.Name != "Default" )
return; return;
builder.Add(T("Tenants"), "22", builder.Add(T("Tenants"), "100",
menu => menu menu => menu.Add(T("List"), "0", item => item.Action("Index", "Admin", new { area = "Orchard.MultiTenancy" })
.Add(T("Manage Tenants"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.MultiTenancy" }).Permission(Permissions.ManageTenants)) .Permission(Permissions.ManageTenants)));
.Add(T("Add New Tenant"), "1.1", item => item.Action("Add", "Admin", new { area = "Orchard.MultiTenancy" }).Permission(Permissions.ManageTenants)));
} }
} }
} }

View File

@@ -10,12 +10,12 @@ namespace Orchard.Packaging {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Gallery"), "5", menu => menu builder.Add(T("Gallery"), "30", menu => menu
.Add(T("Browse Modules"), "1.0", item => item .Add(T("Modules"), "1.0", item => item
.Action("ModulesIndex", "Gallery", new { area = "Orchard.Packaging" })) .Action("ModulesIndex", "Gallery", new { area = "Orchard.Packaging" }))
.Add(T("Browse Themes"), "2.0", item => item .Add(T("Themes"), "2.0", item => item
.Action("ThemesIndex", "Gallery", new { area = "Orchard.Packaging" })) .Action("ThemesIndex", "Gallery", new { area = "Orchard.Packaging" }))
.Add(T("Gallery Feeds"), "3.0", item => item .Add(T("Feeds"), "3.0", item => item
.Action("Sources", "Gallery", new { area = "Orchard.Packaging" }))); .Action("Sources", "Gallery", new { area = "Orchard.Packaging" })));
} }
} }

View File

@@ -7,9 +7,9 @@ namespace Orchard.Roles {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Users"), "9", builder.Add(T("Users"), "40",
menu => menu menu => menu.Add(T("Roles"), "2.0", item => item.Action("Index", "Admin", new { area = "Orchard.Roles" })
.Add(T("Manage Roles"), "2.0", item => item.Action("Index", "Admin", new { area = "Orchard.Roles" }).Permission(Permissions.ManageRoles))); .Permission(Permissions.ManageRoles)));
} }
} }
} }

View File

@@ -7,10 +7,9 @@ namespace Orchard.Tags {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Tags"), "3", builder.Add(T("Tags"), "20",
menu => menu menu => menu.Add(T("List"), "0", item => item.Action("Index", "Admin", new { area = "Orchard.Tags" })
.Add(T("Manage Tags"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Tags" }).Permission(Permissions.ManageTags)) .Permission(Permissions.ManageTags)));
);
} }
} }
} }

View File

@@ -7,10 +7,10 @@ namespace Orchard.Themes {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Site Design"), "10", builder.Add(T("Themes"), "25",
menu => menu menu => menu.Add(T("List"), "0", item => item.Action("Index", "Admin", new { area = "Orchard.Themes" })
.Add(T("Themes"), "2.0", item => item.Action("Index", "Admin", new { area = "Orchard.Themes" }) .Permission(Permissions.ManageThemes)
.Permission(Permissions.ManageThemes).Permission(Permissions.ApplyTheme))); .Permission(Permissions.ApplyTheme)));
} }
} }
} }

View File

@@ -7,9 +7,9 @@ namespace Orchard.Users {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Users"), "9", builder.Add(T("Users"), "40",
menu => menu menu => menu.Add(T("Users"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Users" })
.Add(T("Manage Users"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Users" }).Permission(Permissions.ManageUsers))); .Permission(Permissions.ManageUsers)));
} }
} }
} }

View File

@@ -1,7 +1,12 @@
@model Orchard.Users.ViewModels.LogOnViewModel @model Orchard.Users.ViewModels.LogOnViewModel
@using Orchard.ContentManagement;
@{
var userCanRegister = @WorkContext.CurrentSite.As<Orchard.Users.Models.RegistrationSettingsPart>().UsersCanRegister;
}
<h1 class="page-title">@Html.TitleForPage(Model.Title)</h1> <h1 class="page-title">@Html.TitleForPage(Model.Title)</h1>
<p>@T("Please enter your username and password.") @Html.ActionLink("Register", "Register") @T(" if you don't have an account.")</p> <p>@T("Please enter your username and password.") @if(userCanRegister) { <text> </text> @Html.ActionLink("Register", "Register") @T(" if you don't have an account.") }</p>
@Html.ValidationSummary(T("Login was unsuccessful. Please correct the errors and try again.").ToString()) @Html.ValidationSummary(T("Login was unsuccessful. Please correct the errors and try again.").ToString())
@using (Html.BeginFormAntiForgeryPost(Url.Action("LogOn", new {ReturnUrl = Request.QueryString["ReturnUrl"]}))) { @using (Html.BeginFormAntiForgeryPost(Url.Action("LogOn", new {ReturnUrl = Request.QueryString["ReturnUrl"]}))) {

View File

@@ -7,9 +7,9 @@ namespace Orchard.Widgets {
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Widgets"), "10", builder.Add(T("Widgets"), "4",
menu => menu menu => menu.Add(T("Configure"), "0", item => item.Action("Index", "Admin", new { area = "Orchard.Widgets" })
.Add(T("Manage Widgets"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Widgets" }).Permission(Permissions.ManageWidgets))); .Permission(Permissions.ManageWidgets)));
} }
} }
} }

View File

@@ -116,7 +116,7 @@ number of columns: 24; actual width: 946; column width: 26; gutter width:14
float:right; float:right;
width:83.08%; width:83.08%;
} }
#navigation { #menu .menu-admin {
display:inline; display:inline;
float:left; float:left;
width:15.401%; width:15.401%;
@@ -238,20 +238,20 @@ form.link button:hover {
overflow:hidden; overflow:hidden;
width:0; width:0;
} }
#navigation li { #menu .menu-admin li {
margin:5px 0 17px 4px; margin:5px 0 17px 4px;
} }
#navigation ul li { #menu .menu-admin ul li {
border:0; border:0;
margin:0; margin:0;
} }
#navigation li h3 { #menu .menu-admin li h3 {
padding:0 0 0 8px; padding:0 0 0 8px;
} }
#navigation li h3 a, #navigation li h3 span { #menu .menu-admin li h3 a, #menu .menu-admin li h3 span {
line-height:1.2em; line-height:1.2em;
} }
#navigation ul a, #navigation ul a:link, #navigation ul a:visited { #menu .menu-admin ul a, #menu .menu-admin ul a:link, #menu .menu-admin ul a:visited {
color:#2d2f25; color:#2d2f25;
display:block; display:block;
font-size:1.4em; font-size:1.4em;
@@ -259,7 +259,7 @@ form.link button:hover {
padding:.4em 0 .4em 12px; padding:.4em 0 .4em 12px;
text-decoration:none; text-decoration:none;
} }
#navigation ul a:hover, #navigation ul a:active, #navigation ul a:focus { #menu .menu-admin ul a:hover, #menu .menu-admin ul a:active, #menu .menu-admin ul a:focus {
background:#f5f5f5; background:#f5f5f5;
color: #000; color: #000;
text-decoration:underline; text-decoration:underline;

View File

@@ -1,17 +1,24 @@
@using System.Web.Routing; @using System.Web.Routing;
@using Orchard.Utility.Extensions;
@{ @{
Script.Require("jQuery"); Script.Require("jQuery");
Script.Include("admin.js"); Script.Include("admin.js");
IEnumerable<dynamic> firstLevelMenuItems = Model; IEnumerable<dynamic> firstLevelMenuItems = Model;
Model.Attributes.Add("role", "navigation");
var tag = Tag(Model, "ul");
} }
<ul id="navigation" role="navigation"> @tag.StartElement
@foreach(var firstLevelMenuItem in Model) { @foreach(var firstLevelMenuItem in Model) {
IEnumerable<dynamic> secondLevelMenuItems = firstLevelMenuItem; IEnumerable<dynamic> secondLevelMenuItems = firstLevelMenuItem;
string sectionHeaderText = firstLevelMenuItem.Text;
var firstOfTheSecond = secondLevelMenuItems.FirstOrDefault(); var firstOfTheSecond = secondLevelMenuItems.FirstOrDefault();
var sectionHeaderMarkup = firstOfTheSecond != null var sectionHeaderMarkup = firstLevelMenuItem.RouteValues != null || HasText(firstLevelMenuItem.Url)
? Html.ActionLink((string)firstLevelMenuItem.Text, (string)firstOfTheSecond.RouteValues["action"], (RouteValueDictionary)firstOfTheSecond.RouteValues) ? Html.Link(sectionHeaderText, (string)firstLevelMenuItem.Href)
: new HtmlString(string.Format("<span>{0}</span>", Html.Encode(firstLevelMenuItem.Text))); : firstOfTheSecond != null
? Html.Link(sectionHeaderText, (string)firstOfTheSecond.Href)
: new HtmlString(string.Format("<span>{0}</span>", Html.Encode(sectionHeaderText)));
if (firstLevelMenuItem == firstLevelMenuItems.First()) { if (firstLevelMenuItem == firstLevelMenuItems.First()) {
firstLevelMenuItem.Classes.Add("first"); firstLevelMenuItem.Classes.Add("first");
@@ -20,24 +27,27 @@
firstLevelMenuItem.Classes.Add("last"); firstLevelMenuItem.Classes.Add("last");
} }
firstLevelMenuItem.Classes.Add("section-" + sectionHeaderText.HtmlClassify());
var firstLevelTag = Tag(firstLevelMenuItem, "li"); var firstLevelTag = Tag(firstLevelMenuItem, "li");
@firstLevelTag.StartElement @firstLevelTag.StartElement
<h3>@sectionHeaderMarkup</h3> <h3>@sectionHeaderMarkup</h3>
<ul class="menuItems"> if (secondLevelMenuItems.Count() > 1) {
@foreach(var secondLevelMenuItem in secondLevelMenuItems) { <ul class="menuItems">
<li> @foreach(var secondLevelMenuItem in secondLevelMenuItems) {
<a href="@secondLevelMenuItem.Href">@secondLevelMenuItem.Text</a> <li>
</li> <a href="@secondLevelMenuItem.Href">@secondLevelMenuItem.Text</a>
</li>
}
</ul>
} }
</ul>
@firstLevelTag.EndElement @firstLevelTag.EndElement
} }
</ul> @tag.EndElement
@using(Script.Foot()) { @using(Script.Foot()) {
<script type="text/javascript"> <script type="text/javascript">
//<![CDATA[ //<![CDATA[
(function ($) { (function ($) {
$("#navigation h3").expandoControl(function(controller) { return controller.next(); }, { key: "N42", path: "@Url.Content("~/")" }); $("@string.Format(".{0} h3", string.Join(".", Model.Classes))").expandoControl(function(controller) { return controller.next(); }, { key: "N42", path: "@Url.Content("~/")" });
})(jQuery); })(jQuery);
//]]> //]]>
</script> </script>

View File

@@ -43,7 +43,7 @@ namespace Orchard.Mvc.Html {
return null; return null;
return html.ActionLink( return html.ActionLink(
NonNullOrEmpty(linkText, metadata.DisplayText, "edit"), NonNullOrEmpty(linkText, metadata.DisplayText, content.ContentItem.TypeDefinition.DisplayName),
Convert.ToString(metadata.EditorRouteValues["action"]), Convert.ToString(metadata.EditorRouteValues["action"]),
metadata.EditorRouteValues.Merge(additionalRouteValues)); metadata.EditorRouteValues.Merge(additionalRouteValues));
} }

View File

@@ -3,7 +3,7 @@ using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using System.Web.Mvc.Html; using System.Web.Mvc.Html;
using Orchard.ContentManagement.ViewModels; using Orchard.ContentManagement.ViewModels;
using Orchard.UI.Navigation; using Orchard.UI;
namespace Orchard.Mvc.Html { namespace Orchard.Mvc.Html {
public static class TemplateViewModelExtensions { public static class TemplateViewModelExtensions {
@@ -11,7 +11,7 @@ namespace Orchard.Mvc.Html {
if (templates == null) if (templates == null)
return; return;
foreach (var template in templates.OrderByDescending(t => t.Position, new PositionComparer())) { foreach (var template in templates.OrderByDescending(t => t.Position, new FlatPositionComparer())) {
html.RenderTemplates(template); html.RenderTemplates(template);
} }
} }

View File

@@ -791,7 +791,6 @@
<Compile Include="UI\Navigation\MenuItem.cs" /> <Compile Include="UI\Navigation\MenuItem.cs" />
<Compile Include="UI\Navigation\MenuItemComparer.cs" /> <Compile Include="UI\Navigation\MenuItemComparer.cs" />
<Compile Include="UI\Navigation\NavigationManager.cs" /> <Compile Include="UI\Navigation\NavigationManager.cs" />
<Compile Include="UI\Navigation\PositionComparer.cs" />
<Compile Include="UI\Notify\Notifier.cs" /> <Compile Include="UI\Notify\Notifier.cs" />
<Compile Include="UI\Notify\NotifierExtensions.cs" /> <Compile Include="UI\Notify\NotifierExtensions.cs" />
<Compile Include="UI\Notify\NotifyEntry.cs" /> <Compile Include="UI\Notify\NotifyEntry.cs" />

View File

@@ -8,27 +8,33 @@ namespace Orchard.UI {
if (x == y) if (x == y)
return 0; return 0;
// "" == "5" // null == "before; "" == "0"
x = string.IsNullOrWhiteSpace(x) ? "5" : x.TrimStart(':'); // ':' is _sometimes_ used as a partition identifier x = x == null
y = string.IsNullOrWhiteSpace(y) ? "5" : y.TrimStart(':'); ? "before"
: x.Trim() == "" ? "0" : x.Trim(':').TrimEnd('.'); // ':' is _sometimes_ used as a partition identifier
y = y == null
? "before"
: y.Trim() == "" ? "0" : y.Trim(':').TrimEnd('.');
var xParts = x.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); var xParts = x.Split(new[] { '.', ':' });
var yParts = y.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); var yParts = y.Split(new[] { '.', ':' });
for (var i = 0; i < xParts.Count(); i++) { for (var i = 0; i < xParts.Count(); i++) {
if (yParts.Length < i+1) // x is further defined meaning it comes after y (e.g. x == 1.2.3 and y == 1.2) if (yParts.Length < i+1) // x is further defined meaning it comes after y (e.g. x == 1.2.3 and y == 1.2)
return 1; return 1;
int xPos; int xPos;
int yPos; int yPos;
var xPart = string.IsNullOrWhiteSpace(xParts[i]) ? "before" : xParts[i];
var yPart = string.IsNullOrWhiteSpace(yParts[i]) ? "before" : yParts[i];
xParts[i] = NormalizeKnownPartitions(xParts[i]); xPart = NormalizeKnownPartitions(xPart);
yParts[i] = NormalizeKnownPartitions(yParts[i]); yPart = NormalizeKnownPartitions(yPart);
var xIsInt = int.TryParse(xParts[i], out xPos); var xIsInt = int.TryParse(xPart, out xPos);
var yIsInt = int.TryParse(yParts[i], out yPos); var yIsInt = int.TryParse(yPart, out yPos);
if (!xIsInt && !yIsInt) if (!xIsInt && !yIsInt)
return string.Compare(x, y, StringComparison.OrdinalIgnoreCase); return string.Compare(string.Join(".", xParts), string.Join(".", yParts), StringComparison.OrdinalIgnoreCase);
if (!xIsInt || (yIsInt && xPos > yPos)) // non-int after int or greater x pos than y pos (which is an int) if (!xIsInt || (yIsInt && xPos > yPos)) // non-int after int or greater x pos than y pos (which is an int)
return 1; return 1;
if (!yIsInt || xPos < yPos) if (!yIsInt || xPos < yPos)

View File

@@ -92,7 +92,7 @@ namespace Orchard.UI.Navigation {
private static IEnumerable<MenuItem> Merge(IEnumerable<IEnumerable<MenuItem>> sources) { private static IEnumerable<MenuItem> Merge(IEnumerable<IEnumerable<MenuItem>> sources) {
var comparer = new MenuItemComparer(); var comparer = new MenuItemComparer();
var orderer = new PositionComparer(); var orderer = new FlatPositionComparer();
return sources.SelectMany(x => x).ToArray() return sources.SelectMany(x => x).ToArray()
.GroupBy(key => key, (key, items) => Join(items), comparer) .GroupBy(key => key, (key, items) => Join(items), comparer)
@@ -116,7 +116,7 @@ namespace Orchard.UI.Navigation {
} }
private static string SelectBestPositionValue(IEnumerable<string> positions) { private static string SelectBestPositionValue(IEnumerable<string> positions) {
var comparer = new PositionComparer(); var comparer = new FlatPositionComparer();
return positions.Aggregate(string.Empty, return positions.Aggregate(string.Empty,
(agg, pos) => (agg, pos) =>
string.IsNullOrEmpty(agg) string.IsNullOrEmpty(agg)

View File

@@ -1,105 +0,0 @@
using System;
using System.Collections.Generic;
namespace Orchard.UI.Navigation {
public class PositionComparer : IComparer<string> {
public int Compare(string x, string y) {
if (x == null || y == null) {
return x == null && y == null ? 0 : (x == null ? -1 : 1);
}
if (x == "" || y == "") {
return x == "" && y == "" ? 0 : (x == "" ? -1 : 1);
}
var xRange = new Range { Length = x.Length };
var yRange = new Range { Length = y.Length };
while (xRange.Start != xRange.Length || yRange.Start != yRange.Length) {
var xSize = xRange.NextDot(x);
var ySize = yRange.NextDot(y);
if (xSize == 0 || ySize == 0) {
// one or both sides are empty
if (xSize != 0 || ySize != 0) {
// favor the side that's not empty
return xSize - ySize;
}
// otherwise continue to the next segment if both are
}
else if (xRange.NumericValue != -1 && yRange.NumericValue != -1) {
// two strictly numeric values
// return the difference
var diff = xRange.NumericValue - yRange.NumericValue;
if (diff != 0)
return diff;
// or continue to next segment
}
else {
if (xRange.NumericValue != -1) {
// left-side only has numeric value, right-side explicitly greater
return -1;
}
if (yRange.NumericValue != -1) {
// right-side only has numeric value, left-side explicitly greater
return 1;
}
// two strictly non-numeric
var diff = string.Compare(x, xRange.Start, y, yRange.Start, Math.Min(xSize, ySize),
StringComparison.OrdinalIgnoreCase);
if (diff != 0)
return diff;
if (xSize != ySize)
return xSize - ySize;
}
xRange.Advance();
yRange.Advance();
}
return 0;
}
struct Range {
public int Start { get; private set; }
private int End { get; set; }
public int Length { get; set; }
public int NumericValue { get; private set; }
public int NextDot(string value) {
if (Start == -1) {
End = -1;
return 0;
}
End = value.IndexOf('.', Start);
int numeric;
NumericValue = int.TryParse(Segment(value), out numeric) ? numeric : -1;
return End == -1 ? Length - Start : End - Start;
}
private string Segment(string value) {
if (Start == 0 && End == -1) {
return value;
}
if (End == -1) {
return value.Substring(Start);
}
return value.Substring(Start, End - Start);
}
public void Advance() {
if (End == -1)
Start = Length;
else
Start = End + 1;
}
}
}
}

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 Orchard.UI;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
namespace Orchard.Utility { namespace Orchard.Utility {
@@ -9,7 +10,7 @@ namespace Orchard.Utility {
var topMenuItem = menuItems.FirstOrDefault(); var topMenuItem = menuItems.FirstOrDefault();
if (topMenuItem != null) { if (topMenuItem != null) {
var maxMenuItem = topMenuItem.Items.Where(PositionHasMojorNumber).OrderByDescending(mi => mi.Position, new PositionComparer()).FirstOrDefault(); var maxMenuItem = topMenuItem.Items.Where(PositionHasMojorNumber).OrderByDescending(mi => mi.Position, new FlatPositionComparer()).FirstOrDefault();
var positionParts = maxMenuItem.Position.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries).Where(s => s.Trim() != ""); var positionParts = maxMenuItem.Position.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries).Where(s => s.Trim() != "");
if (positionParts.Count() > 0) { if (positionParts.Count() > 0) {
int result; int result;