Merge branch 'feature/tabs' into dev

This commit is contained in:
Sipke Schoorstra
2015-07-24 11:52:39 +01:00
11 changed files with 139 additions and 14 deletions

View File

@@ -1,4 +1,9 @@
<div class="edit-item">
@using Orchard.Core.Shapes
@{
var tabs = (IEnumerable<string>)CoreShapes.HarvestAndSortTabs(Model.Content);
Display.LocalNavigation(Tabs: tabs);
}
<div class="edit-item">
<div class="edit-item-primary">
@if (Model.Content != null) {
<div class="edit-item-content">

View File

@@ -294,6 +294,7 @@
<Content Include="Common\Views\Parts.Common.Metadata.cshtml" />
<Content Include="Common\Views\CommonMetadataLastModified.cshtml" />
<Content Include="Containers\Module.txt" />
<Content Include="Shapes\Scripts\admin-localnavigation.js" />
<Content Include="Contents\Styles\images\menu.content.png" />
<Content Include="Contents\Styles\menu.content-admin.css" />
<Content Include="Contents\Views\Admin\Create.cshtml" />
@@ -340,6 +341,7 @@
<Content Include="Shapes\Styles\Images\toolBarBackground.gif" />
<Content Include="Shapes\Styles\Images\toolBarHoverButtonBackground.gif" />
<Content Include="Shapes\Styles\jquery.switchable.css" />
<Content Include="Shapes\Styles\site.css" />
<Content Include="Shapes\Styles\special.css" />
<Content Include="Shapes\Views\HeadPreload.cshtml" />
<Content Include="Shapes\Views\Message.cshtml" />
@@ -570,6 +572,12 @@
<Content Include="Reports\Views\Admin\Display.cshtml" />
<Content Include="Reports\Views\Admin\Index.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Shapes\Views\LocalNavigation.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Shapes\Views\AdminTabs.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@@ -282,8 +282,26 @@ namespace Orchard.Core.Shapes {
[Shape]
public void ContentZone(dynamic Display, dynamic Shape, TextWriter Output) {
foreach (var item in Order(Shape))
Output.Write(Display(item));
var unordered = ((IEnumerable<dynamic>)Shape).ToArray();
var tabbed = unordered.GroupBy(x => (string)x.Metadata.Tab);
if (tabbed.Count() > 1) {
foreach (var tab in tabbed) {
var tabName = String.IsNullOrWhiteSpace(tab.Key) ? "Content" : tab.Key;
var tabBuilder = new TagBuilder("div");
tabBuilder.Attributes["id"] = "tab-" + tabName.HtmlClassify();
tabBuilder.Attributes["data-tab"] = tabName;
Output.Write(tabBuilder.ToString(TagRenderMode.StartTag));
foreach (var item in Order(tab))
Output.Write(Display(item));
Output.Write(tabBuilder.ToString(TagRenderMode.EndTag));
}
}
else {
foreach (var item in Order(unordered))
Output.Write(Display(item));
}
}
[Shape]
@@ -327,6 +345,30 @@ namespace Orchard.Core.Shapes {
return ordering.Select(ordered => ordered.item).ToList();
}
public static IEnumerable<string> HarvestAndSortTabs(IEnumerable<dynamic> shapes) {
var orderedShapes = Order(shapes).ToArray();
var tabs = new List<string>();
foreach (var shape in orderedShapes) {
var tab = (string)shape.Metadata.Tab;
if (String.IsNullOrEmpty(tab))
continue;
if(!tabs.Contains(tab))
tabs.Add(tab);
}
// If we have any tabs, make sure we have at least the Content tab and that it is the first one,
// since that's where we will put anything else not part of a tab.
if (tabs.Any()) {
tabs.Remove("Content");
tabs.Insert(0, "Content");
}
return tabs;
}
[Shape]
public void HeadScripts(dynamic Display, TextWriter Output) {
WriteResources(Display, Output, "script", ResourceLocation.Head, null);

View File

@@ -5,7 +5,7 @@ namespace Orchard.Core.Shapes {
public void BuildManifests(ResourceManifestBuilder builder) {
var manifest = builder.Add();
manifest.DefineScript("ShapesBase").SetUrl("base.js").SetDependencies("jQuery");
manifest.DefineStyle("Shapes").SetUrl("site.css"); // todo: missing
manifest.DefineStyle("Shapes").SetUrl("site.css");
manifest.DefineStyle("ShapesSpecial").SetUrl("special.css");
manifest.DefineScript("Html5Shiv").SetUrl("html5.js");
@@ -14,6 +14,8 @@ namespace Orchard.Core.Shapes {
.SetDependencies("jQuery")
.SetDependencies("ShapesBase");
manifest.DefineStyle("Switchable").SetUrl("jquery.switchable.css");
manifest.DefineScript("LocalNavigation").SetUrl("admin-localnavigation.js").SetDependencies("jQuery");
}
}
}

View File

@@ -0,0 +1,33 @@
(function($) {
$(function () {
var allViews = [];
$("#local-navigation").on("click", "a", function(e) {
e.preventDefault();
for (i = 0; i < allViews.length; i++) {
allViews[i].hide();
}
$("#local-navigation li.selected").removeClass("selected");
var tab = $(this);
var selector = tab.attr("href");
var views = $(selector);
tab.closest("li").addClass("selected");
views.show();
});
$("#local-navigation a").each(function (e) {
var tab = $(this);
var selector = tab.attr("href");
var views = $(selector);
views.hide();
allViews.push(views);
});
$("#local-navigation a:first").click();
});
})(jQuery);

View File

@@ -0,0 +1 @@
/*Placeholder for Shapes style resource.*/

View File

@@ -0,0 +1,24 @@
@using Orchard.Localization
@using Orchard.Utility.Extensions
@{
var tabs = ((IEnumerable<dynamic>)Model.Tabs).ToArray();
if (tabs.Any()) {
Script.Require("LocalNavigation");
}
}
@if (tabs.Any()) {
var tabIndex = 0;
<div id="local-navigation">
<ul class="localmenu group">
@foreach (var tab in tabs) {
var tabText = tab is string ? (string)tab : (string)(tab.Text is LocalizedString ? tab.Text.ToString() : tab.Text);
var defaultTabId = string.Format("tab-{0}", tabText.HtmlClassify());
var tabId = tab is string ? defaultTabId : (string)(tab.TabName ?? defaultTabId);
var tabCssClass = tabIndex == 0 ? "first selected" : tabIndex <= tabs.Count() - 1 ? "last" : "middle";
<li class="@tabCssClass"><a href="#@tabId">@tabText</a></li>
tabIndex++;
}
</ul>
</div>
}

View File

@@ -0,0 +1,3 @@
@{
Layout.LocalNavigation.Add(New.AdminTabs(Tabs: Model.Tabs));
}

View File

@@ -67,6 +67,10 @@
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Xml.Linq" />

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Orchard.ContentManagement.Handlers;
using Orchard.DisplayManagement.Shapes;
@@ -27,16 +28,16 @@ namespace Orchard.ContentManagement.Drivers {
private void ApplyImplementation(BuildShapeContext context, string displayType) {
var placement = context.FindPlacement(_shapeType, _differentiator, _defaultLocation);
if (string.IsNullOrEmpty(placement.Location) || placement.Location == "-")
if (String.IsNullOrEmpty(placement.Location) || placement.Location == "-")
return;
// parse group placement
// Parse group placement.
var group = placement.GetGroup();
if (!String.IsNullOrEmpty(group)) {
_groupId = group;
}
if (!string.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase))
if (!String.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase))
return;
dynamic parentShape = context.Shape;
@@ -44,17 +45,17 @@ namespace Orchard.ContentManagement.Drivers {
var newShape = _shapeBuilder(context);
// ignore it if the driver returned a null shape
if(newShape == null) {
// Ignore it if the driver returned a null shape.
if (newShape == null) {
return;
}
// add a ContentPart property to the final shape
// Add a ContentPart property to the final shape.
if (ContentPart != null && newShape.ContentPart == null) {
newShape.ContentPart = ContentPart;
}
// add a ContentField property to the final shape
// Add a ContentField property to the final shape.
if (ContentField != null && newShape.ContentField == null) {
newShape.ContentField = ContentField;
}
@@ -63,8 +64,9 @@ namespace Orchard.ContentManagement.Drivers {
newShapeMetadata.Prefix = _prefix;
newShapeMetadata.DisplayType = displayType;
newShapeMetadata.PlacementSource = placement.Source;
newShapeMetadata.Tab = placement.GetTab();
// if a specific shape is provided, remove all previous alternates and wrappers
// If a specific shape is provided, remove all previous alternates and wrappers.
if (!String.IsNullOrEmpty(placement.ShapeType)) {
newShapeMetadata.Type = placement.ShapeType;
newShapeMetadata.Alternates.Clear();
@@ -79,7 +81,7 @@ namespace Orchard.ContentManagement.Drivers {
newShapeMetadata.Wrappers.Add(wrapper);
}
// the zone name is in reference of Layout, e.g. /AsideSecond
// Check if the zone name is in reference of Layout, e.g. /AsideSecond.
if (placement.IsLayoutZone()) {
parentShape = context.Layout;
}
@@ -106,7 +108,7 @@ namespace Orchard.ContentManagement.Drivers {
}
public ContentShapeResult OnGroup(string groupId) {
_groupId=groupId;
_groupId = groupId;
return this;
}

View File

@@ -17,6 +17,7 @@ namespace Orchard.DisplayManagement.Shapes {
public string Type { get; set; }
public string DisplayType { get; set; }
public string Position { get; set; }
public string Tab { get; set; }
public string PlacementSource { get; set; }
public string Prefix { get; set; }
public IList<string> Wrappers { get; set; }