Adding Frames collection to shape descriptor and metadata

--HG--
branch : theming
This commit is contained in:
Louis DeJardin
2010-09-06 20:51:24 -07:00
parent 77c48fb42a
commit ef7abae721
18 changed files with 94 additions and 49 deletions

View File

@@ -1 +1 @@
3bc513c8049ad19173130a0e0e6a5486ee8247d2 Clay
cf89a75f4158f045c90fb7e5ee1a766623abaa71 Clay

View File

@@ -7,6 +7,7 @@ using NUnit.Framework;
using Orchard.DisplayManagement;
using Orchard.DisplayManagement.Descriptors;
using Orchard.DisplayManagement.Implementation;
using Orchard.DisplayManagement.Shapes;
using Orchard.Environment;
using Orchard.Mvc;
using Orchard.UI.Zones;
@@ -33,7 +34,7 @@ namespace Orchard.Tests.UI {
[Test]
public void WorkContextPageIsLayoutShape() {
var page = _workContext.Page;
IShapeMetadata pageMetadata = page.Metadata;
ShapeMetadata pageMetadata = page.Metadata;
Assert.That(pageMetadata.Type, Is.EqualTo("Layout"));
Assert.That(page.Metadata.Type, Is.EqualTo("Layout"));
}

View File

@@ -1,17 +1,20 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<BaseViewModel>" %>
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage" %>
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
<%@ Import Namespace="Orchard.Mvc.Html"
%><!DOCTYPE html>
<html lang="en" class="static">
<head>
<title><%: Html.Title() %></title>
<link rel="shortcut icon" type="image/x-icon" href="<%=ResolveUrl("../Content/orchard.ico") %>" /><%
<link rel="shortcut icon" type="image/x-icon" href="<%=ResolveUrl("../Content/orchard.ico") %>" />
<%--<%
//todo: (heskew) have resource modules that can be leaned on (like a jQuery module that knows about various CDNs and jQuery's version and min naming schemes)
//todo: (heskew) this is an interim solution to inlude jQuery in every page and still allow that to be overriden in some theme by it containing a headScripts partial
Html.Zone("head", ":metas :styles :scripts"); %>
Html.Zone("head", ":metas :styles :scripts"); %>--%>
<%:Display(Model.Head) %>
<script type="text/javascript">document.documentElement.className="dyn";</script>
</head>
<body class="<%: Html.ClassForPage() %>"><%
Html.ZoneBody("body"); %>
<body class="<%: Html.ClassForPage() %>">
<% Model.Body.Add(Model.Metadata.ChildContent, "5"); %>
<%: Display(Model.Body) %>
</body>
</html>

View File

@@ -1,5 +1,4 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %>
<%-- //todo: (heskew) this should really be using the IResourceManager if it's to be a theme especially for the jquery dep (w/out needing to copy into this theme...)
var jquery = ResolveUrl("~/Modules/Orchard.Themes/Scripts/jquery-1.4.2.js");
Model.Zones.AddAction("head:scripts", html =>
@@ -16,11 +15,14 @@
var ie6Css = ResolveUrl("../Styles/ie6.css");
Model.Zones.AddAction("head:styles", html =>
html.ViewContext.Writer.Write(@"<!--[if lte IE 6]><link rel=""stylesheet"" type=""text/css"" media=""screen, projection"" href=""" + ie6Css + @"""/><![endif]-->"));
--%>
--%>
<div id="header">
<div id="branding"><h1>Welcome to Orchard</h1></div>
<div id="branding">
<h1>
Welcome to Orchard</h1>
</div>
</div>
<div id="main">
<% Model.Content.Add(Model.Metadata.ChildContent, "5"); %>
<%: Display(Model.Content) %>
</div>

View File

@@ -1,4 +1,4 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %>
<div class="zone zone-<%:Model.ZoneName %>">
<%foreach (var item in Model.Items) {%><%:Display(item)%><%}%>
<%foreach (var item in Model) {%><%:Display(item)%><%}%>
</div>

View File

@@ -1,10 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.DisplayManagement.Implementation;
namespace Orchard.DisplayManagement.Descriptors {
public class ShapeDescriptor {
public ShapeDescriptor() {
Creating = Enumerable.Empty<Action<ShapeCreatingContext>>();
Created = Enumerable.Empty<Action<ShapeCreatedContext>>();
FrameTypes = new List<string>();
}
public string ShapeType { get; set; }
/// <summary>
@@ -16,7 +23,8 @@ namespace Orchard.DisplayManagement.Descriptors {
public Func<DisplayContext, IHtmlString> Binding { get; set; }
public IEnumerable<Action<ShapeCreatingContext>> Creating {get;set;}
public IEnumerable<Action<ShapeCreatedContext>> Created {get;set;}
public IList<string> FrameTypes { get; set; }
}
}
}

View File

@@ -1,10 +1,12 @@
namespace Orchard.DisplayManagement {
using Orchard.DisplayManagement.Shapes;
namespace Orchard.DisplayManagement {
/// <summary>
/// Interface present on dynamic shapes.
/// May be used to access attributes in a strongly typed fashion.
/// Note: Anything on this interface is a reserved word for the purpose of shape properties
/// </summary>
public interface IShape {
IShapeMetadata Metadata { get; set; }
ShapeMetadata Metadata { get; set; }
}
}

View File

@@ -1,7 +0,0 @@
namespace Orchard.DisplayManagement {
public interface IShapeMetadata {
string Type { get; set; }
string Position { get; set; }
bool WasExecuted { get; set; }
}
}

View File

@@ -51,10 +51,20 @@ namespace Orchard.DisplayManagement.Implementation {
ShapeDescriptor shapeDescriptor;
if (shapeTable.Descriptors.TryGetValue(shapeMetadata.Type, out shapeDescriptor)) {
return Process(shapeDescriptor, shape, context);
shape.Metadata.ChildContent = Process(shapeDescriptor, shape, context);
}
//postproc / content html alteration/wrapping/etc
throw new OrchardException(T("Shape type {0} not found", shapeMetadata.Type));
else {
throw new OrchardException(T("Shape type {0} not found", shapeMetadata.Type));
}
foreach (var frameType in shape.Metadata.FrameTypes) {
ShapeDescriptor frameDescriptor;
if (shapeTable.Descriptors.TryGetValue(frameType, out frameDescriptor)) {
shape.Metadata.ChildContent = Process(frameDescriptor, shape, context);
}
}
return shape.Metadata.ChildContent;
}
private IHtmlString CoerceHtmlString(object value) {
@@ -68,7 +78,7 @@ namespace Orchard.DisplayManagement.Implementation {
return new HtmlString(HttpUtility.HtmlEncode(value));
}
private IHtmlString Process(ShapeDescriptor shapeDescriptor, IShape shape, DisplayContext context) {
private IHtmlString Process(ShapeDescriptor shapeDescriptor, IShape shape, DisplayContext context) {
return CoerceHtmlString(shapeDescriptor.Binding(context));
}
@@ -83,9 +93,10 @@ namespace Orchard.DisplayManagement.Implementation {
public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion) {
// adjust the normal csharp convert binder to allow failure to become null.
// this causes the same net effect as the "as" keyword, but may be applied to dynamic objects
return _innerBinder.FallbackConvert(
var result = _innerBinder.FallbackConvert(
target,
errorSuggestion ?? new DynamicMetaObject(Expression.Default(_innerBinder.ReturnType), GetTypeRestriction(target)));
return result;
}
static BindingRestrictions GetTypeRestriction(DynamicMetaObject obj) {

View File

@@ -85,7 +85,7 @@ namespace Orchard.DisplayManagement.Implementation {
foreach (var ev in _events) {
ev.Value.Creating(creatingContext);
}
if (shapeDescriptor != null && shapeDescriptor.Creating != null) {
if (shapeDescriptor != null) {
foreach (var ev in shapeDescriptor.Creating) {
ev(creatingContext);
}
@@ -97,13 +97,17 @@ namespace Orchard.DisplayManagement.Implementation {
ShapeType = creatingContext.ShapeType,
Shape = ClayActivator.CreateInstance(creatingContext.BaseType, creatingContext.Behaviors)
};
createdContext.Shape.Metadata = new ShapeMetadata { Type = shapeType };
var shapeMetadata = new ShapeMetadata { Type = shapeType };
createdContext.Shape.Metadata = shapeMetadata;
if (shapeDescriptor != null)
shapeMetadata.FrameTypes = shapeMetadata.FrameTypes.Concat(shapeDescriptor.FrameTypes).ToList();
// "created" events provides default values and new object initialization
foreach (var ev in _events) {
ev.Value.Created(createdContext);
}
if (shapeDescriptor != null && shapeDescriptor.Created != null) {
if (shapeDescriptor != null) {
foreach (var ev in shapeDescriptor.Created) {
ev(createdContext);
}

View File

@@ -1,5 +1,5 @@
namespace Orchard.DisplayManagement.Shapes {
public class Shape : IShape {
public virtual IShapeMetadata Metadata { get; set; }
public virtual ShapeMetadata Metadata { get; set; }
}
}

View File

@@ -1,7 +1,18 @@
namespace Orchard.DisplayManagement.Shapes {
public class ShapeMetadata : IShapeMetadata {
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Orchard.DisplayManagement.Shapes {
public class ShapeMetadata {
public ShapeMetadata() {
FrameTypes = new List<string>();
}
public string Type { get; set; }
public string Position { get; set; }
public IList<string> FrameTypes { get; set; }
public bool WasExecuted { get; set; }
public IHtmlString ChildContent { get; set; }
}
}

View File

@@ -27,23 +27,24 @@ namespace Orchard.Mvc.ViewEngines.ThemeAwareness {
}
public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) {
var findBody = _themeAwareViewEngine.FindPartialView(controllerContext, viewName, useCache, true);
var viewResult = _themeAwareViewEngine.FindPartialView(controllerContext, viewName, useCache, true);
if (findBody.View == null) {
return findBody;
if (viewResult.View == null) {
return viewResult;
}
var layoutView = new LayoutView((viewContext, writer, viewDataContainer) => {
var buffer = new StringWriter();
findBody.View.Render(viewContext, buffer);
_workContext.Page.Zones.Content.Add(new HtmlString(buffer.ToString()), "5");
viewResult.View.Render(viewContext, buffer);
_workContext.Page.Metadata.ChildContent = new HtmlString(buffer.ToString());
var display = _displayHelperFactory.CreateHelper(viewContext, viewDataContainer);
IHtmlString result = display(_workContext.Page);
writer.Write(result.ToHtmlString());
}, (context, view) => findBody.ViewEngine.ReleaseView(context, findBody.View));
}, (context, view) => viewResult.ViewEngine.ReleaseView(context, viewResult.View));
return new ViewEngineResult(layoutView, this);
}

View File

@@ -20,7 +20,7 @@ namespace Orchard.Mvc {
public override void InitHelpers() {
base.InitHelpers();
var workContext = ViewContext.GetWorkContext();
workContext.Resolve<IComponentContext>().InjectUnsetProperties(this);
@@ -36,4 +36,7 @@ namespace Orchard.Mvc {
return Authorizer.Authorize(permission);
}
}
public class ViewPage : ViewPage<dynamic> {
}
}

View File

@@ -1,3 +1,4 @@
using System.Web;
using System.Web.Mvc;
using Autofac;
using Orchard.DisplayManagement;

View File

@@ -391,7 +391,6 @@
<Compile Include="DisplayManagement\IShapeHelperFactory.cs" />
<Compile Include="DisplayManagement\IDisplayHelperFactory.cs" />
<Compile Include="DisplayManagement\IShape.cs" />
<Compile Include="DisplayManagement\IShapeMetadata.cs" />
<Compile Include="DisplayManagement\Shapes\Shape.cs" />
<Compile Include="DisplayManagement\Shapes\ShapeMetadata.cs" />
<Compile Include="DisplayManagement\Descriptors\DefaultShapeTableManager.cs" />

View File

@@ -25,7 +25,7 @@ namespace Orchard.UI {
}
}
public interface IZone {
public interface IZone : IEnumerable {
string ZoneName { get; set; }
IZone Add(object item);
IZone Add(object item, string position);
@@ -63,5 +63,9 @@ namespace Orchard.UI {
return _items;
}
}
public virtual IEnumerator GetEnumerator() {
return _items.GetEnumerator();
}
}
}

View File

@@ -23,14 +23,16 @@ namespace Orchard.UI.Zones {
public class CoreShapes : IShapeDescriptorBindingStrategy {
public void Discover(ShapeTableBuilder builder) {
var feature = new FeatureDescriptor {
Name = "Orchard.Framework",
Extension = new ExtensionDescriptor {
Name = "Orchard.Framework",
Extension = new ExtensionDescriptor {
Name = "Orchard.Framework",
ExtensionType = "Module",
}
};
ExtensionType = "Module",
}
};
builder.Describe.Named("Layout").From(feature)
.OnCreating(context => context.Behaviors.Add(new ZoneHoldingBehavior(context.ShapeFactory)));
.OnCreating(context => context.Behaviors.Add(new ZoneHoldingBehavior(context.ShapeFactory)))
.Configure(d => d.FrameTypes.Add("Document"));
builder.Describe.Named("Zone").From(feature)
.OnCreating(context => context.BaseType = typeof(Zone));