Merge branch '1.10.x' into 1.10.x-to-dev

# Conflicts:
#	src/Orchard.Web/Core/Contents/Controllers/AdminController.cs
#	src/Orchard.Web/Core/Contents/Drivers/ContentsDriver.cs
#	src/Orchard.Web/Core/Contents/Placement.info
#	src/Orchard.Web/Modules/Orchard.Fields/Orchard.Fields.csproj
#	src/Orchard.Web/Themes/TheAdmin/Styles/site.css
#	src/Orchard/Orchard.Framework.csproj
This commit is contained in:
Benedek Farkas
2025-09-18 22:35:24 +02:00
26 changed files with 1332 additions and 905 deletions

View File

@@ -362,6 +362,32 @@ namespace Orchard.Core.Contents.Controllers {
}); });
} }
/// <summary>
/// This action is specific to the submit button of the edit form.
/// Unpublish logic is the same of the Unpublish action, which is called by the content list.
/// </summary>
/// <param name="id"></param>
/// <param name="returnUrl"></param>
/// <returns></returns>
[HttpPost, ActionName("Edit")]
[Mvc.FormValueRequired("submit.Unpublish")]
public ActionResult EditUnpublishPOST(int id, string returnUrl) {
return Unpublish(id, returnUrl);
}
/// <summary>
/// This action is specific to the submit button of the edit form.
/// Delete logic is the same of the Remove action, which is called by the content list.
/// </summary>
/// <param name="id"></param>
/// <param name="returnUrl"></param>
/// <returns></returns>
[HttpPost, ActionName("Edit")]
[Mvc.FormValueRequired("submit.Delete")]
public ActionResult EditDeletePOST(int id, string returnUrl) {
return Remove(id, returnUrl);
}
private ActionResult EditPOST(int id, string returnUrl, Func<ContentItem, bool> conditionallyPublish) { private ActionResult EditPOST(int id, string returnUrl, Func<ContentItem, bool> conditionallyPublish) {
var contentItem = _contentManager.Get(id, VersionOptions.DraftRequired); var contentItem = _contentManager.Get(id, VersionOptions.DraftRequired);

View File

@@ -17,12 +17,17 @@ namespace Orchard.Core.Contents.Drivers {
} }
protected override DriverResult Editor(ContentPart part, dynamic shapeHelper) { protected override DriverResult Editor(ContentPart part, dynamic shapeHelper) {
var results = new List<DriverResult>(); var results = new List<DriverResult> { ContentShape("Content_SaveButton", saveButton => saveButton) };
if (part.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable)
results.Add(ContentShape("Content_SaveButton", saveButton => saveButton));
if (part.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable) {
results.Add(ContentShape("Content_PublishButton", publishButton => publishButton)); results.Add(ContentShape("Content_PublishButton", publishButton => publishButton));
results.Add(ContentShape("Content_UnpublishButton", unpublishButton => unpublishButton));
}
if (part.Id > 0) {
results.Add(ContentShape("Content_DeleteButton", deleteButton => deleteButton));
}
results.Add(ContentShape("Content_CancelButton", cancelButton => cancelButton)); results.Add(ContentShape("Content_CancelButton", cancelButton => cancelButton));
return Combined(results.ToArray()); return Combined(results.ToArray());

View File

@@ -8,7 +8,9 @@
<!-- edit "shape" --> <!-- edit "shape" -->
<Place Content_SaveButton="Sidebar:23"/> <Place Content_SaveButton="Sidebar:23"/>
<Place Content_PublishButton="Sidebar:24"/> <Place Content_PublishButton="Sidebar:24"/>
<Place Content_CancelButton="Sidebar:26"/> <Place Content_UnpublishButton="Sidebar:25"/>
<Place Content_DeleteButton="Sidebar:26"/>
<Place Content_CancelButton="Sidebar:27"/>
<Match DisplayType="Detail"> <Match DisplayType="Detail">
<Place Parts_Contents_Publish="Content:5"/> <Place Parts_Contents_Publish="Content:5"/>
</Match> </Match>

View File

@@ -0,0 +1,8 @@
@using Orchard.ContentManagement;
@using Orchard.Core.Contents;
@if (Authorizer.Authorize(Permissions.DeleteContent, (IContent)Model.ContentItem)) {
<fieldset class="delete-button">
<button type="submit" name="submit.Delete" value="submit.Delete" itemprop="RemoveUrl">@T("Delete")</button>
</fieldset>
}

View File

@@ -0,0 +1,12 @@
@using Orchard.ContentManagement;
@using Orchard.Core.Contents;
@{
var contentItem = Model.ContentItem as IContent;
}
@if (Authorizer.Authorize(Permissions.PublishContent, contentItem) && contentItem.IsPublished()) {
<fieldset class="unpublish-button">
<button type="submit" name="submit.Unpublish" value="submit.Unpublish">@T("Unpublish")</button>
</fieldset>
}

View File

@@ -629,12 +629,16 @@
<Content Include="Contents\Views\Parts.Contents.Clone.SummaryAdmin.cshtml" /> <Content Include="Contents\Views\Parts.Contents.Clone.SummaryAdmin.cshtml" />
<Content Include="Navigation\Views\Admin\Edit.cshtml" /> <Content Include="Navigation\Views\Admin\Edit.cshtml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Contents\Views\Content.UnpublishButton.cshtml" />
<Content Include="Contents\Views\Content.DeleteButton.cshtml" />
<None Include="packages.config" />
<Content Include="Title\Views\DefinitionTemplates\TitlePartSettings.cshtml" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Containers\Styles\Web.config"> <Content Include="Containers\Styles\Web.config">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Content> </Content>
<None Include="packages.config" />
<Content Include="Title\Views\DefinitionTemplates\TitlePartSettings.cshtml" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.Blogs.Extensions; using Orchard.Blogs.Extensions;
using Orchard.Blogs.Models; using Orchard.Blogs.Models;
@@ -138,6 +137,12 @@ namespace Orchard.Blogs.Controllers {
}); });
} }
[HttpPost, ActionName("Edit")]
[Mvc.FormValueRequired("submit.Delete")]
public ActionResult EditDeletePOST(int blogId, int postId, string returnUrl) {
return Delete(blogId, postId);
}
[HttpPost, ActionName("Edit")] [HttpPost, ActionName("Edit")]
[FormValueRequired("submit.Publish")] [FormValueRequired("submit.Publish")]
public ActionResult EditAndPublishPOST(int blogId, int postId, string returnUrl) { public ActionResult EditAndPublishPOST(int blogId, int postId, string returnUrl) {
@@ -156,6 +161,12 @@ namespace Orchard.Blogs.Controllers {
return EditPOST(blogId, postId, returnUrl, contentItem => Services.ContentManager.Publish(contentItem)); return EditPOST(blogId, postId, returnUrl, contentItem => Services.ContentManager.Publish(contentItem));
} }
[HttpPost, ActionName("Edit")]
[Mvc.FormValueRequired("submit.Unpublish")]
public ActionResult EditUnpublishPOST(int blogId, int postId, string returnUrl) {
return Unpublish(blogId, postId);
}
public ActionResult EditPOST(int blogId, int postId, string returnUrl, Action<ContentItem> conditionallyPublish) { public ActionResult EditPOST(int blogId, int postId, string returnUrl, Action<ContentItem> conditionallyPublish) {
var blog = _blogService.Get(blogId, VersionOptions.Latest); var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null) if (blog == null)

View File

@@ -8,4 +8,8 @@ namespace Orchard.Caching.Services {
void Remove(string key); void Remove(string key);
void Clear(); void Clear();
} }
public interface ICacheStorageProviderWithKeyPrefix : ICacheStorageProvider {
void Clear(string key);
}
} }

View File

@@ -4,39 +4,44 @@ using Orchard.ContentManagement.Handlers;
using Orchard.Fields.Fields; using Orchard.Fields.Fields;
using Orchard.Fields.Settings; using Orchard.Fields.Settings;
using Orchard.Localization; using Orchard.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Orchard.Fields.Drivers { namespace Orchard.Fields.Drivers {
public class EnumerationFieldDriver : ContentFieldDriver<EnumerationField> { public class EnumerationFieldDriver : ContentFieldDriver<EnumerationField> {
public IOrchardServices Services { get; set; } public IOrchardServices Services { get; set; }
private const string TemplateName = "Fields/Enumeration.Edit"; private const string TemplateName = "Fields/Enumeration.Edit";
public EnumerationFieldDriver(IOrchardServices services) { public EnumerationFieldDriver(IOrchardServices services) {
Services = services; Services = services;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
public Localizer T { get; set; } public Localizer T { get; set; }
private static string GetPrefix(ContentField field, ContentPart part) => private static string GetPrefix(ContentField field, ContentPart part) {
part.PartDefinition.Name + "." + field.Name; return part.PartDefinition.Name + "." + field.Name;
}
private static string GetDifferentiator(EnumerationField field) => field.Name; private static string GetDifferentiator(EnumerationField field, ContentPart part) {
return field.Name;
}
protected override DriverResult Display(ContentPart part, EnumerationField field, string displayType, dynamic shapeHelper) { protected override DriverResult Display(ContentPart part, EnumerationField field, string displayType, dynamic shapeHelper) {
return ContentShape("Fields_Enumeration", GetDifferentiator(field), () => shapeHelper.Fields_Enumeration()); return ContentShape("Fields_Enumeration", GetDifferentiator(field, part),
() => shapeHelper.Fields_Enumeration());
} }
protected override DriverResult Editor(ContentPart part, EnumerationField field, dynamic shapeHelper) { protected override DriverResult Editor(ContentPart part, EnumerationField field, dynamic shapeHelper) {
return ContentShape("Fields_Enumeration_Edit", GetDifferentiator(field), () => { return ContentShape("Fields_Enumeration_Edit", GetDifferentiator(field, part),
if (part.IsNew() && string.IsNullOrEmpty(field.Value)) { () => {
if (part.IsNew() && String.IsNullOrEmpty(field.Value)) {
var settings = field.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>(); var settings = field.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
if (!string.IsNullOrWhiteSpace(settings.DefaultValue)) { if (!String.IsNullOrWhiteSpace(settings.DefaultValue)) {
field.SelectedValues = new string[] { settings.DefaultValue }; field.Value = settings.DefaultValue;
} }
} }
return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part)); return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part));
}); });
} }

View File

@@ -7,16 +7,28 @@ namespace Orchard.Fields.Fields {
private const char Separator = ';'; private const char Separator = ';';
public string Value { public string Value {
get => Storage.Get<string>()?.Trim(Separator) ?? ""; get { return Storage.Get<string>(); }
set => Storage.Set(string.IsNullOrWhiteSpace(value) set { Storage.Set(value ?? String.Empty); }
? string.Empty
// It is now the responsibility of this field to (re-)add the separators.
: Separator + value.Trim(Separator) + Separator);
} }
public string[] SelectedValues { public string[] SelectedValues {
get => Value?.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries) ?? new string[0]; get {
set => Value = value?.Length > 0 ? string.Join(Separator.ToString(), value) : ""; var value = Value;
if(string.IsNullOrWhiteSpace(value)) {
return new string[0];
}
return value.Split(new [] { Separator }, StringSplitOptions.RemoveEmptyEntries);
}
set {
if (value == null || value.Length == 0) {
Value = String.Empty;
}
else {
Value = Separator + string.Join(Separator.ToString(), value) + Separator;
}
}
} }
} }
} }

View File

@@ -169,7 +169,6 @@
<Compile Include="ViewModels\NumericFieldViewModel.cs" /> <Compile Include="ViewModels\NumericFieldViewModel.cs" />
<Compile Include="ViewModels\DateTimeFieldViewModel.cs" /> <Compile Include="ViewModels\DateTimeFieldViewModel.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup />
<ItemGroup> <ItemGroup>
<Content Include="Views\Fields\Input.cshtml" /> <Content Include="Views\Fields\Input.cshtml" />
</ItemGroup> </ItemGroup>

View File

@@ -4,30 +4,48 @@
@{ @{
var settings = Model.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>(); var settings = Model.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
string[] options = (!String.IsNullOrWhiteSpace(settings.Options)) ? settings.Options.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.None) : new string[] { T("Select an option").ToString() }; string[] options = (!String.IsNullOrWhiteSpace(settings.Options)) ?
settings.Options.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.None)
: new string[] { T("Select an option").ToString() };
} }
<fieldset> <fieldset>
<label for="@Html.FieldIdFor(m => m.Value)" @if (settings.Required) { <text> class="required" </text> }>@Model.DisplayName</label> <label for="@Html.FieldIdFor(m => m.Value)" @if (settings.Required) { <text> class="required" </text> }>@Model.DisplayName</label>
@switch (settings.ListMode) { @switch (settings.ListMode) {
case ListMode.Dropdown: case ListMode.Dropdown:
@Html.DropDownListFor(m => m.Value, new SelectList(options, Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null) @Html.DropDownListFor(
m => m.Value,
new SelectList(options, Model.SelectedValues.FirstOrDefault()),
settings.Required ? new { required = "required" } : null)
break; break;
case ListMode.Radiobutton: case ListMode.Radiobutton:
foreach (var option in options) { foreach (var option in options) {
if (string.IsNullOrWhiteSpace(option)) { if (string.IsNullOrWhiteSpace(option)) {
<label>@Html.RadioButton("Value", "", string.IsNullOrWhiteSpace(Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null)<i>@T("unset")</i></label> <label>@Html.RadioButton(
"Value",
"",
string.IsNullOrWhiteSpace(Model.SelectedValues.FirstOrDefault()),
settings.Required ? new { required = "required" } : null)<i>@T("unset")</i>
</label>
} }
else { else {
<label>@Html.RadioButton("Value", option, (option == Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null)@option</label> <label>@Html.RadioButton(
"Value",
option,
option == Model.SelectedValues.FirstOrDefault(),
settings.Required ? new { required = "required" } : null)@option
</label>
} }
} }
break; break;
case ListMode.Listbox: case ListMode.Listbox:
<input name="@Html.FieldNameFor(m => m.SelectedValues)" type="hidden" /> <input name="@Html.FieldNameFor(m => m.SelectedValues)" type="hidden" />
@Html.ListBoxFor(m => m.SelectedValues, new MultiSelectList(options, Model.SelectedValues), settings.Required ? new { required = "required" } : null) @Html.ListBoxFor(
m => m.SelectedValues,
new MultiSelectList(options, Model.SelectedValues),
settings.Required ? new { required = "required" } : null)
break; break;
case ListMode.Checkbox: case ListMode.Checkbox:
@@ -37,7 +55,9 @@
index++; index++;
if (!string.IsNullOrWhiteSpace(option)) { if (!string.IsNullOrWhiteSpace(option)) {
<div> <div>
<input type="checkbox" name="@Html.FieldNameFor(m => m.SelectedValues)" value="@option" @((Model.SelectedValues != null && Model.SelectedValues.Contains(option)) ? "checked=\"checked\"" : "") class="check-box" id="@Html.FieldIdFor(m => m.SelectedValues)-@index" /> <input type="checkbox" name="@Html.FieldNameFor(m => m.SelectedValues)" value="@option"
@((Model.SelectedValues != null && Model.SelectedValues.Contains(option)) ? "checked=\"checked\"" : "")
class="check-box" id="@Html.FieldIdFor(m => m.SelectedValues)-@index" />
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.SelectedValues)-@index">@option</label> <label class="forcheckbox" for="@Html.FieldIdFor(m => m.SelectedValues)-@index">@option</label>
</div> </div>
} }

View File

@@ -1106,14 +1106,14 @@ html.dyn #submit-pager, html.dyn .apply-bulk-actions-auto { display:none; }
padding:0; padding:0;
} }
fieldset.publish-button, fieldset.delete-button, fieldset.save-button { fieldset.publish-button, fieldset.delete-button, fieldset.save-button, fieldset.unpublish-button {
clear:none; clear:none;
float:left; float:left;
} }
fieldset.save-button { fieldset.save-button {
clear:left; clear:left;
} }
fieldset.publish-button { fieldset.publish-button, fieldset.unpublish-button {
margin: 0 12px 0 0; margin: 0 12px 0 0;
padding: 0 12px; padding: 0 12px;
border-right: 1px solid #ccc; border-right: 1px solid #ccc;

View File

@@ -17,12 +17,16 @@ namespace Orchard.MediaLibrary.Controllers {
[Admin, Themed(false)] [Admin, Themed(false)]
public class OEmbedController : Controller { public class OEmbedController : Controller {
private readonly IMediaLibraryService _mediaLibraryService; private readonly IMediaLibraryService _mediaLibraryService;
private readonly IOEmbedService _oEmbedService;
public OEmbedController( public OEmbedController(
IOrchardServices services, IOrchardServices services,
IMediaLibraryService mediaManagerService) { IMediaLibraryService mediaManagerService,
_mediaLibraryService = mediaManagerService; IOEmbedService oEmbedService) {
Services = services; Services = services;
_mediaLibraryService = mediaManagerService;
_oEmbedService = oEmbedService;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
@@ -78,39 +82,9 @@ namespace Orchard.MediaLibrary.Controllers {
} }
} }
var webClient = new WebClient { Encoding = Encoding.UTF8 };
try { try {
// <link rel="alternate" href="http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F23608259" type="text/xml+oembed"> viewModel.Content = _oEmbedService.DownloadMediaData(url);
var source = webClient.DownloadString(url);
// seek type="text/xml+oembed" or application/xml+oembed
var oembedSignature = source.IndexOf("type=\"text/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
if (oembedSignature == -1) {
oembedSignature = source.IndexOf("type=\"application/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
}
if (oembedSignature != -1) {
var tagStart = source.Substring(0, oembedSignature).LastIndexOf('<');
var tagEnd = source.IndexOf('>', oembedSignature);
var tag = source.Substring(tagStart, tagEnd - tagStart);
var matches = new Regex("href=\"([^\"]+)\"").Matches(tag);
if (matches.Count > 0) {
var href = matches[0].Groups[1].Value;
try {
var content = webClient.DownloadString(Server.HtmlDecode(href));
viewModel.Content = XDocument.Parse(content);
}
catch {
// bubble exception
}
}
}
if (viewModel.Content == null) {
viewModel.Content = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("oembed")
);
}
var root = viewModel.Content.Root; var root = viewModel.Content.Root;
if (!String.IsNullOrWhiteSpace(url)) { if (!String.IsNullOrWhiteSpace(url)) {
root.El("url", url); root.El("url", url);

View File

@@ -208,7 +208,9 @@
<Compile Include="Security\MediaAuthorizationEventHandler.cs" /> <Compile Include="Security\MediaAuthorizationEventHandler.cs" />
<Compile Include="Services\IMediaLibraryService.cs" /> <Compile Include="Services\IMediaLibraryService.cs" />
<Compile Include="Providers\IMediaFolderProvider.cs" /> <Compile Include="Providers\IMediaFolderProvider.cs" />
<Compile Include="Services\IOEmbedService.cs" />
<Compile Include="Services\MediaLibraryService.cs" /> <Compile Include="Services\MediaLibraryService.cs" />
<Compile Include="Services\OEmbedService.cs" />
<Compile Include="Services\Shapes.cs" /> <Compile Include="Services\Shapes.cs" />
<Compile Include="Services\XmlRpcHandler.cs" /> <Compile Include="Services\XmlRpcHandler.cs" />
<Compile Include="Settings\MediaLibraryPickerFieldLocalizationEditorEvents.cs" /> <Compile Include="Settings\MediaLibraryPickerFieldLocalizationEditorEvents.cs" />

View File

@@ -0,0 +1,7 @@
using System.Xml.Linq;
namespace Orchard.MediaLibrary.Services {
public interface IOEmbedService : IDependency {
XDocument DownloadMediaData(string url);
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml.Linq;
namespace Orchard.MediaLibrary.Services {
public class OEmbedService : IOEmbedService {
public XDocument DownloadMediaData(string url) {
var webClient = new WebClient { Encoding = Encoding.UTF8 };
XDocument doc = null;
try {
// <link rel="alternate" href="http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F23608259" type="text/xml+oembed">
var source = webClient.DownloadString(url);
// seek type="text/xml+oembed" or application/xml+oembed
var oembedSignature = source.IndexOf("type=\"text/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
if (oembedSignature == -1) {
oembedSignature = source.IndexOf("type=\"application/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
}
if (oembedSignature != -1) {
var tagStart = source.Substring(0, oembedSignature).LastIndexOf('<');
var tagEnd = source.IndexOf('>', oembedSignature);
var tag = source.Substring(tagStart, tagEnd - tagStart);
var matches = new Regex("href=\"([^\"]+)\"").Matches(tag);
if (matches.Count > 0) {
var href = matches[0].Groups[1].Value;
try {
var content = webClient.DownloadString(HttpUtility.HtmlDecode(href));
doc = XDocument.Parse(content);
} catch {
// bubble exception
}
}
}
} catch {
doc = null;
}
if (doc == null) {
doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("oembed")
);
}
return doc;
}
}
}

View File

@@ -9,10 +9,9 @@ using StackExchange.Redis;
using System; using System;
namespace Orchard.Redis.Caching { namespace Orchard.Redis.Caching {
[OrchardFeature("Orchard.Redis.Caching")] [OrchardFeature("Orchard.Redis.Caching")]
[OrchardSuppressDependency("Orchard.Caching.Services.DefaultCacheStorageProvider")] [OrchardSuppressDependency("Orchard.Caching.Services.DefaultCacheStorageProvider")]
public class RedisCacheStorageProvider : Component, ICacheStorageProvider { public class RedisCacheStorageProvider : Component, ICacheStorageProviderWithKeyPrefix {
public const string ConnectionStringKey = "Orchard.Redis.Cache"; public const string ConnectionStringKey = "Orchard.Redis.Cache";
private readonly ShellSettings _shellSettings; private readonly ShellSettings _shellSettings;
@@ -61,6 +60,10 @@ namespace Orchard.Redis.Caching {
_connectionMultiplexer.KeyDeleteWithPrefix(GetLocalizedKey("*")); _connectionMultiplexer.KeyDeleteWithPrefix(GetLocalizedKey("*"));
} }
public void Clear(string key) {
_connectionMultiplexer.KeyDeleteWithPrefix(GetLocalizedKey($"{_shellSettings.Name}:{key}"));
}
private string GetLocalizedKey(string key) { private string GetLocalizedKey(string key) {
return _shellSettings.Name + ":Cache:" + key; return _shellSettings.Name + ":Cache:" + key;
} }

View File

@@ -33,10 +33,6 @@ namespace Orchard.Widgets.Drivers {
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.LayerPart", Model: layerPart, Prefix: Prefix)) () => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.LayerPart", Model: layerPart, Prefix: Prefix))
}; };
if (layerPart.Id > 0)
results.Add(ContentShape("Widget_DeleteButton",
deleteButton => deleteButton));
return Combined(results.ToArray()); return Combined(results.ToArray());
} }
@@ -55,8 +51,7 @@ namespace Orchard.Widgets.Drivers {
try { try {
_conditionManager.Matches(layerPart.LayerRule); _conditionManager.Matches(layerPart.LayerRule);
} } catch (Exception e) {
catch (Exception e) {
updater.AddModelError("Description", T("The rule is not valid: {0}", e.Message)); updater.AddModelError("Description", T("The rule is not valid: {0}", e.Message));
} }
} }

View File

@@ -35,10 +35,6 @@ namespace Orchard.Widgets.Drivers {
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.WidgetPart", Model: widgetPart, Prefix: Prefix)) () => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.WidgetPart", Model: widgetPart, Prefix: Prefix))
}; };
if (widgetPart.Id > 0)
results.Add(ContentShape("Widget_DeleteButton",
deleteButton => deleteButton));
return Combined(results.ToArray()); return Combined(results.ToArray());
} }

View File

@@ -208,9 +208,6 @@
<Content Include="Views\EditorTemplates\Parts.Widgets.LayerPart.cshtml" /> <Content Include="Views\EditorTemplates\Parts.Widgets.LayerPart.cshtml" />
<Content Include="Views\EditorTemplates\Parts.Widgets.WidgetPart.cshtml" /> <Content Include="Views\EditorTemplates\Parts.Widgets.WidgetPart.cshtml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Views\Widget.DeleteButton.cshtml" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Web.config" /> <Content Include="Web.config" />
</ItemGroup> </ItemGroup>

View File

@@ -1,5 +1,4 @@
<Placement> <Placement>
<Place Widget_DeleteButton="Sidebar:25"/>
<Place Parts_Widgets_LayerPart="Content:1"/> <Place Parts_Widgets_LayerPart="Content:1"/>
<Place Parts_Widgets_WidgetPart="Content:1"/> <Place Parts_Widgets_WidgetPart="Content:1"/>
</Placement> </Placement>

View File

@@ -1,3 +0,0 @@
<fieldset class="delete-button">
<button type="submit" name="submit.Delete" value="@T("Delete")" itemprop="RemoveUrl">@T("Delete")</button>
</fieldset>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
using System;
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
namespace Orchard.Data.Conventions
{
[AttributeUsage(AttributeTargets.Property)]
public class LazyLoadAttribute : Attribute {
}
public class LazyLoadConvention : AttributePropertyConvention<LazyLoadAttribute> {
protected override void Apply(LazyLoadAttribute attribute, IPropertyInstance instance) {
instance.LazyLoad();
}
}
}

View File

@@ -154,6 +154,7 @@
<Compile Include="ContentManagement\Extensions\DriverResultExtensions.cs" /> <Compile Include="ContentManagement\Extensions\DriverResultExtensions.cs" />
<Compile Include="ContentManagement\Handlers\CloneContentContext.cs" /> <Compile Include="ContentManagement\Handlers\CloneContentContext.cs" />
<Compile Include="ContentManagement\IGlobalCriteriaProvider.cs" /> <Compile Include="ContentManagement\IGlobalCriteriaProvider.cs" />
<Compile Include="Data\Conventions\LazyLoadConvention.cs" />
<Compile Include="Data\MapAsRecordAttribute.cs" /> <Compile Include="Data\MapAsRecordAttribute.cs" />
<Compile Include="Data\Migration\Interpreters\PostgreSqlCommandInterpreter.cs" /> <Compile Include="Data\Migration\Interpreters\PostgreSqlCommandInterpreter.cs" />
<Compile Include="Data\NoLockInterceptor.cs" /> <Compile Include="Data\NoLockInterceptor.cs" />