mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Implemented tabbed editor UI support.
This commit is contained in:
@@ -1,4 +1,16 @@
|
|||||||
<div class="edit-item">
|
@{
|
||||||
|
var tabs = ((IEnumerable<string>)Model.Tabs).ToList();
|
||||||
|
|
||||||
|
// 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 antyhing else not part of a tab.
|
||||||
|
if (tabs.Any()) {
|
||||||
|
tabs.Remove("Content");
|
||||||
|
tabs.Insert(0, "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();
|
||||||
|
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(Display(item));
|
||||||
|
|
||||||
|
Output.Write(tabBuilder.ToString(TagRenderMode.EndTag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foreach (var item in Order(unordered))
|
||||||
|
Output.Write(Display(item));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Shape]
|
[Shape]
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ namespace Orchard.ContentManagement.Drivers {
|
|||||||
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;
|
||||||
@@ -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,21 @@ 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 tab name is specified, add it to the list of tabs on the parent shape so it can render them.
|
||||||
|
var tabs = (HashSet<string>)parentShape.Tabs;
|
||||||
|
|
||||||
|
if (tabs == null) {
|
||||||
|
tabs = new HashSet<string>();
|
||||||
|
parentShape.Tabs = tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(newShapeMetadata.Tab)) {
|
||||||
|
tabs.Add(newShapeMetadata.Tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 +93,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 +120,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