mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-27 04:19:04 +08:00
Merge branch 'dev' into feature/widget-elements
Conflicts: src/Orchard.Web/Modules/Orchard.Layouts/Orchard.Layouts.csproj src/Orchard.Web/Modules/Orchard.Layouts/Services/ElementManager.cs
This commit is contained in:
@@ -11,9 +11,9 @@ namespace Orchard.Layouts {
|
||||
builder
|
||||
.AddImageSet("layouts")
|
||||
.Add(T("Layouts"), "8.5", layouts => layouts
|
||||
.Action("List", "Admin", new {id = "Layout", area = "Contents"})
|
||||
.Action("List", "Admin", new {id = "Layout", area = "Contents"}).Permission(Permissions.ManageLayouts)
|
||||
.LinkToFirstChild(false)
|
||||
.Add(T("Elements"), "1", elements => elements.Action("Index", "BlueprintAdmin", new {area = "Orchard.Layouts"})));
|
||||
.Add(T("Elements"), "1", elements => elements.Action("Index", "BlueprintAdmin", new {area = "Orchard.Layouts"}).Permission(Permissions.ManageLayouts)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,45 +74,6 @@
|
||||
return host.addElement(contentType);
|
||||
};
|
||||
|
||||
$scope.toggleInlineEditing = function () {
|
||||
if (!$scope.element.inlineEditingIsActive) {
|
||||
$scope.element.inlineEditingIsActive = true;
|
||||
$element.find(".layout-toolbar-container").show();
|
||||
var selector = "#layout-editor-" + $scope.$id + " .layout-html .layout-content-markup[data-templated=false]";
|
||||
var firstContentEditorId = $(selector).first().attr("id");
|
||||
tinymce.init({
|
||||
selector: selector,
|
||||
theme: "modern",
|
||||
schema: "html5",
|
||||
plugins: [
|
||||
"advlist autolink lists link image charmap print preview hr anchor pagebreak",
|
||||
"searchreplace wordcount visualblocks visualchars code fullscreen",
|
||||
"insertdatetime media nonbreaking table contextmenu directionality",
|
||||
"emoticons template paste textcolor colorpicker textpattern",
|
||||
"fullscreen autoresize"
|
||||
],
|
||||
toolbar: "undo redo cut copy paste | bold italic | bullist numlist outdent indent formatselect | alignleft aligncenter alignright alignjustify ltr rtl | link unlink charmap | code fullscreen close",
|
||||
convert_urls: false,
|
||||
valid_elements: "*[*]",
|
||||
// Shouldn't be needed due to the valid_elements setting, but TinyMCE would strip script.src without it.
|
||||
extended_valid_elements: "script[type|defer|src|language]",
|
||||
statusbar: false,
|
||||
skin: "orchardlightgray",
|
||||
inline: true,
|
||||
fixed_toolbar_container: "#layout-editor-" + $scope.$id + " .layout-toolbar-container",
|
||||
init_instance_callback: function (editor) {
|
||||
if (editor.id == firstContentEditorId)
|
||||
tinymce.execCommand("mceFocus", false, editor.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
tinymce.remove("#layout-editor-" + $scope.$id + " .layout-content-markup");
|
||||
$element.find(".layout-toolbar-container").hide();
|
||||
$scope.element.inlineEditingIsActive = false;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on("cut copy paste", function (e) {
|
||||
// If the pseudo clipboard was already invoked (which happens on the first clipboard
|
||||
// operation after page load even if native clipboard support exists) then sit this
|
||||
@@ -164,23 +125,12 @@
|
||||
element.find(".layout-toolbar-container").click(function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
// Intercept mousedown on editor while in inline editing mode to
|
||||
// prevent current editor from losing focus.
|
||||
element.mousedown(function (e) {
|
||||
if (scope.element.inlineEditingIsActive) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
})
|
||||
// Unfocus and unselect everything on click outside of canvas.
|
||||
$(window).click(function (e) {
|
||||
// Except when in inline editing mode.
|
||||
if (!scope.element.inlineEditingIsActive) {
|
||||
scope.$apply(function () {
|
||||
scope.element.activeElement = null;
|
||||
scope.element.focusedElement = null;
|
||||
});
|
||||
}
|
||||
scope.$apply(function () {
|
||||
scope.element.activeElement = null;
|
||||
scope.element.focusedElement = null;
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,13 +35,6 @@
|
||||
templateUrl: environment.templateUrl("Html"),
|
||||
replace: true,
|
||||
link: function (scope, element) {
|
||||
// Mouse down events must not be intercepted by drag and drop while inline editing is active,
|
||||
// otherwise clicks in inline editors will have no effect.
|
||||
element.find(".layout-content-markup").mousedown(function (e) {
|
||||
if (scope.element.editor.inlineEditingIsActive) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
var resetFocus = false;
|
||||
var element = $scope.element;
|
||||
|
||||
if (element.editor.isDragging || element.editor.inlineEditingIsActive)
|
||||
if (element.editor.isDragging)
|
||||
return;
|
||||
|
||||
// If native clipboard support exists, the pseudo-clipboard will have been disabled.
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
this.focusedElement = null;
|
||||
this.dropTargetElement = null;
|
||||
this.isDragging = false;
|
||||
this.inlineEditingIsActive = false;
|
||||
this.isResizing = false;
|
||||
|
||||
this.resetToolboxElements = function () {
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
this.setIsActive = function (value) {
|
||||
if (!this.editor)
|
||||
return;
|
||||
if (this.editor.isDragging || this.editor.inlineEditingIsActive || this.editor.isResizing)
|
||||
if (this.editor.isDragging || this.editor.isResizing)
|
||||
return;
|
||||
|
||||
if (value)
|
||||
@@ -81,7 +81,7 @@
|
||||
return;
|
||||
if (this.isTemplated && !this.allowSealedFocus())
|
||||
return;
|
||||
if (this.editor.isDragging || this.editor.inlineEditingIsActive || this.editor.isResizing)
|
||||
if (this.editor.isDragging || this.editor.isResizing)
|
||||
return;
|
||||
|
||||
this.editor.focusedElement = this;
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,8 @@ namespace Orchard.Layouts.Controllers {
|
||||
ICultureAccessor cultureAccessor,
|
||||
IShapeFactory shapeFactory,
|
||||
ITransactionManager transactionManager,
|
||||
ISignals signals) {
|
||||
ISignals signals,
|
||||
IOrchardServices orchardServices) {
|
||||
|
||||
_elementBlueprintService = elementBlueprintService;
|
||||
_notifier = notifier;
|
||||
@@ -43,12 +44,19 @@ namespace Orchard.Layouts.Controllers {
|
||||
_shapeFactory = shapeFactory;
|
||||
_transactionManager = transactionManager;
|
||||
_signals = signals;
|
||||
Services = orchardServices;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public ActionResult Index() {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
var blueprints = _elementBlueprintService.GetBlueprints().ToArray();
|
||||
var viewModel = new BlueprintsIndexViewModel {
|
||||
Blueprints = blueprints
|
||||
@@ -57,6 +65,10 @@ namespace Orchard.Layouts.Controllers {
|
||||
}
|
||||
|
||||
public ActionResult Browse() {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
var categories = RemoveBlueprints(_elementManager.GetCategories(DescribeElementsContext.Empty)).ToArray();
|
||||
var viewModel = new BrowseElementsViewModel {
|
||||
Categories = categories
|
||||
@@ -65,6 +77,10 @@ namespace Orchard.Layouts.Controllers {
|
||||
}
|
||||
|
||||
public ActionResult Create(string id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
if (String.IsNullOrWhiteSpace(id))
|
||||
return RedirectToAction("Browse");
|
||||
|
||||
@@ -80,6 +96,10 @@ namespace Orchard.Layouts.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Create(string id, CreateElementBlueprintViewModel model) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
var describeContext = DescribeElementsContext.Empty;
|
||||
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, id);
|
||||
var baseElement = _elementManager.ActivateElement(descriptor);
|
||||
@@ -100,7 +120,11 @@ namespace Orchard.Layouts.Controllers {
|
||||
return RedirectToAction("Edit", new { id = blueprint.Id });
|
||||
}
|
||||
|
||||
public ViewResult Edit(int id) {
|
||||
public ActionResult Edit(int id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
var blueprint = _elementBlueprintService.GetBlueprint(id);
|
||||
var describeContext = DescribeElementsContext.Empty;
|
||||
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
|
||||
@@ -125,6 +149,10 @@ namespace Orchard.Layouts.Controllers {
|
||||
[HttpPost]
|
||||
[ValidateInput(false)]
|
||||
public ActionResult Edit(int id, ElementDataViewModel model) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
var blueprint = _elementBlueprintService.GetBlueprint(id);
|
||||
var describeContext = DescribeElementsContext.Empty;
|
||||
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
|
||||
@@ -154,6 +182,10 @@ namespace Orchard.Layouts.Controllers {
|
||||
}
|
||||
|
||||
public ActionResult Properties(int id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
var blueprint = _elementBlueprintService.GetBlueprint(id);
|
||||
var describeContext = DescribeElementsContext.Empty;
|
||||
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
|
||||
@@ -171,6 +203,10 @@ namespace Orchard.Layouts.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Properties(int id, ElementBlueprintPropertiesViewModel model) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
var blueprint = _elementBlueprintService.GetBlueprint(id);
|
||||
var describeContext = DescribeElementsContext.Empty;
|
||||
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
|
||||
@@ -191,7 +227,12 @@ namespace Orchard.Layouts.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Delete(int id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
var blueprint = _elementBlueprintService.GetBlueprint(id);
|
||||
|
||||
if (blueprint == null)
|
||||
@@ -204,7 +245,12 @@ namespace Orchard.Layouts.Controllers {
|
||||
|
||||
[FormValueRequired("submit.BulkEdit")]
|
||||
[ActionName("Index")]
|
||||
[HttpPost]
|
||||
public ActionResult BulkDelete(IEnumerable<int> blueprintIds) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
if (blueprintIds == null || !blueprintIds.Any()) {
|
||||
_notifier.Error(T("Please select the blueprints to delete."));
|
||||
}
|
||||
|
||||
@@ -142,18 +142,7 @@ namespace Orchard.Layouts.Controllers {
|
||||
_objectStore.Set(session, state);
|
||||
return RedirectToAction("Edit", new {session = session});
|
||||
}
|
||||
|
||||
public RedirectToRouteResult Add(string session, string typeName, int? contentId = null, string contentType = null) {
|
||||
var state = new ElementSessionState {
|
||||
TypeName = typeName,
|
||||
ContentId = contentId,
|
||||
ContentType = contentType
|
||||
};
|
||||
|
||||
_objectStore.Set(session, state);
|
||||
return RedirectToAction("Edit", new { session = session });
|
||||
}
|
||||
|
||||
|
||||
public ViewResult Edit(string session) {
|
||||
var sessionState = _objectStore.Get<ElementSessionState>(session);
|
||||
var contentId = sessionState.ContentId;
|
||||
|
||||
@@ -6,6 +6,7 @@ using Orchard.ContentManagement;
|
||||
using Orchard.Layouts.Elements;
|
||||
using Orchard.Layouts.Framework.Elements;
|
||||
using Orchard.Layouts.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Admin;
|
||||
|
||||
namespace Orchard.Layouts.Controllers {
|
||||
@@ -15,15 +16,25 @@ namespace Orchard.Layouts.Controllers {
|
||||
private readonly ILayoutManager _layoutManager;
|
||||
private readonly ILayoutModelMapper _mapper;
|
||||
|
||||
public LayoutController(IContentManager contentManager, ILayoutManager layoutManager, ILayoutModelMapper mapper) {
|
||||
public LayoutController(
|
||||
IContentManager contentManager,
|
||||
ILayoutManager layoutManager,
|
||||
ILayoutModelMapper mapper,
|
||||
IOrchardServices orchardServices) {
|
||||
|
||||
_contentManager = contentManager;
|
||||
_layoutManager = layoutManager;
|
||||
_mapper = mapper;
|
||||
Services = orchardServices;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
|
||||
[HttpPost, ValidateInput(enableValidation: false)]
|
||||
public ContentResult ApplyTemplate(int? templateId = null, string layoutData = null, int? contentId = null, string contentType = null) {
|
||||
public ActionResult ApplyTemplate(int? templateId = null, string layoutData = null, int? contentId = null, string contentType = null) {
|
||||
var template = templateId != null ? _layoutManager.GetLayout(templateId.Value) : null;
|
||||
var templateElements = template != null ? _layoutManager.LoadElements(template).ToList() : default(IEnumerable<Element>);
|
||||
var describeContext = CreateDescribeElementsContext(contentId, contentType);
|
||||
|
||||
@@ -307,10 +307,9 @@ namespace Orchard.Layouts.Drivers {
|
||||
|
||||
var queryPart = query.As<QueryPart>();
|
||||
var layoutIndex = XmlHelper.Parse<int>(context.ExportableData.Get("LayoutIndex"));
|
||||
var layout = queryPart.Layouts[layoutIndex];
|
||||
|
||||
element.QueryId = queryPart.Id;
|
||||
element.LayoutId = layout.Id;
|
||||
element.LayoutId = layoutIndex != -1 ? queryPart.Layouts[layoutIndex].Id : -1;
|
||||
}
|
||||
|
||||
private static string GetLayoutDescription(IEnumerable<LayoutDescriptor> layouts, LayoutRecord l) {
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace Orchard.Layouts {
|
||||
.WithPart("LayoutPart", p => p
|
||||
.WithSetting("LayoutTypePartSettings.IsTemplate", "True"))
|
||||
.DisplayedAs("Layout")
|
||||
.Listable()
|
||||
.Draftable());
|
||||
|
||||
ContentDefinitionManager.AlterTypeDefinition("LayoutWidget", type => type
|
||||
|
||||
@@ -371,6 +371,7 @@
|
||||
<Compile Include="Helpers\PrefixHelper.cs" />
|
||||
<Compile Include="Helpers\JsonHelper.cs" />
|
||||
<Compile Include="Helpers\StringHelper.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Providers\PlaceableContentElementHarvester.cs" />
|
||||
<Compile Include="ViewModels\PlaceableContentItemViewModel.cs" />
|
||||
<Compile Include="Recipes\Builders\CustomElementsStep.cs" />
|
||||
|
||||
40
src/Orchard.Web/Modules/Orchard.Layouts/Permissions.cs
Normal file
40
src/Orchard.Web/Modules/Orchard.Layouts/Permissions.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Security.Permissions;
|
||||
|
||||
namespace Orchard.Layouts {
|
||||
public class Permissions : IPermissionProvider {
|
||||
public static readonly Permission ManageLayouts = new Permission { Description = "Managing Layouts", Name = "ManageLayouts" };
|
||||
|
||||
public virtual Feature Feature { get; set; }
|
||||
|
||||
public IEnumerable<Permission> GetPermissions() {
|
||||
return new[] {
|
||||
ManageLayouts,
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
|
||||
return new[] {
|
||||
new PermissionStereotype {
|
||||
Name = "Administrator",
|
||||
Permissions = new[] { ManageLayouts }
|
||||
},
|
||||
new PermissionStereotype {
|
||||
Name = "Editor",
|
||||
Permissions = new[] { ManageLayouts }
|
||||
},
|
||||
new PermissionStereotype {
|
||||
Name = "Moderator",
|
||||
},
|
||||
new PermissionStereotype {
|
||||
Name = "Author"
|
||||
},
|
||||
new PermissionStereotype {
|
||||
Name = "Contributor",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -38,7 +38,7 @@ namespace Orchard.Layouts.Services {
|
||||
public IEnumerable<ElementDescriptor> DescribeElements(DescribeElementsContext context) {
|
||||
var contentType = context.Content != null ? context.Content.ContentItem.ContentType : default(string);
|
||||
var cacheKey = String.Format("LayoutElementTypes-{0}-{1}", contentType ?? "AnyType", context.CacheVaryParam);
|
||||
return _cacheManager.Get(cacheKey, acquireContext => {
|
||||
return _cacheManager.Get(cacheKey, true, acquireContext => {
|
||||
var harvesterContext = new HarvestElementsContext {
|
||||
Content = context.Content
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
@foreach (var contentItemShape in Model.ContentItems) {
|
||||
var contentItem = (ContentItem)contentItemShape.ContentItem;
|
||||
var displayTextHtmlString = Html.ItemDisplayText(contentItem);
|
||||
var displayText = displayTextHtmlString != null ? displayTextHtmlString.ToString() : T("-").ToString();
|
||||
var displayText = displayTextHtmlString != null ? (IHtmlString)displayTextHtmlString : T("-");
|
||||
<div class="layout-snippet">
|
||||
@displayText
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
<div class="layout-toolbox-wrapper">
|
||||
<div class="layout-toolbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-checked="element.inlineEditingIsActive" ng-click="toggleInlineEditing()" />
|
||||
@T("Edit HTML content inline")
|
||||
</label>
|
||||
<ul class="layout-toolbox-groups" ng-hide="element.inlineEditingIsActive">
|
||||
<ul class="layout-toolbox-groups">
|
||||
<li class="layout-toolbox-group" ng-class="{collapsed: layoutIsCollapsed}">
|
||||
<a href="#" class="layout-toolbox-group-heading" ng-click="toggleLayoutIsCollapsed($event)">@T("Layout")</a>
|
||||
<ul class="layout-toolbox-items">
|
||||
|
||||
Reference in New Issue
Block a user