diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Futures.Widgets/Controllers/AdminController.cs new file mode 100644 index 000000000..6706ed689 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Controllers/AdminController.cs @@ -0,0 +1,68 @@ +using System; +using System.Web.Mvc; +using Futures.Widgets.Models; +using Futures.Widgets.ViewModels; +using Orchard; +using Orchard.ContentManagement; +using Orchard.Core.Common.Models; +using Orchard.Localization; +using Orchard.Settings; + +namespace Futures.Widgets.Controllers { + [ValidateInput(false)] + public class AdminController : Controller, IUpdateModel { + public AdminController(IOrchardServices services) { + Services = services; + } + + private IOrchardServices Services { get; set; } + protected virtual ISite CurrentSite { get; set; } + + public ActionResult AddWidget() { + var hasWidgetsRecord = CurrentSite.As().Record; + + var widget = Services.ContentManager.Create("HtmlWidget", init => { + init.Record.Scope = hasWidgetsRecord; + init.Record.Zone = "content"; + init.Record.Position = "after"; + init.As().Text = "Hello world!"; + }); + + return RedirectToAction("Edit", new {widget.ContentItem.Id }); + } + + public ActionResult Edit(int id, string returnUrl) { + var widget = Services.ContentManager.Get(id); + var viewModel = new WidgetEditViewModel { + Widget = Services.ContentManager.BuildEditorModel(widget), + ReturnUrl = returnUrl, + }; + return View(viewModel); + } + + [HttpPost, ActionName("Edit")] + public ActionResult EditPOST(int id, string returnUrl) { + var widget = Services.ContentManager.Get(id); + var viewModel = new WidgetEditViewModel { + Widget = Services.ContentManager.UpdateEditorModel(widget, this), + ReturnUrl = returnUrl, + }; + if (ModelState.IsValid == false) { + return View(viewModel); + } + if (string.IsNullOrEmpty(returnUrl)) { + return RedirectToAction("Edit", new { id }); + } + return Redirect(returnUrl); + } + + + bool IUpdateModel.TryUpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) { + return TryUpdateModel(model, prefix, includeProperties, excludeProperties); + } + + void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) { + ModelState.AddModelError(key, errorMessage.ToString()); + } + } +} diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Controllers/WidgetDriver.cs b/src/Orchard.Web/Modules/Futures.Widgets/Controllers/WidgetDriver.cs new file mode 100644 index 000000000..226c08f12 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Controllers/WidgetDriver.cs @@ -0,0 +1,20 @@ +using System.Web.Routing; +using Futures.Widgets.Models; +using Orchard.ContentManagement.Drivers; + +namespace Futures.Widgets.Controllers { + public class WidgetDriver : ContentItemDriver { + protected override RouteValueDictionary GetEditorRouteValues(Widget item) { + return new RouteValueDictionary { + {"Area", "Futures.Widgets"}, + {"Controller", "Admin"}, + {"Action", "Edit"}, + {"Id", item.ContentItem.Id} + }; + } + + protected override bool UseDefaultTemplate { + get { return true; } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Controllers/WidgetHandler.cs b/src/Orchard.Web/Modules/Futures.Widgets/Controllers/WidgetHandler.cs new file mode 100644 index 000000000..84ffd1181 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Controllers/WidgetHandler.cs @@ -0,0 +1,50 @@ +using System.Linq; +using System.Web.Routing; +using Futures.Widgets.Models; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Drivers; +using Orchard.ContentManagement.Handlers; +using Orchard.Core.Common.Models; +using Orchard.Data; + +namespace Futures.Widgets.Controllers { + public class WidgetHandler : ContentHandler { + public WidgetHandler( + IRepository hasWidgetRepository, + IRepository widgetRepository) { + + // marking the "site" content type as a widget container + Filters.Add(new ActivatingFilter("site")); + + // adding parts to the "HtmlWidget" content type + Filters.Add(new ActivatingFilter("HtmlWidget")); + Filters.Add(new ActivatingFilter("HtmlWidget")); + + // providing standard storage support for widget records + Filters.Add(StorageFilter.For(hasWidgetRepository)); + Filters.Add(StorageFilter.For(widgetRepository)); + + OnLoaded( + (ctx, part) => part.WidgetField.Loader( + () => ctx.ContentManager + .Query() + .Where(x => x.Scope == part.Record) + .List().ToList())); + } + } + + public class WidgetDriver : ContentItemDriver { + protected override RouteValueDictionary GetEditorRouteValues(Widget item) { + return new RouteValueDictionary { + {"Area", "Futures.Widgets"}, + {"Controller", "Admin"}, + {"Action", "Edit"}, + {"Id", item.ContentItem.Id} + }; + } + + protected override bool UseDefaultTemplate { + get { return true; } + } + } +} diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Futures.Widgets.csproj b/src/Orchard.Web/Modules/Futures.Widgets/Futures.Widgets.csproj new file mode 100644 index 000000000..8ee420c90 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Futures.Widgets.csproj @@ -0,0 +1,118 @@ + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {E65E5633-C0FF-453C-A906-481C14F969D6} + {F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Futures.Widgets + Futures.Widgets + v3.5 + false + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + 3.5 + + + 3.5 + + + 3.5 + + + False + ..\..\..\..\..\..\Program Files\Microsoft ASP.NET\ASP.NET MVC 2\\Assemblies\System.Web.Mvc.dll + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} + Orchard + + + {9916839C-39FC-4CEB-A5AF-89CA7E87119F} + Orchard.Core + + + + + + + + + + + + + + + + False + True + 17593 + / + + + False + True + http://orchard.codeplex.com + False + + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Models/HasWidgets.cs b/src/Orchard.Web/Modules/Futures.Widgets/Models/HasWidgets.cs new file mode 100644 index 000000000..b30dde572 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Models/HasWidgets.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Records; +using Orchard.Core.Common.Utilities; + +namespace Futures.Widgets.Models { + public class HasWidgets : ContentPart { + public LazyField> WidgetField = new LazyField>(); + public IList Widgets { get { return WidgetField.Value; } set { WidgetField.Value = value; } } + } + + public class HasWidgetsRecord : ContentPartRecord { + } +} diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Models/Widget.cs b/src/Orchard.Web/Modules/Futures.Widgets/Models/Widget.cs new file mode 100644 index 000000000..c2c693eec --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Models/Widget.cs @@ -0,0 +1,13 @@ +using Orchard.ContentManagement; +using Orchard.ContentManagement.Records; + +namespace Futures.Widgets.Models { + public class Widget : ContentPart { + } + + public class WidgetRecord : ContentPartRecord { + public virtual HasWidgetsRecord Scope { get; set; } + public virtual string Zone { get; set; } + public virtual string Position { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Module.txt b/src/Orchard.Web/Modules/Futures.Widgets/Module.txt new file mode 100644 index 000000000..b38d568c2 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Module.txt @@ -0,0 +1 @@ +name: Widgets diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Futures.Widgets/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..b0a50137d --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Futures.Widgets")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft IT")] +[assembly: AssemblyProduct("Futures.Widgets")] +[assembly: AssemblyCopyright("Copyright © Microsoft IT 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8c179868-e814-4277-a0af-b71707c3bff4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Orchard.Web/Modules/Futures.Widgets/ViewModels/WidgetEditViewModel.cs b/src/Orchard.Web/Modules/Futures.Widgets/ViewModels/WidgetEditViewModel.cs new file mode 100644 index 000000000..1f288285e --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/ViewModels/WidgetEditViewModel.cs @@ -0,0 +1,8 @@ +using Orchard.Mvc.ViewModels; + +namespace Futures.Widgets.ViewModels { + public class WidgetEditViewModel : BaseViewModel { + public ContentItemViewModel Widget { get; set; } + public string ReturnUrl { get; set;} + } +} diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Views/Admin/Edit.ascx b/src/Orchard.Web/Modules/Futures.Widgets/Views/Admin/Edit.ascx new file mode 100644 index 000000000..f42d7c0cf --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Views/Admin/Edit.ascx @@ -0,0 +1,12 @@ +<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %> +<%@ Import Namespace="Futures.Widgets.ViewModels" %> +<%@ Import Namespace="Orchard.Mvc.Html" %> +

<%=Html.TitleForPage(T("Edit Widget").ToString()) %>

+<% using (Html.BeginFormAntiForgeryPost()) { %> + <%= Html.ValidationSummary() %> + <%= Html.EditorForItem(m => m.Widget) %> +
+ <%= Html.HiddenFor(m => m.ReturnUrl) %> + +
+<%} %> diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Views/Web.config b/src/Orchard.Web/Modules/Futures.Widgets/Views/Web.config new file mode 100644 index 000000000..7022197d4 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Views/Web.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Futures.Widgets/Web.config b/src/Orchard.Web/Modules/Futures.Widgets/Web.config new file mode 100644 index 000000000..b1c399e16 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/Web.config @@ -0,0 +1,154 @@ + + + + + + + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Futures.Widgets/WidgetFilter.cs b/src/Orchard.Web/Modules/Futures.Widgets/WidgetFilter.cs new file mode 100644 index 000000000..dd6f14fc3 --- /dev/null +++ b/src/Orchard.Web/Modules/Futures.Widgets/WidgetFilter.cs @@ -0,0 +1,43 @@ +using System; +using System.Linq; +using System.Web.Mvc; +using Futures.Widgets.Models; +using Orchard.ContentManagement; +using Orchard.Mvc.Filters; +using Orchard.Mvc.ViewModels; +using Orchard.Settings; +using Orchard.UI.Admin; + +namespace Futures.Widgets { + public class WidgetFilter : FilterProvider, IActionFilter { + private readonly IContentManager _contentManager; + + public WidgetFilter(IContentManager contentManager) { + _contentManager = contentManager; + } + + public virtual ISite CurrentSite { get; set; } + + public void OnActionExecuting(ActionExecutingContext filterContext) { + } + + public void OnActionExecuted(ActionExecutedContext filterContext) { + var model = BaseViewModel.From(filterContext.Result); + if (model == null || AdminFilter.IsApplied(filterContext.RequestContext)) { + return; + } + + var siteWidgets = CurrentSite.As(); + if (siteWidgets == null) { + return; + } + + var zones = model.Zones; + foreach (var widget in siteWidgets.Widgets) { + zones.AddDisplayItem( + widget.Record.Zone + ":" + widget.Record.Position, + _contentManager.BuildDisplayModel(widget, "Widget")); + } + } + } +} diff --git a/src/Orchard.Web/Modules/Orchard.DevTools/Views/DisplayTemplates/Parts/DevTools.ShowDebugLink.ascx b/src/Orchard.Web/Modules/Orchard.DevTools/Views/DisplayTemplates/Parts/DevTools.ShowDebugLink.ascx index b5ced4224..0ff4e2ef6 100644 --- a/src/Orchard.Web/Modules/Orchard.DevTools/Views/DisplayTemplates/Parts/DevTools.ShowDebugLink.ascx +++ b/src/Orchard.Web/Modules/Orchard.DevTools/Views/DisplayTemplates/Parts/DevTools.ShowDebugLink.ascx @@ -1,6 +1,6 @@ <%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %> <%@ Import Namespace="Orchard.DevTools.Models" %>
<%=T( - "DevTools: editing {0}", + "DevTools: displaying {0}", Html.ActionLink(T("{0} #{1} v{2}", Model.ContentItem.ContentType, Model.ContentItem.Id, Model.ContentItem.Version).ToString(), "details", "content", new { area = "Orchard.DevTools", Model.ContentItem.Id, Model.ContentItem.Version }, new { }) ) %>
diff --git a/src/Orchard.Web/Orchard.Web.csproj b/src/Orchard.Web/Orchard.Web.csproj index 184187747..260d326dd 100644 --- a/src/Orchard.Web/Orchard.Web.csproj +++ b/src/Orchard.Web/Orchard.Web.csproj @@ -102,6 +102,10 @@ {9916839C-39FC-4CEB-A5AF-89CA7E87119F} Orchard.Core + + {E65E5633-C0FF-453C-A906-481C14F969D6} + Futures.Widgets + {63FBD4D9-E1DA-4A7B-AA6A-D6074FE50867} Orchard.Blogs diff --git a/src/Orchard.sln b/src/Orchard.sln index f0297539d..6035c7e86 100644 --- a/src/Orchard.sln +++ b/src/Orchard.sln @@ -47,6 +47,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSBuild.Orchard.Tasks", "To EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSBuild.Orchard.Tasks.Tests", "Tools\MSBuild.Orchard.Tasks.Tests\MSBuild.Orchard.Tasks.Tests.csproj", "{4AB4B5B6-277E-4FF6-B69B-7AE9E16D2A56}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Futures", "Futures", "{E75A4CE4-CAA6-41E4-B951-33ACC60DC77C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Futures.Widgets", "Orchard.Web\Modules\Futures.Widgets\Futures.Widgets.csproj", "{E65E5633-C0FF-453C-A906-481C14F969D6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -133,6 +137,10 @@ Global {4AB4B5B6-277E-4FF6-B69B-7AE9E16D2A56}.Debug|Any CPU.Build.0 = Debug|Any CPU {4AB4B5B6-277E-4FF6-B69B-7AE9E16D2A56}.Release|Any CPU.ActiveCfg = Release|Any CPU {4AB4B5B6-277E-4FF6-B69B-7AE9E16D2A56}.Release|Any CPU.Build.0 = Release|Any CPU + {E65E5633-C0FF-453C-A906-481C14F969D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E65E5633-C0FF-453C-A906-481C14F969D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E65E5633-C0FF-453C-A906-481C14F969D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E65E5633-C0FF-453C-A906-481C14F969D6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -155,5 +163,6 @@ Global {8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {5E5E7A21-C7B2-44D8-8593-2F9541AE041D} = {383DBA32-4A3E-48D1-AAC3-75377A694452} {4AB4B5B6-277E-4FF6-B69B-7AE9E16D2A56} = {383DBA32-4A3E-48D1-AAC3-75377A694452} + {E65E5633-C0FF-453C-A906-481C14F969D6} = {E75A4CE4-CAA6-41E4-B951-33ACC60DC77C} EndGlobalSection EndGlobal diff --git a/src/Orchard/UI/Zones/ContentItemDisplayZoneItem.cs b/src/Orchard/UI/Zones/ContentItemDisplayZoneItem.cs index 604b3aba6..5e5857f84 100644 --- a/src/Orchard/UI/Zones/ContentItemDisplayZoneItem.cs +++ b/src/Orchard/UI/Zones/ContentItemDisplayZoneItem.cs @@ -7,7 +7,8 @@ namespace Orchard.UI.Zones { public ContentItemViewModel ViewModel { get; set; } public override void Execute(HtmlHelper html) { - html.DisplayForItem(ViewModel); + var htmlString = html.DisplayForItem(ViewModel); + html.ViewContext.Writer.Write(htmlString); } } } \ No newline at end of file diff --git a/src/Orchard/UI/Zones/ContentPartDisplayZoneItem.cs b/src/Orchard/UI/Zones/ContentPartDisplayZoneItem.cs index 91f587c41..f9e8ea408 100644 --- a/src/Orchard/UI/Zones/ContentPartDisplayZoneItem.cs +++ b/src/Orchard/UI/Zones/ContentPartDisplayZoneItem.cs @@ -8,8 +8,8 @@ namespace Orchard.UI.Zones { public string Prefix { get; set; } public override void Execute(HtmlHelper html) { - html.ViewContext.Writer.Write( - html.DisplayFor(m => Model, TemplateName, Prefix)); + var htmlString = html.DisplayFor(m => Model, TemplateName, Prefix); + html.ViewContext.Writer.Write(htmlString); } } } \ No newline at end of file