diff --git a/src/Orchard.Web/Core/Common/Drivers/BodyDriver.cs b/src/Orchard.Web/Core/Common/Drivers/BodyDriver.cs index 20d5e0a1b..e4dc6f79f 100644 --- a/src/Orchard.Web/Core/Common/Drivers/BodyDriver.cs +++ b/src/Orchard.Web/Core/Common/Drivers/BodyDriver.cs @@ -1,6 +1,8 @@ -using System.Text.RegularExpressions; +using System; +using System.Text.RegularExpressions; using JetBrains.Annotations; using Orchard.ContentManagement; +using Orchard.ContentManagement.Aspects; using Orchard.ContentManagement.Drivers; using Orchard.Core.Common.Models; using Orchard.Core.Common.ViewModels; @@ -17,7 +19,7 @@ namespace Orchard.Core.Common.Drivers { } protected override string Prefix { - get {return "Body";} + get { return "Body"; } } // \/\/ Haackalicious on many accounts - don't copy what has been done here for the wrapper \/\/ @@ -30,18 +32,77 @@ namespace Orchard.Core.Common.Drivers { ContentPartTemplate(model, TemplateName, Prefix).LongestMatch(displayType, "Summary", "SummaryAdmin").Location("primary", "5"), Services.Authorizer.Authorize(Permissions.ChangeOwner) ? ContentPartTemplate(model, "Parts/Common.Body.ManageWrapperPost").Location("primary", "5") : null); } - + protected override DriverResult Editor(BodyAspect part) { - var model = new BodyEditorViewModel { BodyAspect = part, TextEditorTemplate = DefaultTextEditorTemplate }; + var model = BuildEditorViewModel(part); return ContentPartTemplate(model, TemplateName, Prefix).Location("primary", "5"); } protected override DriverResult Editor(BodyAspect part, IUpdateModel updater) { - var model = new BodyEditorViewModel { BodyAspect = part, TextEditorTemplate = DefaultTextEditorTemplate }; + var model = BuildEditorViewModel(part); updater.TryUpdateModel(model, Prefix, null, null); return ContentPartTemplate(model, TemplateName, Prefix).Location("primary", "5"); } + private static BodyEditorViewModel BuildEditorViewModel(BodyAspect part) { + return new BodyEditorViewModel { + BodyAspect = part, + TextEditorTemplate = DefaultTextEditorTemplate, + AddMediaPath= new PathBuilder(part).AddContentType().AddContainerSlug().AddSlug().ToString() + }; + } + class PathBuilder { + private readonly IContent _content; + private string _path; + + public PathBuilder(IContent content) { + _content = content; + _path = ""; + } + + public override string ToString() { + return _path; + } + + public PathBuilder AddContentType() { + Add(_content.ContentItem.ContentType); + return this; + } + + public PathBuilder AddContainerSlug() { + var common = _content.As(); + if (common == null) + return this; + + var routable = common.Container.As(); + if (routable == null) + return this; + + Add(routable.Slug); + return this; + } + + public PathBuilder AddSlug() { + var routable = _content.As(); + if (routable == null) + return this; + + Add(routable.Slug); + return this; + } + + private void Add(string segment) { + if (string.IsNullOrEmpty(segment)) + return; + if (string.IsNullOrEmpty(_path)) + _path = segment; + else + _path = _path + "/" + segment; + } + + } + + // Can be moved somewhere else once we have IoC enabled body text filters. private static string BbcodeReplace(string bodyText) { Regex urlRegex = new Regex(@"\[url\]([^\]]+)\[\/url\]"); diff --git a/src/Orchard.Web/Core/Common/ViewModels/BodyEditorViewModel.cs b/src/Orchard.Web/Core/Common/ViewModels/BodyEditorViewModel.cs index 272b55e0d..c1e723a1e 100644 --- a/src/Orchard.Web/Core/Common/ViewModels/BodyEditorViewModel.cs +++ b/src/Orchard.Web/Core/Common/ViewModels/BodyEditorViewModel.cs @@ -15,5 +15,6 @@ namespace Orchard.Core.Common.ViewModels { } public string TextEditorTemplate { get; set; } + public string AddMediaPath { get; set; } } } \ 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 97b36865a..e48fac9e0 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -131,6 +131,7 @@ + diff --git a/src/Orchard.Web/Core/Themes/DesignerNotes/ZoneManagerEvents.cs b/src/Orchard.Web/Core/Themes/DesignerNotes/ZoneManagerEvents.cs new file mode 100644 index 000000000..4f07d0f06 --- /dev/null +++ b/src/Orchard.Web/Core/Themes/DesignerNotes/ZoneManagerEvents.cs @@ -0,0 +1,61 @@ +using System.IO; +using System.Linq; +using System.Web.Mvc.Html; +using Orchard.Security; +using Orchard.Themes; +using Orchard.UI.Zones; + +namespace Orchard.Core.Themes.DesignerNotes { + public class ZoneManagerEvents : IZoneManagerEvents { + private readonly IThemeService _themeService; + private readonly IAuthorizationService _authorizationService; + + public ZoneManagerEvents(IThemeService themeService, IAuthorizationService authorizationService) { + _themeService = themeService; + _authorizationService = authorizationService; + } + + public virtual IUser CurrentUser { get; set; } + + public void ZoneRendering(ZoneRenderContext context) { + if (context.RenderingItems.Any()) + return; + + var requestContext = context.Html.ViewContext.RequestContext; + var theme = _themeService.GetRequestTheme(requestContext); + var virtualPath = "~/Themes/" + theme.ThemeName + "/DesignerNotes/" + context.ZoneName + ".html"; + var physicalPath = requestContext.HttpContext.Server.MapPath(virtualPath); + if (!File.Exists(physicalPath)) + return; + + var accessAdminPanel = _authorizationService.TryCheckAccess( + StandardPermissions.AccessAdminPanel, CurrentUser, null); + + var writer = context.Html.ViewContext.Writer; + if (accessAdminPanel) { + writer.Write("
"); + writer.Write(context.Html.ActionLink("Edit", "AddWidget", new { + Area = "Futures.Widgets", + Controller = "Admin", + context.ZoneName, + theme.ThemeName, + ReturnUrl = requestContext.HttpContext.Request.Url, + })); + writer.Write("
"); + } + writer.Write(File.ReadAllText(physicalPath)); + if (accessAdminPanel) { + writer.Write("
"); + } + } + + public void ZoneItemRendering(ZoneRenderContext context, ZoneItem item) { + } + + public void ZoneItemRendered(ZoneRenderContext context, ZoneItem item) { + } + + public void ZoneRendered(ZoneRenderContext context) { + } + } +} diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Futures.Widgets/Controllers/AdminController.cs index 6706ed689..cb385a377 100644 --- a/src/Orchard.Web/Modules/Futures.Widgets/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Futures.Widgets/Controllers/AdminController.cs @@ -1,5 +1,4 @@ -using System; -using System.Web.Mvc; +using System.Web.Mvc; using Futures.Widgets.Models; using Futures.Widgets.ViewModels; using Orchard; @@ -7,28 +6,39 @@ using Orchard.ContentManagement; using Orchard.Core.Common.Models; using Orchard.Localization; using Orchard.Settings; +using Orchard.UI.Notify; namespace Futures.Widgets.Controllers { [ValidateInput(false)] public class AdminController : Controller, IUpdateModel { public AdminController(IOrchardServices services) { Services = services; + T = NullLocalizer.Instance; } private IOrchardServices Services { get; set; } protected virtual ISite CurrentSite { get; set; } + public Localizer T{ get; set;} - public ActionResult AddWidget() { + public ActionResult AddWidget(string zoneName, string themeName, string returnUrl) { var hasWidgetsRecord = CurrentSite.As().Record; + var virtualPath = "~/Themes/" + themeName + "/DesignerNotes/" + zoneName + ".html"; + var physicalPath = Server.MapPath(virtualPath); + + if (!System.IO.File.Exists(physicalPath)) { + Services.Notifier.Error(T("Designer notes not found.")); + return Redirect(returnUrl); + } + var widget = Services.ContentManager.Create("HtmlWidget", init => { init.Record.Scope = hasWidgetsRecord; - init.Record.Zone = "content"; - init.Record.Position = "after"; - init.As().Text = "Hello world!"; + init.Record.Zone = zoneName; + init.Record.Position = "1"; + init.As().Text = System.IO.File.ReadAllText(physicalPath); }); - return RedirectToAction("Edit", new {widget.ContentItem.Id }); + return RedirectToAction("Edit", new { widget.ContentItem.Id, returnUrl }); } public ActionResult Edit(int id, string returnUrl) { diff --git a/src/Orchard.Web/Modules/TinyMce/Extensions/HtmlHelperExtensions.cs b/src/Orchard.Web/Modules/TinyMce/Extensions/HtmlHelperExtensions.cs deleted file mode 100644 index 65d49a7c4..000000000 --- a/src/Orchard.Web/Modules/TinyMce/Extensions/HtmlHelperExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Web.Mvc; -using Orchard.ContentManagement; -using Orchard.ContentManagement.Drivers; -using Orchard.Core.Common.Models; -using Orchard.Core.Common.ViewModels; -using Orchard.Extensions; -using Orchard.Mvc.Html; - -namespace TinyMce.Extensions { - public static class HtmlHelperExtensions { - public static string GetCurrentMediaPath(this HtmlHelper htmlHelper) { - var body = htmlHelper.ViewData.Model.BodyAspect; - var currentDriver = htmlHelper.Resolve>().Where(cid => cid.GetContentTypes().Any(ct => string.Compare(ct.Name, body.ContentItem.ContentType, true) == 0)).FirstOrDefault(); - var currentModule = htmlHelper.Resolve().ActiveExtensions().FirstOrDefault(ee => ee.Descriptor.ExtensionType == "Module" && ee.Assembly == currentDriver.GetType().Assembly); - var routable = body.ContentItem.Has() ? body.ContentItem.As() : null; - - return string.Format("{0}{1}", currentModule.Descriptor.Name, routable != null && !string.IsNullOrEmpty(routable.ContainerPath) ? "/" + routable.ContainerPath : ""); - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/TinyMce/TinyMce.csproj b/src/Orchard.Web/Modules/TinyMce/TinyMce.csproj index e74679737..d20a7f730 100644 --- a/src/Orchard.Web/Modules/TinyMce/TinyMce.csproj +++ b/src/Orchard.Web/Modules/TinyMce/TinyMce.csproj @@ -122,7 +122,6 @@ - diff --git a/src/Orchard.Web/Modules/TinyMce/Views/EditorTemplates/TinyMceTextEditor.ascx b/src/Orchard.Web/Modules/TinyMce/Views/EditorTemplates/TinyMceTextEditor.ascx index 5ce39e585..8c90831a2 100644 --- a/src/Orchard.Web/Modules/TinyMce/Views/EditorTemplates/TinyMceTextEditor.ascx +++ b/src/Orchard.Web/Modules/TinyMce/Views/EditorTemplates/TinyMceTextEditor.ascx @@ -19,7 +19,7 @@ using (this.Capture("end-of-page-scripts")) {%> theme_advanced_buttons3: "", convert_urls: false, addmedia_action: "<%=Url.Action("AddFromClient", "Admin", new {area = "Orchard.Media"}) %>", - addmedia_path: "<%=Html.GetCurrentMediaPath() %>", + addmedia_path: "<%= Model.AddMediaPath %>", request_verification_token: "<%=Html.AntiForgeryTokenValueOrchard() %>" }); <% diff --git a/src/Orchard.Web/Orchard.Web.csproj b/src/Orchard.Web/Orchard.Web.csproj index 5c408565b..bb66a1a39 100644 --- a/src/Orchard.Web/Orchard.Web.csproj +++ b/src/Orchard.Web/Orchard.Web.csproj @@ -170,6 +170,7 @@ + @@ -192,6 +193,10 @@ + + + + diff --git a/src/Orchard.Web/Themes/Classic/DesignerNotes/Sidebar.html b/src/Orchard.Web/Themes/Classic/DesignerNotes/Sidebar.html new file mode 100644 index 000000000..177a88e1f --- /dev/null +++ b/src/Orchard.Web/Themes/Classic/DesignerNotes/Sidebar.html @@ -0,0 +1,8 @@ +
    +
  • +

    Heading

    +
  • +
  • +

    Paragraph - Small

    +
  • +
diff --git a/src/Orchard.Web/Themes/Classic/Views/Layout.ascx b/src/Orchard.Web/Themes/Classic/Views/Layout.ascx index 71945c5fc..fe247668c 100644 --- a/src/Orchard.Web/Themes/Classic/Views/Layout.ascx +++ b/src/Orchard.Web/Themes/Classic/Views/Layout.ascx @@ -33,16 +33,7 @@ <%Html.ZoneBody("content");%> <%-- End Content --%> <% Html.Include("Footer"); %> diff --git a/src/Orchard.Web/Themes/Green/DesignerNotes/Sidebar.html b/src/Orchard.Web/Themes/Green/DesignerNotes/Sidebar.html new file mode 100644 index 000000000..127613180 --- /dev/null +++ b/src/Orchard.Web/Themes/Green/DesignerNotes/Sidebar.html @@ -0,0 +1,25 @@ +

Sidebar

+
    +
  • +

    Item 1

    +
  • +
  • +

    + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas adipiscing dolor + vel nunc molestie laoreet. Curabitur vitae elit et massa consequat interdum. Curabitur + blandit leo nec magna dictum vitae mollis tellus gravida. Morbi non condimentum + neque. Suspendisse commodo condimentum feugiat. Class aptent taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos.

    +
  • +
  • +

    Item 2

    +
  • +
  • +

    + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas adipiscing dolor + vel nunc molestie laoreet. Curabitur vitae elit et massa consequat interdum. Curabitur + blandit leo nec magna dictum vitae mollis tellus gravida. Morbi non condimentum + neque. Suspendisse commodo condimentum feugiat. Class aptent taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos.

    +
  • +
diff --git a/src/Orchard.Web/Themes/Green/DesignerNotes/User1.html b/src/Orchard.Web/Themes/Green/DesignerNotes/User1.html new file mode 100644 index 000000000..8c5d0c3b7 --- /dev/null +++ b/src/Orchard.Web/Themes/Green/DesignerNotes/User1.html @@ -0,0 +1,3 @@ +
About Your Site
+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam nec nisi vel eros ornare auctor. Aenean vitae nulla. Sed in velit sit amet metus sollicitudin porttitor. Fusce non tortor. Nunc ornare imperdiet mauris. Nulla facilisi. In hac habitasse platea dictumst. Praesent pellentesque iaculis orci. Ut imperdiet dolor non turpis. In hac habitasse platea dictumst. More... +

diff --git a/src/Orchard.Web/Themes/Green/DesignerNotes/User2.html b/src/Orchard.Web/Themes/Green/DesignerNotes/User2.html new file mode 100644 index 000000000..c0d2593e6 --- /dev/null +++ b/src/Orchard.Web/Themes/Green/DesignerNotes/User2.html @@ -0,0 +1,8 @@ +
Lorem ipsum
+ diff --git a/src/Orchard.Web/Themes/Green/DesignerNotes/User3.html b/src/Orchard.Web/Themes/Green/DesignerNotes/User3.html new file mode 100644 index 000000000..c0d2593e6 --- /dev/null +++ b/src/Orchard.Web/Themes/Green/DesignerNotes/User3.html @@ -0,0 +1,8 @@ +
Lorem ipsum
+ diff --git a/src/Orchard.Web/Themes/Green/Views/Footer.ascx b/src/Orchard.Web/Themes/Green/Views/Footer.ascx index a7ecfbea2..18f93872d 100644 --- a/src/Orchard.Web/Themes/Green/Views/Footer.ascx +++ b/src/Orchard.Web/Themes/Green/Views/Footer.ascx @@ -1,38 +1,17 @@ -<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> -<%-- - - - ---%> -
-

Sidebar

-
    -
  • Item 1

  • -
  • Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas adipiscing dolor vel nunc molestie laoreet. Curabitur vitae elit et massa consequat interdum. Curabitur blandit leo nec magna dictum vitae mollis tellus gravida. Morbi non condimentum neque. Suspendisse commodo condimentum feugiat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

  • - -
  • Item 2

  • -
  • Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas adipiscing dolor vel nunc molestie laoreet. Curabitur vitae elit et massa consequat interdum. Curabitur blandit leo nec magna dictum vitae mollis tellus gravida. Morbi non condimentum neque. Suspendisse commodo condimentum feugiat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

  • -
- + <%Html.Zone("sidebar"); %>
<%-- End Content --%> diff --git a/src/Orchard/Orchard.csproj b/src/Orchard/Orchard.csproj index 9a6d6484f..f45f503fa 100644 --- a/src/Orchard/Orchard.csproj +++ b/src/Orchard/Orchard.csproj @@ -311,6 +311,7 @@ + diff --git a/src/Orchard/UI/Zones/IZoneManagerEvents.cs b/src/Orchard/UI/Zones/IZoneManagerEvents.cs new file mode 100644 index 000000000..4eb7273f6 --- /dev/null +++ b/src/Orchard/UI/Zones/IZoneManagerEvents.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Web.Mvc; + +namespace Orchard.UI.Zones { + public interface IZoneManagerEvents : IEvents { + void ZoneRendering(ZoneRenderContext context); + void ZoneItemRendering(ZoneRenderContext context, ZoneItem item); + void ZoneItemRendered(ZoneRenderContext context, ZoneItem item); + void ZoneRendered(ZoneRenderContext context); + } + public class ZoneRenderContext { + public HtmlHelper Html { get; set; } + public ZoneCollection Zones { get; set; } + public string ZoneName { get; set; } + public IEnumerable RenderingItems { get; set; } + } + +} \ No newline at end of file diff --git a/src/Orchard/UI/Zones/ZoneManager.cs b/src/Orchard/UI/Zones/ZoneManager.cs index 05d18c265..932154039 100644 --- a/src/Orchard/UI/Zones/ZoneManager.cs +++ b/src/Orchard/UI/Zones/ZoneManager.cs @@ -2,10 +2,19 @@ using System.Collections.Generic; using System.Linq; using System.Web.Mvc; +using Orchard.Logging; using Orchard.UI.Navigation; namespace Orchard.UI.Zones { + public class ZoneManager : IZoneManager { + private readonly IEnumerable _events; + + public ZoneManager(IEnumerable events) { + _events = events; + Logger = NullLogger.Instance; + } + public void Render(HtmlHelper html, ZoneCollection zones, string zoneName, string partitions, string[] exclude) { IEnumerable groups; if (string.IsNullOrEmpty(zoneName)) { @@ -14,18 +23,35 @@ namespace Orchard.UI.Zones { } else { ZoneEntry entry; - if (!zones.TryGetValue(zoneName, out entry)) - return; - groups = BuildGroups(partitions, new[] { entry }); + if (zones.TryGetValue(zoneName, out entry)) { + groups = BuildGroups(partitions, new[] { entry }); + } + else { + groups = Enumerable.Empty(); + } } - foreach (var item in groups.SelectMany(x => x.Items)) { - item.WasExecuted = true; - item.Execute(html); + var context = new ZoneRenderContext { + Html = html, + Zones = zones, + ZoneName = zoneName, + RenderingItems = groups.SelectMany(x => x.Items).ToList() + }; + + _events.Invoke(x => x.ZoneRendering(context), Logger); + foreach (var item in context.RenderingItems) { + var zoneItem = item; + _events.Invoke(x => x.ZoneItemRendering(context, zoneItem), Logger); + zoneItem.WasExecuted = true; + zoneItem.Execute(html); + _events.Invoke(x => x.ZoneItemRendered(context, zoneItem), Logger); } + _events.Invoke(x => x.ZoneRendered(context), Logger); } + protected ILogger Logger { get; set; } + private IEnumerable BuildGroups(string partitions, IEnumerable zones) { var partitionCodes = (":before " + partitions + " :* :after").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);