diff --git a/.hgsubstate b/.hgsubstate index 0fe42d968..bd162d5e9 100644 --- a/.hgsubstate +++ b/.hgsubstate @@ -8,5 +8,5 @@ e7fc05ff6137ed5459d198b2bea9a5804818b0bd src/Orchard.Web/Modules/Orchard.Forms 419399ef2e37122a000e6cc8674148d3183d7032 src/Orchard.Web/Modules/Orchard.TaskLease aca1f5aeb5dd426bc80c6142afc7f2717fc6d5a1 src/Orchard.Web/Modules/Orchard.Tokens 4ed51e0e76c2aacc2de90ce9984fd00cfdfae2ce src/orchard.web/Modules/Orchard.Alias -d3a8dac3aca8deb5fd45e8864a4273a88a8741ee src/orchard.web/Modules/Orchard.Projections +8812c9cb3495450ce4a3f9c9a3e594c06e18fe4a src/orchard.web/Modules/Orchard.Projections 5a8c67141b56f29d56d2315904dee15223419dc4 src/orchard.web/modules/Orchard.Fields diff --git a/src/Orchard.Web/Core/Navigation/Drivers/MenuWidgetPartDriver.cs b/src/Orchard.Web/Core/Navigation/Drivers/MenuWidgetPartDriver.cs index d41e40995..c5bd5e1c9 100644 --- a/src/Orchard.Web/Core/Navigation/Drivers/MenuWidgetPartDriver.cs +++ b/src/Orchard.Web/Core/Navigation/Drivers/MenuWidgetPartDriver.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using Orchard.ContentManagement; +using Orchard.ContentManagement.Aspects; using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.Handlers; using Orchard.Core.Navigation.Models; @@ -48,9 +49,25 @@ namespace Orchard.Core.Navigation.Drivers { } var menuName = menu.As().Title.HtmlClassify(); + var currentCulture = _workContextAccessor.GetContext().CurrentCulture; IEnumerable menuItems = _navigationManager.BuildMenu(menu); + var localized = new List(); + foreach(var menuItem in menuItems) { + // if there is no associated content, it as culture neutral + if(menuItem.Content == null) { + localized.Add(menuItem); + } + + // if the menu item is culture neutral or of the current culture + if (String.IsNullOrEmpty(menuItem.Culture) || String.Equals(menuItem.Culture, currentCulture, StringComparison.OrdinalIgnoreCase)) { + localized.Add(menuItem); + } + } + + menuItems = localized; + var routeData = _workContextAccessor.GetContext().HttpContext.Request.RequestContext.RouteData; var selectedPath = NavigationHelper.SetSelectedPath(menuItems, routeData); diff --git a/src/Orchard.Web/Core/Navigation/Handlers/ContentMenuItemPartHandler.cs b/src/Orchard.Web/Core/Navigation/Handlers/ContentMenuItemPartHandler.cs index ff7744b11..580e6058f 100644 --- a/src/Orchard.Web/Core/Navigation/Handlers/ContentMenuItemPartHandler.cs +++ b/src/Orchard.Web/Core/Navigation/Handlers/ContentMenuItemPartHandler.cs @@ -7,12 +7,23 @@ using Orchard.ContentManagement.Handlers; namespace Orchard.Core.Navigation.Handlers { [UsedImplicitly] public class ContentMenuItemPartHandler : ContentHandler { + private readonly IContentManager _contentManager; public ContentMenuItemPartHandler(IContentManager contentManager, IRepository repository) { + _contentManager = contentManager; Filters.Add(new ActivatingFilter("ContentMenuItem")); Filters.Add(StorageFilter.For(repository)); OnLoading((context, part) => part._content.Loader(p => contentManager.Get(part.Record.ContentMenuItemRecord.Id))); } + + protected override void GetItemMetadata(GetContentItemMetadataContext context) { + var contentMenuItemPart = context.ContentItem.As(); + + // the display route for the menu item is the one for the referenced content item + if(contentMenuItemPart != null) { + context.Metadata.DisplayRouteValues = _contentManager.GetItemMetadata(contentMenuItemPart.Content).DisplayRouteValues; + } + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/Handlers/MenuPartHandler.cs b/src/Orchard.Web/Core/Navigation/Handlers/MenuPartHandler.cs index 11ece86af..aa081112e 100644 --- a/src/Orchard.Web/Core/Navigation/Handlers/MenuPartHandler.cs +++ b/src/Orchard.Web/Core/Navigation/Handlers/MenuPartHandler.cs @@ -1,5 +1,6 @@ using System; using JetBrains.Annotations; +using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.Core.Navigation.Models; using Orchard.Data; @@ -14,5 +15,13 @@ namespace Orchard.Core.Navigation.Handlers { x.MenuText = String.Empty; }); } + + protected override void GetItemMetadata(GetContentItemMetadataContext context) { + var part = context.ContentItem.As(); + + if (part != null) { + context.Metadata.DisplayText = part.MenuText; + } + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/Services/DefaultMenuManager.cs b/src/Orchard.Web/Core/Navigation/Services/DefaultMenuManager.cs index e4d5181f9..9a4338f1c 100644 --- a/src/Orchard.Web/Core/Navigation/Services/DefaultMenuManager.cs +++ b/src/Orchard.Web/Core/Navigation/Services/DefaultMenuManager.cs @@ -1,7 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Web; using Orchard.ContentManagement; namespace Orchard.Core.Navigation.Services { diff --git a/src/Orchard.Web/Core/Navigation/Services/DefaultMenuProvider.cs b/src/Orchard.Web/Core/Navigation/Services/DefaultMenuProvider.cs index 3499719fc..af38980ee 100644 --- a/src/Orchard.Web/Core/Navigation/Services/DefaultMenuProvider.cs +++ b/src/Orchard.Web/Core/Navigation/Services/DefaultMenuProvider.cs @@ -1,5 +1,6 @@ using System.Web; using Orchard.ContentManagement; +using Orchard.ContentManagement.Aspects; using Orchard.Core.Navigation.Models; using Orchard.Localization; using Orchard.UI.Navigation; @@ -23,10 +24,17 @@ namespace Orchard.Core.Navigation.Services { if (menuPart != null) { var part = menuPart; + // fetch the culture of the menu item, if any + string culture = null; + var localized = part.As(); + if(localized != null) { + culture = localized.Culture; + } + if (part.Is()) - builder.Add(new LocalizedString(HttpUtility.HtmlEncode(part.MenuText)), part.MenuPosition, item => item.Url(part.As().Url).Content(part)); + builder.Add(new LocalizedString(HttpUtility.HtmlEncode(part.MenuText)), part.MenuPosition, item => item.Url(part.As().Url).Content(part).Culture(culture)); else - builder.Add(new LocalizedString(HttpUtility.HtmlEncode(part.MenuText)), part.MenuPosition, item => item.Action(_contentManager.GetItemMetadata(part.ContentItem).DisplayRouteValues).Content(part)); + builder.Add(new LocalizedString(HttpUtility.HtmlEncode(part.MenuText)), part.MenuPosition, item => item.Action(_contentManager.GetItemMetadata(part.ContentItem).DisplayRouteValues).Content(part).Culture(culture)); } } } diff --git a/src/Orchard.Web/Core/Navigation/Views/EditorTemplates/Parts.MenuItem.Edit.cshtml b/src/Orchard.Web/Core/Navigation/Views/EditorTemplates/Parts.MenuItem.Edit.cshtml index 03ee48b57..0c42f469e 100644 --- a/src/Orchard.Web/Core/Navigation/Views/EditorTemplates/Parts.MenuItem.Edit.cshtml +++ b/src/Orchard.Web/Core/Navigation/Views/EditorTemplates/Parts.MenuItem.Edit.cshtml @@ -4,5 +4,5 @@
@Html.TextBoxFor(m => m.Url, new { @class = "large text" }) - @T("A valid url, i.e. http://orchardproject.net, /content/file.pdf, ...") + @T("A valid url, i.e. ~/my-page, http://orchardproject.net, /content/file.pdf, ...")
diff --git a/src/Orchard.Web/Core/Navigation/Views/MenuItemLink-ContentMenuItem.cshtml b/src/Orchard.Web/Core/Navigation/Views/MenuItemLink-ContentMenuItem.cshtml index 16aa754b3..d2b10f6ef 100644 --- a/src/Orchard.Web/Core/Navigation/Views/MenuItemLink-ContentMenuItem.cshtml +++ b/src/Orchard.Web/Core/Navigation/Views/MenuItemLink-ContentMenuItem.cshtml @@ -1,2 +1,8 @@ @using Orchard.ContentManagement -@Model.Text \ No newline at end of file +@{ + ContentItem contentItem = Model.Content.ContentItem.ContentMenuItemPart.Content; +} + +@if (contentItem != null) { + @Model.Text +} \ No newline at end of file diff --git a/src/Orchard/UI/Navigation/INavigationFilter.cs b/src/Orchard/UI/Navigation/INavigationFilter.cs index aa7b5d160..de6e567ec 100644 --- a/src/Orchard/UI/Navigation/INavigationFilter.cs +++ b/src/Orchard/UI/Navigation/INavigationFilter.cs @@ -1,6 +1,9 @@ using System.Collections.Generic; namespace Orchard.UI.Navigation { + /// + /// Provides a way to alter the main navigation, for instance by dynamically injecting new items + /// public interface INavigationFilter : IDependency { IEnumerable Filter(IEnumerable menuItems); } diff --git a/src/Orchard/UI/Navigation/MenuItem.cs b/src/Orchard/UI/Navigation/MenuItem.cs index 2bee57b13..de3c25901 100644 --- a/src/Orchard/UI/Navigation/MenuItem.cs +++ b/src/Orchard/UI/Navigation/MenuItem.cs @@ -21,6 +21,7 @@ namespace Orchard.UI.Navigation { public string Position { get; set; } public bool LinkToFirstChild { get; set; } public bool LocalNav { get; set; } + public string Culture { get; set; } public bool Selected { get; set; } public RouteValueDictionary RouteValues { get; set; } public IEnumerable Items { get; set; } diff --git a/src/Orchard/UI/Navigation/NavigationItemBuilder.cs b/src/Orchard/UI/Navigation/NavigationItemBuilder.cs index 8aae06e12..95c5b6090 100644 --- a/src/Orchard/UI/Navigation/NavigationItemBuilder.cs +++ b/src/Orchard/UI/Navigation/NavigationItemBuilder.cs @@ -33,6 +33,11 @@ namespace Orchard.UI.Navigation { return this; } + public NavigationItemBuilder Culture(string culture) { + _item.Culture = culture; + return this; + } + public NavigationItemBuilder IdHint(string idHint) { _item.IdHint = idHint; return this; diff --git a/src/Orchard/UI/Navigation/NavigationManager.cs b/src/Orchard/UI/Navigation/NavigationManager.cs index 97415266f..8a12c2341 100644 --- a/src/Orchard/UI/Navigation/NavigationManager.cs +++ b/src/Orchard/UI/Navigation/NavigationManager.cs @@ -103,6 +103,7 @@ namespace Orchard.UI.Navigation { Position = item.Position, RouteValues = item.RouteValues, LocalNav = item.LocalNav, + Culture = item.Culture, Text = item.Text, IdHint = item.IdHint, Classes = item.Classes, @@ -222,22 +223,25 @@ namespace Orchard.UI.Navigation { } static MenuItem Join(IEnumerable items) { - if (items.Count() < 2) - return items.Single(); + var list = items.ToArray(); + + if (list.Count() < 2) + return list.Single(); var joined = new MenuItem { - Text = items.First().Text, - IdHint = items.Select(x => x.IdHint).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), - Classes = items.Select(x => x.Classes).FirstOrDefault(x => x != null && x.Count > 0), - Url = items.Select(x => x.Url).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), - Href = items.Select(x => x.Href).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), - LinkToFirstChild = items.First().LinkToFirstChild, - RouteValues = items.Select(x => x.RouteValues).FirstOrDefault(x => x != null), - LocalNav = items.Any(x => x.LocalNav), - Items = Merge(items.Select(x => x.Items)).ToArray(), - Position = SelectBestPositionValue(items.Select(x => x.Position)), - Permissions = items.SelectMany(x => x.Permissions).Distinct(), - Content = items.First().Content + Text = list.First().Text, + IdHint = list.Select(x => x.IdHint).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), + Classes = list.Select(x => x.Classes).FirstOrDefault(x => x != null && x.Count > 0), + Url = list.Select(x => x.Url).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), + Href = list.Select(x => x.Href).FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)), + LinkToFirstChild = list.First().LinkToFirstChild, + RouteValues = list.Select(x => x.RouteValues).FirstOrDefault(x => x != null), + LocalNav = list.Any(x => x.LocalNav), + Culture = list.First().Culture, + Items = Merge(list.Select(x => x.Items)).ToArray(), + Position = SelectBestPositionValue(list.Select(x => x.Position)), + Permissions = list.SelectMany(x => x.Permissions).Distinct(), + Content = list.First().Content }; return joined;