diff --git a/.hgsub b/.hgsub index 214ea4a36..7e1be8d77 100644 --- a/.hgsub +++ b/.hgsub @@ -9,4 +9,5 @@ src/orchard.web/Modules/Orchard.Alias = https://hg.codeplex.com/orchardalias src/orchard.web/Modules/Orchard.Projections = https://hg.codeplex.com/orchardprojections src/Orchard.Web/Modules/Orchard.AntiSpam = https://hg.codeplex.com/orchardantispam src/Orchard.Web/Modules/Orchard.CustomForms = https://hg.codeplex.com/orchardcustomforms -src/Orchard.Web/Modules/Orchard.ViewPermissions = https://hg.codeplex.com/orchardpermissions \ No newline at end of file +src/Orchard.Web/Modules/Orchard.ViewPermissions = https://hg.codeplex.com/orchardpermissions +src/Orchard.Web/Modules/Orchard.ContentPicker = https://hg.codeplex.com/orchardcontentpicker \ No newline at end of file diff --git a/.hgsubstate b/.hgsubstate index 3553815f6..34a783bdd 100644 --- a/.hgsubstate +++ b/.hgsubstate @@ -1,5 +1,6 @@ fdaecfbb0eab3673a3074313f5adcedc6a678506 src/Orchard.Web/Modules/Orchard.AntiSpam bf20391f8fe1ba5d67cadc0643d79ad9fe892d4e src/Orchard.Web/Modules/Orchard.Autoroute +da175731d643b675472e893689641066db827a7c src/Orchard.Web/Modules/Orchard.ContentPicker 37b71cc2949b792b8da48ee4b5450684e3f8b4cf src/Orchard.Web/Modules/Orchard.CustomForms b8e23b1daab66d46b6d2196f87aceb91aed2f582 src/Orchard.Web/Modules/Orchard.Forms cfc264d41c1d299c104d76c5032d8ffee3047dcd src/Orchard.Web/Modules/Orchard.Rules @@ -8,4 +9,4 @@ cfc264d41c1d299c104d76c5032d8ffee3047dcd src/Orchard.Web/Modules/Orchard.Rules f6fecd1702066225a84a482ac029e3e6daff38f3 src/Orchard.Web/Modules/Orchard.ViewPermissions 4ed51e0e76c2aacc2de90ce9984fd00cfdfae2ce src/orchard.web/Modules/Orchard.Alias 29857523c5275b8566ee3a6f4ba2a3d641e7fa0c src/orchard.web/Modules/Orchard.Projections -0ce46c4e39390472b82459007c0e5a05c18d22d8 src/orchard.web/modules/Orchard.Fields +5a25640f15b1a5a336e424324f1c4baf0a8ee73c src/orchard.web/modules/Orchard.Fields diff --git a/src/Orchard.Web/Core/Navigation/Drivers/ContentMenuItemPartDriver.cs b/src/Orchard.Web/Core/Navigation/Drivers/ContentMenuItemPartDriver.cs new file mode 100644 index 000000000..03e39d04d --- /dev/null +++ b/src/Orchard.Web/Core/Navigation/Drivers/ContentMenuItemPartDriver.cs @@ -0,0 +1,82 @@ +using JetBrains.Annotations; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Drivers; +using Orchard.ContentManagement.Handlers; +using Orchard.Core.Navigation.Models; +using Orchard.Core.Navigation.ViewModels; +using Orchard.Localization; +using Orchard.Security; + +namespace Orchard.Core.Navigation.Drivers { + [UsedImplicitly] + public class ContentMenuItemPartDriver : ContentPartDriver { + private readonly IContentManager _contentManager; + private readonly IAuthorizationService _authorizationService; + private readonly IWorkContextAccessor _workContextAccessor; + + public ContentMenuItemPartDriver( + IContentManager contentManager, + IAuthorizationService authorizationService, + IWorkContextAccessor workContextAccessor) { + _contentManager = contentManager; + _authorizationService = authorizationService; + _workContextAccessor = workContextAccessor; + + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + + protected override DriverResult Editor(ContentMenuItemPart part, dynamic shapeHelper) { + return ContentShape("Parts_ContentMenuItem_Edit", + () => { + var model = new ContentMenuItemEditViewModel { + ContentItemId = part.Content == null ? -1 : part.Content.Id, + Part = part + }; + return shapeHelper.EditorTemplate(TemplateName: "Parts.ContentMenuItem.Edit", Model: model, Prefix: Prefix); + }); + } + + protected override DriverResult Editor(ContentMenuItemPart part, IUpdateModel updater, dynamic shapeHelper) { + var currentUser = _workContextAccessor.GetContext().CurrentUser; + if (!_authorizationService.TryCheckAccess(Permissions.ManageMainMenu, currentUser, part)) + return null; + + var model = new ContentMenuItemEditViewModel(); + + if(updater.TryUpdateModel(model, Prefix, null, null)) { + var contentItem = _contentManager.Get(model.ContentItemId); + if(contentItem == null) { + updater.AddModelError("ContentItemId", T("You must select a Content Item")); + } + else { + part.Content = contentItem; + } + } + + return Editor(part, shapeHelper); + } + + protected override void Importing(ContentMenuItemPart part, ImportContentContext context) { + var contentItemId = context.Attribute(part.PartDefinition.Name, "ContentItem"); + if (contentItemId != null) { + var contentItem = context.GetItemFromSession(contentItemId); + part.Content = contentItem; + } + else { + part.Content = null; + } + } + + protected override void Exporting(ContentMenuItemPart part, ExportContentContext context) { + if (part.Content != null) { + var contentItem = _contentManager.Get(part.Content.Id); + if (contentItem != null) { + var containerIdentity = _contentManager.GetItemMetadata(contentItem).Identity; + context.Element(part.PartDefinition.Name).SetAttributeValue("ContentItem", containerIdentity.ToString()); + } + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/Handlers/ContentMenuItemPartHandler.cs b/src/Orchard.Web/Core/Navigation/Handlers/ContentMenuItemPartHandler.cs new file mode 100644 index 000000000..ff7744b11 --- /dev/null +++ b/src/Orchard.Web/Core/Navigation/Handlers/ContentMenuItemPartHandler.cs @@ -0,0 +1,18 @@ +using JetBrains.Annotations; +using Orchard.ContentManagement; +using Orchard.Core.Navigation.Models; +using Orchard.Data; +using Orchard.ContentManagement.Handlers; + +namespace Orchard.Core.Navigation.Handlers { + [UsedImplicitly] + public class ContentMenuItemPartHandler : ContentHandler { + + public ContentMenuItemPartHandler(IContentManager contentManager, IRepository repository) { + Filters.Add(new ActivatingFilter("ContentMenuItem")); + Filters.Add(StorageFilter.For(repository)); + + OnLoading((context, part) => part._content.Loader(p => contentManager.Get(part.Record.ContentMenuItemRecord.Id))); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/Migrations.cs b/src/Orchard.Web/Core/Navigation/Migrations.cs index 116e1fa37..691dd9fba 100644 --- a/src/Orchard.Web/Core/Navigation/Migrations.cs +++ b/src/Orchard.Web/Core/Navigation/Migrations.cs @@ -72,6 +72,21 @@ namespace Orchard.Core.Navigation { ContentDefinitionManager.AlterPartDefinition("AdminMenuPart", builder => builder.Attachable()); + SchemaBuilder.CreateTable("ContentMenuItemPartRecord", + table => table + .ContentPartRecord() + .Column("ContentMenuItemRecord_id") + ); + + ContentDefinitionManager.AlterTypeDefinition("ContentMenuItem", cfg => cfg + .WithPart("MenuPart") + .WithPart("CommonPart") + .WithPart("ContentMenuItemPart") + .DisplayedAs("Content Menu Item") + .WithSetting("Description", "Adds a Content Item to the menu.") + .WithSetting("Stereotype", "MenuItem") + ); + return 3; } diff --git a/src/Orchard.Web/Core/Navigation/Models/ContentMenuItemPart.cs b/src/Orchard.Web/Core/Navigation/Models/ContentMenuItemPart.cs new file mode 100644 index 000000000..6fd311d72 --- /dev/null +++ b/src/Orchard.Web/Core/Navigation/Models/ContentMenuItemPart.cs @@ -0,0 +1,17 @@ +using Orchard.ContentManagement; +using Orchard.ContentManagement.Utilities; + +namespace Orchard.Core.Navigation.Models { + public class ContentMenuItemPart : ContentPart { + + public readonly LazyField _content = new LazyField(); + + public ContentItem Content { + get { return _content.Value; } + set { + _content.Value = value; + Record.ContentMenuItemRecord = value == null ? null : value.Record; + } + } + } +} diff --git a/src/Orchard.Web/Core/Navigation/Models/ContentMenuItemPartRecord.cs b/src/Orchard.Web/Core/Navigation/Models/ContentMenuItemPartRecord.cs index c28647a0a..eef1b90ae 100644 --- a/src/Orchard.Web/Core/Navigation/Models/ContentMenuItemPartRecord.cs +++ b/src/Orchard.Web/Core/Navigation/Models/ContentMenuItemPartRecord.cs @@ -2,6 +2,6 @@ namespace Orchard.Core.Navigation.Models { public class ContentMenuItemPartRecord : ContentPartRecord { - public virtual ContentItemRecord ContentItemRecord { get; set; } + public virtual ContentItemRecord ContentMenuItemRecord { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/Module.txt b/src/Orchard.Web/Core/Navigation/Module.txt index 4c7f78beb..e731292d9 100644 --- a/src/Orchard.Web/Core/Navigation/Module.txt +++ b/src/Orchard.Web/Core/Navigation/Module.txt @@ -7,3 +7,4 @@ OrchardVersion: 1.4.1 Description: The navigation module creates and manages a simple navigation menu for the front-end of the application and allows you to add content items to the admin menu. FeatureDescription: Menu management. Category: Core +FeatureDependencies: Orchard.ContentPicker diff --git a/src/Orchard.Web/Core/Navigation/Placement.info b/src/Orchard.Web/Core/Navigation/Placement.info index 09ea70cad..4f6a565e7 100644 --- a/src/Orchard.Web/Core/Navigation/Placement.info +++ b/src/Orchard.Web/Core/Navigation/Placement.info @@ -2,6 +2,7 @@ + \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/ViewModels/ContentMenuItemEditViewModel.cs b/src/Orchard.Web/Core/Navigation/ViewModels/ContentMenuItemEditViewModel.cs new file mode 100644 index 000000000..8944f74ce --- /dev/null +++ b/src/Orchard.Web/Core/Navigation/ViewModels/ContentMenuItemEditViewModel.cs @@ -0,0 +1,8 @@ +using Orchard.Core.Navigation.Models; + +namespace Orchard.Core.Navigation.ViewModels { + public class ContentMenuItemEditViewModel { + public int ContentItemId { get; set; } + public ContentMenuItemPart Part { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/Views/EditorTemplates/Parts.ContentMenuItem.Edit.cshtml b/src/Orchard.Web/Core/Navigation/Views/EditorTemplates/Parts.ContentMenuItem.Edit.cshtml new file mode 100644 index 000000000..d5da2e12e --- /dev/null +++ b/src/Orchard.Web/Core/Navigation/Views/EditorTemplates/Parts.ContentMenuItem.Edit.cshtml @@ -0,0 +1,25 @@ +@model Orchard.Core.Navigation.ViewModels.ContentMenuItemEditViewModel +@{ + Script.Require("ContentPicker").AtFoot(); +} +
+ + @Html.TextBoxFor(m => m.ContentItemId, new { @class = "small text", @readonly = "readonly" }) @T("Browse") + @T("Select the Content Item to display in the menu.") +
+ +@using(Script.Foot()) { + +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/Views/MenuItemLink-ContentMenuItem.cshtml b/src/Orchard.Web/Core/Navigation/Views/MenuItemLink-ContentMenuItem.cshtml new file mode 100644 index 000000000..16aa754b3 --- /dev/null +++ b/src/Orchard.Web/Core/Navigation/Views/MenuItemLink-ContentMenuItem.cshtml @@ -0,0 +1,2 @@ +@using Orchard.ContentManagement +@Model.Text \ No newline at end of file diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index 973f91f66..5afbb274e 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -131,12 +131,15 @@ + + + @@ -146,6 +149,7 @@ + @@ -189,7 +193,7 @@ - + @@ -528,6 +532,12 @@ + + + + + +