diff --git a/src/Orchard.Web/Modules/Orchard.Layouts/Handlers/LayoutPartHandler.cs b/src/Orchard.Web/Modules/Orchard.Layouts/Handlers/LayoutPartHandler.cs index 7e32d286e..53530f962 100644 --- a/src/Orchard.Web/Modules/Orchard.Layouts/Handlers/LayoutPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Layouts/Handlers/LayoutPartHandler.cs @@ -1,4 +1,5 @@ -using Orchard.ContentManagement; +using Orchard.Caching; +using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.Data; using Orchard.DisplayManagement; @@ -12,6 +13,7 @@ namespace Orchard.Layouts.Handlers { private readonly IContentPartDisplay _contentPartDisplay; private readonly IShapeDisplay _shapeDisplay; private readonly ILayoutSerializer _serializer; + private readonly ISignals _signals; public LayoutPartHandler( IRepository repository, @@ -19,16 +21,19 @@ namespace Orchard.Layouts.Handlers { IContentManager contentManager, IContentPartDisplay contentPartDisplay, IShapeDisplay shapeDisplay, - ILayoutSerializer serializer) { + ILayoutSerializer serializer, + ISignals signals) { _layoutManager = layoutManager; _contentManager = contentManager; _contentPartDisplay = contentPartDisplay; _shapeDisplay = shapeDisplay; _serializer = serializer; + _signals = signals; Filters.Add(StorageFilter.For(repository)); OnPublished(UpdateTemplateClients); + OnPublished(InvalidateLayoutZones); OnIndexing(IndexLayout); } @@ -45,6 +50,10 @@ namespace Orchard.Layouts.Handlers { UpdateTemplateClients(part); } + private void InvalidateLayoutZones(PublishContentContext context, LayoutPart part) { + _signals.Trigger(Signals.LayoutZones); + } + /// /// Recursively updates all layouts that use the specified layout as its template. /// diff --git a/src/Orchard.Web/Modules/Orchard.Layouts/Services/DefaultModelMaps.cs b/src/Orchard.Web/Modules/Orchard.Layouts/Services/DefaultModelMaps.cs index 43f3ebdca..819adf52c 100644 --- a/src/Orchard.Web/Modules/Orchard.Layouts/Services/DefaultModelMaps.cs +++ b/src/Orchard.Web/Modules/Orchard.Layouts/Services/DefaultModelMaps.cs @@ -46,7 +46,11 @@ namespace Orchard.Layouts.Services { element.IsTemplated = (bool)(node["isTemplated"] ?? false); } - protected bool? ParseBoolean(string value) { + protected bool? ReadBoolean(JToken node) { + if (node == null) + return null; + + var value = node.Value(); if (String.IsNullOrWhiteSpace(value)) return null; @@ -69,7 +73,7 @@ namespace Orchard.Layouts.Services { element.Width = (int?)node["width"]; element.Offset = (int?)node["offset"]; element.ZoneName = (string) node["zoneName"]; - element.Collapsible = ParseBoolean(node["collapsible"].Value()); + element.Collapsible = ReadBoolean(node["collapsible"]); } public override void FromElement(Column element, DescribeElementsContext describeContext, JToken node) { diff --git a/src/Orchard.Web/Modules/Orchard.Layouts/Services/ILayoutManager.cs b/src/Orchard.Web/Modules/Orchard.Layouts/Services/ILayoutManager.cs index ea9e26b4f..7ca114ca8 100644 --- a/src/Orchard.Web/Modules/Orchard.Layouts/Services/ILayoutManager.cs +++ b/src/Orchard.Web/Modules/Orchard.Layouts/Services/ILayoutManager.cs @@ -6,7 +6,16 @@ using Orchard.Layouts.Models; namespace Orchard.Layouts.Services { public interface ILayoutManager : IDependency { + /// + /// Returns all content items with a LayoutPart whose IsTemplate setting is set to true. + /// IEnumerable GetTemplates(); + + /// + /// Returns all content items with a LayoutPart. + /// + IEnumerable GetLayouts(); + LayoutPart GetLayout(int id); IEnumerable LoadElements(ILayoutAspect layout); diff --git a/src/Orchard.Web/Modules/Orchard.Layouts/Services/LayoutManager.cs b/src/Orchard.Web/Modules/Orchard.Layouts/Services/LayoutManager.cs index 34a83932f..9ae999b06 100644 --- a/src/Orchard.Web/Modules/Orchard.Layouts/Services/LayoutManager.cs +++ b/src/Orchard.Web/Modules/Orchard.Layouts/Services/LayoutManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Orchard.Caching; using Orchard.ContentManagement; using Orchard.Layouts.Elements; using Orchard.Layouts.Framework.Display; @@ -16,12 +17,23 @@ namespace Orchard.Layouts.Services { private readonly ILayoutSerializer _serializer; private readonly IElementDisplay _elementDisplay; private readonly IElementManager _elementManager; + private readonly ICacheManager _cacheManager; + private readonly ISignals _signals; + + public LayoutManager( + IContentManager contentManager, + ILayoutSerializer serializer, + IElementDisplay elementDisplay, + IElementManager elementManager, + ICacheManager cacheManager, + ISignals signals) { - public LayoutManager(IContentManager contentManager, ILayoutSerializer serializer, IElementDisplay elementDisplay, IElementManager elementManager) { _contentManager = contentManager; _serializer = serializer; _elementDisplay = elementDisplay; _elementManager = elementManager; + _cacheManager = cacheManager; + _signals = signals; } public IEnumerable GetTemplates() { @@ -35,6 +47,16 @@ namespace Orchard.Layouts.Services { return _contentManager.Query(templateTypeNames).List(); } + public IEnumerable GetLayouts() { + var templateTypeNamesQuery = from typeDefinition in _contentManager.GetContentTypeDefinitions() + from typePartDefinition in typeDefinition.Parts + where typePartDefinition.PartDefinition.Name == "LayoutPart" + select typeDefinition.Name; + + var templateTypeNames = templateTypeNamesQuery.ToArray(); + return _contentManager.Query(templateTypeNames).List(); + } + public LayoutPart GetLayout(int id) { return _contentManager.Get(id); } @@ -61,18 +83,21 @@ namespace Orchard.Layouts.Services { } public IEnumerable GetZones() { - var layouts = GetTemplates().ToList(); - var zoneNames = new HashSet(); + return _cacheManager.Get("LayoutZones", context => { + var layouts = GetLayouts().ToList(); + var zoneNames = new HashSet(); - foreach (var layoutPart in layouts) { - var elements = LoadElements(layoutPart).Flatten(); - var columns = elements.Where(x => x is Column).Cast().Where(x => !String.IsNullOrWhiteSpace(x.ZoneName)).ToList(); + foreach (var layoutPart in layouts) { + var elements = LoadElements(layoutPart).Flatten(); + var columns = elements.Where(x => x is Column).Cast().Where(x => !String.IsNullOrWhiteSpace(x.ZoneName)).ToList(); - foreach (var column in columns) - zoneNames.Add(column.ZoneName); - } + foreach (var column in columns) + zoneNames.Add(column.ZoneName); + } - return zoneNames; + context.Monitor(_signals.When(Signals.LayoutZones)); + return zoneNames; + }); } public dynamic RenderLayout(string data, string displayType = null, IContent content = null) { diff --git a/src/Orchard.Web/Modules/Orchard.Layouts/Signals.cs b/src/Orchard.Web/Modules/Orchard.Layouts/Signals.cs index 6ea01ffa8..b2f23982a 100644 --- a/src/Orchard.Web/Modules/Orchard.Layouts/Signals.cs +++ b/src/Orchard.Web/Modules/Orchard.Layouts/Signals.cs @@ -1,5 +1,6 @@ namespace Orchard.Layouts { public static class Signals { public static readonly object ElementDescriptors = new object(); + public static readonly object LayoutZones = new object(); } } \ No newline at end of file