mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Merge branch 'feature/tabs' into dev
This commit is contained in:
@@ -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">
|
<div class="edit-item-primary">
|
||||||
@if (Model.Content != null) {
|
@if (Model.Content != null) {
|
||||||
<div class="edit-item-content">
|
<div class="edit-item-content">
|
||||||
|
|||||||
@@ -294,6 +294,7 @@
|
|||||||
<Content Include="Common\Views\Parts.Common.Metadata.cshtml" />
|
<Content Include="Common\Views\Parts.Common.Metadata.cshtml" />
|
||||||
<Content Include="Common\Views\CommonMetadataLastModified.cshtml" />
|
<Content Include="Common\Views\CommonMetadataLastModified.cshtml" />
|
||||||
<Content Include="Containers\Module.txt" />
|
<Content Include="Containers\Module.txt" />
|
||||||
|
<Content Include="Shapes\Scripts\admin-localnavigation.js" />
|
||||||
<Content Include="Contents\Styles\images\menu.content.png" />
|
<Content Include="Contents\Styles\images\menu.content.png" />
|
||||||
<Content Include="Contents\Styles\menu.content-admin.css" />
|
<Content Include="Contents\Styles\menu.content-admin.css" />
|
||||||
<Content Include="Contents\Views\Admin\Create.cshtml" />
|
<Content Include="Contents\Views\Admin\Create.cshtml" />
|
||||||
@@ -340,6 +341,7 @@
|
|||||||
<Content Include="Shapes\Styles\Images\toolBarBackground.gif" />
|
<Content Include="Shapes\Styles\Images\toolBarBackground.gif" />
|
||||||
<Content Include="Shapes\Styles\Images\toolBarHoverButtonBackground.gif" />
|
<Content Include="Shapes\Styles\Images\toolBarHoverButtonBackground.gif" />
|
||||||
<Content Include="Shapes\Styles\jquery.switchable.css" />
|
<Content Include="Shapes\Styles\jquery.switchable.css" />
|
||||||
|
<Content Include="Shapes\Styles\site.css" />
|
||||||
<Content Include="Shapes\Styles\special.css" />
|
<Content Include="Shapes\Styles\special.css" />
|
||||||
<Content Include="Shapes\Views\HeadPreload.cshtml" />
|
<Content Include="Shapes\Views\HeadPreload.cshtml" />
|
||||||
<Content Include="Shapes\Views\Message.cshtml" />
|
<Content Include="Shapes\Views\Message.cshtml" />
|
||||||
@@ -570,6 +572,12 @@
|
|||||||
<Content Include="Reports\Views\Admin\Display.cshtml" />
|
<Content Include="Reports\Views\Admin\Display.cshtml" />
|
||||||
<Content Include="Reports\Views\Admin\Index.cshtml" />
|
<Content Include="Reports\Views\Admin\Index.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Shapes\Views\LocalNavigation.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Shapes\Views\AdminTabs.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
|||||||
@@ -282,8 +282,26 @@ namespace Orchard.Core.Shapes {
|
|||||||
|
|
||||||
[Shape]
|
[Shape]
|
||||||
public void ContentZone(dynamic Display, dynamic Shape, TextWriter Output) {
|
public void ContentZone(dynamic Display, dynamic Shape, TextWriter Output) {
|
||||||
foreach (var item in Order(Shape))
|
var unordered = ((IEnumerable<dynamic>)Shape).ToArray();
|
||||||
Output.Write(Display(item));
|
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]
|
[Shape]
|
||||||
@@ -327,6 +345,30 @@ namespace Orchard.Core.Shapes {
|
|||||||
return ordering.Select(ordered => ordered.item).ToList();
|
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]
|
[Shape]
|
||||||
public void HeadScripts(dynamic Display, TextWriter Output) {
|
public void HeadScripts(dynamic Display, TextWriter Output) {
|
||||||
WriteResources(Display, Output, "script", ResourceLocation.Head, null);
|
WriteResources(Display, Output, "script", ResourceLocation.Head, null);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace Orchard.Core.Shapes {
|
|||||||
public void BuildManifests(ResourceManifestBuilder builder) {
|
public void BuildManifests(ResourceManifestBuilder builder) {
|
||||||
var manifest = builder.Add();
|
var manifest = builder.Add();
|
||||||
manifest.DefineScript("ShapesBase").SetUrl("base.js").SetDependencies("jQuery");
|
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.DefineStyle("ShapesSpecial").SetUrl("special.css");
|
||||||
|
|
||||||
manifest.DefineScript("Html5Shiv").SetUrl("html5.js");
|
manifest.DefineScript("Html5Shiv").SetUrl("html5.js");
|
||||||
@@ -14,6 +14,8 @@ namespace Orchard.Core.Shapes {
|
|||||||
.SetDependencies("jQuery")
|
.SetDependencies("jQuery")
|
||||||
.SetDependencies("ShapesBase");
|
.SetDependencies("ShapesBase");
|
||||||
manifest.DefineStyle("Switchable").SetUrl("jquery.switchable.css");
|
manifest.DefineStyle("Switchable").SetUrl("jquery.switchable.css");
|
||||||
|
|
||||||
|
manifest.DefineScript("LocalNavigation").SetUrl("admin-localnavigation.js").SetDependencies("jQuery");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
src/Orchard.Web/Core/Shapes/Scripts/admin-localnavigation.js
Normal file
33
src/Orchard.Web/Core/Shapes/Scripts/admin-localnavigation.js
Normal 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);
|
||||||
1
src/Orchard.Web/Core/Shapes/Styles/site.css
Normal file
1
src/Orchard.Web/Core/Shapes/Styles/site.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/*Placeholder for Shapes style resource.*/
|
||||||
24
src/Orchard.Web/Core/Shapes/Views/AdminTabs.cshtml
Normal file
24
src/Orchard.Web/Core/Shapes/Views/AdminTabs.cshtml
Normal 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>
|
||||||
|
}
|
||||||
3
src/Orchard.Web/Core/Shapes/Views/LocalNavigation.cshtml
Normal file
3
src/Orchard.Web/Core/Shapes/Views/LocalNavigation.cshtml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@{
|
||||||
|
Layout.LocalNavigation.Add(New.AdminTabs(Tabs: Model.Tabs));
|
||||||
|
}
|
||||||
@@ -67,6 +67,10 @@
|
|||||||
<Reference Include="System.Web" />
|
<Reference Include="System.Web" />
|
||||||
<Reference Include="System.Web.Abstractions" />
|
<Reference Include="System.Web.Abstractions" />
|
||||||
<Reference Include="System.Web.Routing" />
|
<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.Xml" />
|
||||||
<Reference Include="System.Configuration" />
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.DisplayManagement.Shapes;
|
using Orchard.DisplayManagement.Shapes;
|
||||||
|
|
||||||
@@ -27,16 +28,16 @@ namespace Orchard.ContentManagement.Drivers {
|
|||||||
|
|
||||||
private void ApplyImplementation(BuildShapeContext context, string displayType) {
|
private void ApplyImplementation(BuildShapeContext context, string displayType) {
|
||||||
var placement = context.FindPlacement(_shapeType, _differentiator, _defaultLocation);
|
var placement = context.FindPlacement(_shapeType, _differentiator, _defaultLocation);
|
||||||
if (string.IsNullOrEmpty(placement.Location) || placement.Location == "-")
|
if (String.IsNullOrEmpty(placement.Location) || placement.Location == "-")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// parse group placement
|
// Parse group placement.
|
||||||
var group = placement.GetGroup();
|
var group = placement.GetGroup();
|
||||||
if (!String.IsNullOrEmpty(group)) {
|
if (!String.IsNullOrEmpty(group)) {
|
||||||
_groupId = group;
|
_groupId = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase))
|
if (!String.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dynamic parentShape = context.Shape;
|
dynamic parentShape = context.Shape;
|
||||||
@@ -44,17 +45,17 @@ namespace Orchard.ContentManagement.Drivers {
|
|||||||
|
|
||||||
var newShape = _shapeBuilder(context);
|
var newShape = _shapeBuilder(context);
|
||||||
|
|
||||||
// ignore it if the driver returned a null shape
|
// Ignore it if the driver returned a null shape.
|
||||||
if(newShape == null) {
|
if (newShape == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a ContentPart property to the final shape
|
// Add a ContentPart property to the final shape.
|
||||||
if (ContentPart != null && newShape.ContentPart == null) {
|
if (ContentPart != null && newShape.ContentPart == null) {
|
||||||
newShape.ContentPart = ContentPart;
|
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) {
|
if (ContentField != null && newShape.ContentField == null) {
|
||||||
newShape.ContentField = ContentField;
|
newShape.ContentField = ContentField;
|
||||||
}
|
}
|
||||||
@@ -63,8 +64,9 @@ namespace Orchard.ContentManagement.Drivers {
|
|||||||
newShapeMetadata.Prefix = _prefix;
|
newShapeMetadata.Prefix = _prefix;
|
||||||
newShapeMetadata.DisplayType = displayType;
|
newShapeMetadata.DisplayType = displayType;
|
||||||
newShapeMetadata.PlacementSource = placement.Source;
|
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)) {
|
if (!String.IsNullOrEmpty(placement.ShapeType)) {
|
||||||
newShapeMetadata.Type = placement.ShapeType;
|
newShapeMetadata.Type = placement.ShapeType;
|
||||||
newShapeMetadata.Alternates.Clear();
|
newShapeMetadata.Alternates.Clear();
|
||||||
@@ -79,7 +81,7 @@ namespace Orchard.ContentManagement.Drivers {
|
|||||||
newShapeMetadata.Wrappers.Add(wrapper);
|
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()) {
|
if (placement.IsLayoutZone()) {
|
||||||
parentShape = context.Layout;
|
parentShape = context.Layout;
|
||||||
}
|
}
|
||||||
@@ -106,7 +108,7 @@ namespace Orchard.ContentManagement.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ContentShapeResult OnGroup(string groupId) {
|
public ContentShapeResult OnGroup(string groupId) {
|
||||||
_groupId=groupId;
|
_groupId = groupId;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace Orchard.DisplayManagement.Shapes {
|
|||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public string DisplayType { get; set; }
|
public string DisplayType { get; set; }
|
||||||
public string Position { get; set; }
|
public string Position { get; set; }
|
||||||
|
public string Tab { get; set; }
|
||||||
public string PlacementSource { get; set; }
|
public string PlacementSource { get; set; }
|
||||||
public string Prefix { get; set; }
|
public string Prefix { get; set; }
|
||||||
public IList<string> Wrappers { get; set; }
|
public IList<string> Wrappers { get; set; }
|
||||||
|
|||||||
Reference in New Issue
Block a user