--HG--
branch : dev
This commit is contained in:
Louis DeJardin
2010-10-11 12:04:17 -07:00
13 changed files with 98 additions and 40 deletions

View File

@@ -18,8 +18,8 @@ namespace Orchard.Tests.DisplayManagement {
protected override void Register(Autofac.ContainerBuilder builder) {
_defaultShapeTable = new ShapeTable {
Descriptors = new Dictionary<string, ShapeDescriptor>(),
Bindings = new Dictionary<string, ShapeBinding>()
Descriptors = new Dictionary<string, ShapeDescriptor>(StringComparer.OrdinalIgnoreCase),
Bindings = new Dictionary<string, ShapeBinding>(StringComparer.OrdinalIgnoreCase)
};
_workContext = new TestWorkContext {
CurrentTheme = new Theme { ThemeName = "Hello" }
@@ -322,5 +322,26 @@ namespace Orchard.Tests.DisplayManagement {
Assert.That(resultNormally.ToString(), Is.EqualTo("alpha"));
Assert.That(resultWithOverride.ToString(), Is.EqualTo("beta"));
}
[Test]
public void ShapeTypeAndBindingNamesAreNotCaseSensitive() {
var displayManager = _container.Resolve<IDisplayManager>();
var shapeFoo = new Shape {
Metadata = new ShapeMetadata {
Type = "foo"
}
};
var descriptorFoo = new ShapeDescriptor {
ShapeType = "Foo",
};
AddBinding(descriptorFoo, "Foo", ctx => new HtmlString("alpha"));
AddShapeDescriptor(descriptorFoo);
var result = displayManager.Execute(CreateDisplayContext(shapeFoo));
Assert.That(result.ToString(), Is.EqualTo("alpha"));
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
@@ -11,7 +10,7 @@ using System.Web.Mvc.Html;
using Orchard.DisplayManagement;
using Orchard.DisplayManagement.Descriptors;
using Orchard.DisplayManagement.Implementation;
using Orchard.Mvc.ViewEngines;
using Orchard.DisplayManagement.Shapes;
using Orchard.Settings;
using Orchard.UI;
using Orchard.UI.Resources;
@@ -37,31 +36,42 @@ namespace Orchard.Core.Shapes {
.OnCreating(creating => creating.Behaviors.Add(new ZoneHoldingBehavior(name => CreateZone(creating))))
.OnCreated(created => {
var layout = created.Shape;
layout.Head = created.New.DocumentZone();
layout.Body = created.New.DocumentZone();
layout.Tail = created.New.DocumentZone();
layout.Content = created.New.Zone();
layout.Head = created.New.DocumentZone(ZoneName: "Head");
layout.Body = created.New.DocumentZone(ZoneName: "Body");
layout.Tail = created.New.DocumentZone(ZoneName: "Tail");
layout.Body.Add(created.New.PlaceChildContent(Source: layout));
layout.Content = created.New.Zone();
layout.Content.ZoneName = "Content";
layout.Content.Add(created.New.PlaceChildContent(Source: layout));
});
// 'Zone' shapes are built on the Zone base class
// They have class="zone zone-{name}"
// and the template can be specialized with "Zone-{Name}" base file name
builder.Describe("Zone")
.OnCreating(creating => creating.BaseType = typeof (Zone))
.OnCreating(creating => creating.BaseType = typeof(Zone))
.OnDisplaying(displaying => {
var name = displaying.Shape.ZoneName.ToLower();
var zone = displaying.Shape;
zone.Classes.Add("zone-" + name);
zone.Classes.Add("zone");
});
var zone = displaying.Shape;
zone.Classes.Add("zone-" + zone.ZoneName.ToLower());
zone.Classes.Add("zone");
zone.Metadata.Alternates.Add("Zone__" + zone.ZoneName);
});
builder.Describe("Menu")
.OnDisplaying(displaying => {
var name = displaying.Shape.MenuName.ToLower();
var menu = displaying.Shape;
menu.Classes.Add("menu-" + name);
menu.Classes.Add("menu-" + menu.MenuName.ToLower());
menu.Classes.Add("menu");
menu.Metadata.Alternates.Add("Menu__" + menu.MenuName);
});
builder.Describe("MenuItem")
.OnDisplaying(displaying => {
var menuItem = displaying.Shape;
var menu = menuItem.Menu;
menuItem.Metadata.Alternates.Add("MenuItem__" + menu.MenuName);
});
// 'List' shapes start with several empty collections
@@ -122,15 +132,15 @@ namespace Orchard.Core.Shapes {
var progress = 1;
var flatPositionComparer = new FlatPositionComparer();
var ordering = unordered.Select(item => {
var position = (item == null || item.GetType().GetProperty("Metadata") == null || item.Metadata.GetType().GetProperty("Position") == null)
? null
: item.Metadata.Position;
return new {item, position};
}).ToList();
var position = (item == null || item.GetType().GetProperty("Metadata") == null || item.Metadata.GetType().GetProperty("Position") == null)
? null
: item.Metadata.Position;
return new { item, position };
}).ToList();
// since this isn't sticking around (hence, the "hack" in the name), throwing (in) a gnome
while (i < ordering.Count()) {
if (flatPositionComparer.Compare(ordering[i].position, ordering[i-1].position) > -1) {
if (flatPositionComparer.Compare(ordering[i].position, ordering[i - 1].position) > -1) {
if (i == progress)
progress = ++i;
else
@@ -138,8 +148,8 @@ namespace Orchard.Core.Shapes {
}
else {
var higherThanItShouldBe = ordering[i];
ordering[i] = ordering[i-1];
ordering[i-1] = higherThanItShouldBe;
ordering[i] = ordering[i - 1];
ordering[i - 1] = higherThanItShouldBe;
if (i > 1)
--i;
}
@@ -157,8 +167,8 @@ namespace Orchard.Core.Shapes {
x = string.IsNullOrWhiteSpace(x) ? "5" : x.TrimStart(':'); // ':' is _sometimes_ used as a partition identifier
y = string.IsNullOrWhiteSpace(y) ? "5" : y.TrimStart(':');
var xParts = x.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
var yParts = y.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
var xParts = x.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
var yParts = y.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
for (var i = 0; i < xParts.Count(); i++) {
if (yParts.Length < i - 1) // x is further defined meaning it comes after y (e.g. x == 1.2.3 and y == 1.2)
return 1;
@@ -247,7 +257,7 @@ namespace Orchard.Core.Shapes {
private static void WriteResources(HtmlHelper html, ISite site, IResourceManager rm, string resourceType, ResourceLocation? includeLocation, ResourceLocation? excludeLocation) {
bool debugMode;
switch(site.ResourceDebugMode) {
switch (site.ResourceDebugMode) {
case ResourceDebugMode.Enabled:
debugMode = true;
break;

View File

@@ -143,6 +143,10 @@
<None Include="Themes\TheThemeMachine\Views\Recent.cshtml">
<SubType>Designer</SubType>
</None>
<None Include="Themes\Classic\Views\Menu-Main.cshtml">
<SubType>Designer</SubType>
</None>
<None Include="Themes\Classic\Views\Zone-Content.cshtml" />
<None Include="Themes\TheThemeMachine\Views\Layout-Blog.cshtml" />
<None Include="Themes\TheThemeMachine\Views\Featured.cshtml">
<SubType>Designer</SubType>

View File

@@ -0,0 +1,10 @@
@{
// Model is Model.Menu from the layout (Layout.Menu)
var tag = Tag(Model, "ul");
}
<nav>
@tag.StartElement
@* see MenuItem shape template *@
[@DisplayChildren(Model)]
@tag.EndElement
</nav>

View File

@@ -0,0 +1,7 @@
@{
Model.Attributes.Add("style", "background:salmon;");
var tag = Tag(Model, "div");
}
@tag.StartElement
@DisplayChildren(Model)
@tag.EndElement

View File

@@ -32,7 +32,7 @@ namespace Orchard.DisplayManagement.Descriptors {
var alterations = builderFactory.BuildAlterations()
.Where(alteration => IsModuleOrRequestedTheme(alteration, themeName));
var descriptors = alterations.GroupBy(alteration => alteration.ShapeType)
var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase)
.Select(group => group.Aggregate(
new ShapeDescriptor { ShapeType = group.Key },
(descriptor, alteration) => {
@@ -41,8 +41,8 @@ namespace Orchard.DisplayManagement.Descriptors {
}));
return new ShapeTable {
Descriptors = descriptors.ToDictionary(sd => sd.ShapeType),
Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value),
Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase),
Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase),
};
});
}

View File

@@ -55,7 +55,7 @@ namespace Orchard.DisplayManagement.Descriptors {
return target(displayContext);
}
};
descriptor.Bindings[_shapeType] = binding;
descriptor.Bindings[_bindingName] = binding;
});
}

View File

@@ -7,19 +7,19 @@ using System.Web.Mvc;
namespace Orchard.DisplayManagement.Shapes {
public interface ITagBuilderFactory : IDependency {
TagBuilder Create(dynamic shape, string tagName);
OrchardTagBuilder Create(dynamic shape, string tagName);
}
public class TagBuilder : System.Web.Mvc.TagBuilder {
public TagBuilder(string tagName) : base(tagName) { }
public class OrchardTagBuilder : TagBuilder {
public OrchardTagBuilder(string tagName) : base(tagName) { }
public IHtmlString StartElement { get { return new HtmlString(ToString(TagRenderMode.StartTag)); } }
public IHtmlString EndElement { get { return new HtmlString(ToString(TagRenderMode.EndTag)); } }
}
public class TagBuilderFactory : ITagBuilderFactory {
public TagBuilder Create(dynamic shape, string tagName) {
var tagBuilder = new TagBuilder(tagName);
public OrchardTagBuilder Create(dynamic shape, string tagName) {
var tagBuilder = new OrchardTagBuilder(tagName);
tagBuilder.MergeAttributes(shape.Attributes, false);
foreach (var cssClass in shape.Classes ?? Enumerable.Empty<string>())
tagBuilder.AddCssClass(cssClass);

View File

@@ -1,5 +1,6 @@
using System;
using System.Web;
using Orchard.DisplayManagement.Shapes;
using Orchard.Localization;
using Orchard.UI.Resources;
@@ -22,5 +23,8 @@ namespace Orchard.Mvc {
void SetMeta(MetaEntry meta);
void AppendMeta(string name, string content, string contentSeparator);
void AppendMeta(MetaEntry meta, string contentSeparator);
bool HasText(object thing);
OrchardTagBuilder Tag(dynamic shape, string tagName);
}
}

View File

@@ -90,7 +90,7 @@ namespace Orchard.Mvc.ViewEngines.Razor {
return !string.IsNullOrWhiteSpace(thing as string);
}
public TagBuilder Tag(dynamic shape, string tagName) {
public OrchardTagBuilder Tag(dynamic shape, string tagName) {
return Html.Resolve<ITagBuilderFactory>().Create(shape, tagName);
}

View File

@@ -91,7 +91,7 @@ namespace Orchard.Mvc {
return !string.IsNullOrWhiteSpace(thing as string);
}
public TagBuilder Tag(dynamic shape, string tagName) {
public OrchardTagBuilder Tag(dynamic shape, string tagName) {
return Html.Resolve<ITagBuilderFactory>().Create(shape, tagName);
}

View File

@@ -92,7 +92,7 @@ namespace Orchard.Mvc {
return !string.IsNullOrWhiteSpace(thing as string);
}
public TagBuilder Tag(dynamic shape, string tagName) {
public OrchardTagBuilder Tag(dynamic shape, string tagName) {
return Html.Resolve<ITagBuilderFactory>().Create(shape, tagName);
}

View File

@@ -39,7 +39,9 @@ namespace Orchard.UI.Navigation {
.Text(menuItem.Text)
.Href(menuItem.Href)
.RouteValues(menuItem.RouteValues)
.Item(menuItem);
.Item(menuItem)
.Menu(shape)
.Parent(parentShape);
if (menuItem.Items != null && menuItem.Items.Any()) {
PopulateMenu(shape, menuItemShape, menuItem.Items);