diff --git a/src/Orchard/Mvc/Html/LayoutExtensions.cs b/src/Orchard/Mvc/Html/LayoutExtensions.cs
index 1016bd857..937d960d8 100644
--- a/src/Orchard/Mvc/Html/LayoutExtensions.cs
+++ b/src/Orchard/Mvc/Html/LayoutExtensions.cs
@@ -27,7 +27,7 @@ namespace Orchard.Mvc.Html {
}
public static void Zone(this HtmlHelper html, string zoneName, string partitions) where TModel : BaseViewModel {
- //is IoC necessary for this to work properly?
+ //TODO: is IoC necessary for this to work properly?
var manager = new ZoneManager();
manager.Render(html, html.ViewData.Model.Zones, zoneName, partitions);
}
@@ -37,6 +37,7 @@ namespace Orchard.Mvc.Html {
}
public static void Zone(this HtmlHelper html, string zoneName, Action action) where TModel : BaseViewModel {
+ //TODO: again, IoC could move this AddAction (or similar) method out of the data-bearing object
html.ViewData.Model.Zones.AddAction(zoneName, x => action());
Zone(html, zoneName, string.Empty);
}
diff --git a/src/Orchard/UI/Zones/ZoneCollection.cs b/src/Orchard/UI/Zones/ZoneCollection.cs
index a2b576309..644c9248b 100644
--- a/src/Orchard/UI/Zones/ZoneCollection.cs
+++ b/src/Orchard/UI/Zones/ZoneCollection.cs
@@ -12,6 +12,32 @@ namespace Orchard.UI.Zones {
}
public void AddAction(string location, Action action) {
+ AddZoneItem(location, new DelegateZoneItem { Action = action });
+ }
+
+ private void AddZoneItem(string location, ZoneItem item) {
+ string zoneName;
+ var position = string.Empty;
+
+ var colonIndex = location.IndexOf(':');
+ if (colonIndex == -1) {
+ zoneName = location.Trim();
+ }
+ else {
+ zoneName = location.Substring(0, colonIndex).Trim();
+ position = location.Substring(colonIndex + 1).Trim();
+ }
+
+ item.Position = position;
+ ZoneEntry entry;
+ if (TryGetValue(zoneName, out entry)) {
+ entry.Items.Add(item);
+ }
+ else {
+ entry = new ZoneEntry { ZoneName = zoneName, Items = new List() };
+ Add(zoneName, entry);
+ entry.Items.Add(item);
+ }
}
}
diff --git a/src/Orchard/UI/Zones/ZoneManager.cs b/src/Orchard/UI/Zones/ZoneManager.cs
index 0a31b4714..42528ceb7 100644
--- a/src/Orchard/UI/Zones/ZoneManager.cs
+++ b/src/Orchard/UI/Zones/ZoneManager.cs
@@ -12,14 +12,49 @@ namespace Orchard.UI.Zones {
if (!zones.TryGetValue(zoneName, out zone))
return;
- //TODO: partitions
- foreach (var item in zone.Items) {
- if (item.WasExecuted)
- continue;
+ var partitionItems = LocatePartitionItems(partitions, zone);
+
+ foreach (var partitionItem in partitionItems) {
+ foreach (var item in zone.Items) {
+ if (item.WasExecuted)
+ continue;
+
+ item.WasExecuted = true;
+ item.Execute(html);
+ }
- item.WasExecuted = true;
- item.Execute(html);
}
}
+
+ private IEnumerable LocatePartitionItems(string partitions, ZoneEntry zone) {
+
+ var partitionCodes = (":before " + partitions + " :* :after").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
+
+ var itemsRemaining = zone.Items.Where(x => x.WasExecuted == false);
+
+ PartitionItem catchAllItem = null;
+
+ var results = new List();
+ foreach (var code in partitionCodes) {
+ if (code == ":*") {
+ catchAllItem=new PartitionItem();
+ results.Add(catchAllItem);
+ }
+ else {
+ var value = code;
+ var items = itemsRemaining.Where(x => (":" + x.Position).StartsWith(value));
+ results.Add(new PartitionItem { ZoneItems = items.ToArray() });
+ itemsRemaining = itemsRemaining.Except(items).ToArray();
+ }
+ }
+ if (catchAllItem != null) {
+ catchAllItem.ZoneItems = itemsRemaining;
+ }
+ return results;
+ }
+
+ class PartitionItem {
+ public IEnumerable ZoneItems { get; set; }
+ }
}
}