mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-04-05 21:01:35 +08:00
Projections: "RewriteOutput" bool property of a Layout Property migrated to a tokenized condition text, fixes #6928 (#8275)
This commit is contained in:
parent
5815a2b9fa
commit
5668919dd4
@ -10,7 +10,6 @@ using Orchard.Localization;
|
||||
using Orchard.Projections.Models;
|
||||
using Orchard.Projections.Services;
|
||||
using Orchard.Projections.ViewModels;
|
||||
using Orchard.Security;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
@ -59,7 +58,7 @@ namespace Orchard.Projections.Controllers {
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var property = _repository.Get(propertyId);
|
||||
if(property == null) {
|
||||
if (property == null) {
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
@ -82,8 +81,8 @@ namespace Orchard.Projections.Controllers {
|
||||
}
|
||||
|
||||
var viewModel = new PropertyEditViewModel {
|
||||
Id = id,
|
||||
Description = String.Empty,
|
||||
Id = id,
|
||||
Description = String.Empty,
|
||||
Property = property
|
||||
};
|
||||
|
||||
@ -123,7 +122,7 @@ namespace Orchard.Projections.Controllers {
|
||||
viewModel.ZeroIsEmpty = propertyRecord.ZeroIsEmpty;
|
||||
viewModel.HideEmpty = propertyRecord.HideEmpty;
|
||||
|
||||
viewModel.RewriteOutput = propertyRecord.RewriteOutput;
|
||||
viewModel.RewriteOutputCondition = propertyRecord.RewriteOutputCondition;
|
||||
viewModel.RewriteText = propertyRecord.RewriteText;
|
||||
viewModel.StripHtmlTags = propertyRecord.StripHtmlTags;
|
||||
viewModel.TrimLength = propertyRecord.TrimLength;
|
||||
@ -158,8 +157,8 @@ namespace Orchard.Projections.Controllers {
|
||||
// add new property record if it's a newly created property
|
||||
if (propertyRecord == null) {
|
||||
propertyRecord = new PropertyRecord {
|
||||
Category = category,
|
||||
Type = type,
|
||||
Category = category,
|
||||
Type = type,
|
||||
Position = layout.Properties.Count
|
||||
};
|
||||
layout.Properties.Add(propertyRecord);
|
||||
@ -190,7 +189,7 @@ namespace Orchard.Projections.Controllers {
|
||||
propertyRecord.ZeroIsEmpty = model.ZeroIsEmpty;
|
||||
propertyRecord.HideEmpty = model.HideEmpty;
|
||||
|
||||
propertyRecord.RewriteOutput = model.RewriteOutput;
|
||||
propertyRecord.RewriteOutputCondition = model.RewriteOutputCondition;
|
||||
propertyRecord.RewriteText = model.RewriteText;
|
||||
propertyRecord.StripHtmlTags = model.StripHtmlTags;
|
||||
propertyRecord.TrimLength = model.TrimLength;
|
||||
@ -217,9 +216,11 @@ namespace Orchard.Projections.Controllers {
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
switch (direction) {
|
||||
case "up": _propertyService.MoveUp(id);
|
||||
case "up":
|
||||
_propertyService.MoveUp(id);
|
||||
break;
|
||||
case "down": _propertyService.MoveDown(id);
|
||||
case "down":
|
||||
_propertyService.MoveDown(id);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("direction");
|
||||
|
@ -232,7 +232,7 @@ namespace Orchard.Projections.Drivers {
|
||||
new XAttribute("MaxLength", property.MaxLength),
|
||||
new XAttribute("NoResultText", property.NoResultText ?? ""),
|
||||
new XAttribute("PreserveLines", property.PreserveLines),
|
||||
new XAttribute("RewriteOutput", property.RewriteOutput),
|
||||
new XAttribute("RewriteOutputCondition", property.RewriteOutputCondition ?? ""),
|
||||
new XAttribute("RewriteText", property.RewriteText ?? ""),
|
||||
new XAttribute("StripHtmlTags", property.StripHtmlTags),
|
||||
new XAttribute("TrimLength", property.TrimLength),
|
||||
@ -270,7 +270,10 @@ namespace Orchard.Projections.Drivers {
|
||||
NoResultText = property.Attribute("NoResultText").Value,
|
||||
Position = Convert.ToInt32(property.Attribute("Position").Value),
|
||||
PreserveLines = Convert.ToBoolean(property.Attribute("PreserveLines").Value),
|
||||
RewriteOutput = Convert.ToBoolean(property.Attribute("RewriteOutput").Value),
|
||||
// RewriteOutput is processed to ensure backwards-compatibility with recipes
|
||||
// that were created before RewriteOutputCondition was added.
|
||||
RewriteOutputCondition = property.Attribute("RewriteOutputCondition")?.Value ??
|
||||
property.Attribute("RewriteOutput")?.Value,
|
||||
RewriteText = property.Attribute("RewriteText").Value,
|
||||
State = property.Attribute("State").Value,
|
||||
StripHtmlTags = Convert.ToBoolean(property.Attribute("StripHtmlTags").Value),
|
||||
|
@ -11,9 +11,14 @@ using Orchard.Projections.Models;
|
||||
namespace Orchard.Projections {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
private readonly IRepository<MemberBindingRecord> _memberBindingRepository;
|
||||
private readonly IRepository<PropertyRecord> _propertyRecordRepository;
|
||||
|
||||
public Migrations(IRepository<MemberBindingRecord> memberBindingRepository) {
|
||||
public Migrations(
|
||||
IRepository<MemberBindingRecord> memberBindingRepository,
|
||||
IRepository<PropertyRecord> propertyRecordRepository) {
|
||||
_memberBindingRepository = memberBindingRepository;
|
||||
_propertyRecordRepository = propertyRecordRepository;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@ -238,7 +243,7 @@ namespace Orchard.Projections {
|
||||
DisplayName = T("Body Part Text").Text,
|
||||
Description = T("The text from the Body part").Text
|
||||
});
|
||||
|
||||
|
||||
SchemaBuilder.AlterTable("StringFieldIndexRecord", table => table
|
||||
.CreateIndex("IDX_Orchard_Projections_StringFieldIndexRecord", "FieldIndexPartRecord_Id")
|
||||
);
|
||||
@ -294,6 +299,7 @@ namespace Orchard.Projections {
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int UpdateFrom4() {
|
||||
SchemaBuilder.AlterTable("StringFieldIndexRecord", table => table
|
||||
.AddColumn<string>("LatestValue", c => c.WithLength(4000)));
|
||||
@ -322,7 +328,19 @@ namespace Orchard.Projections {
|
||||
|
||||
SchemaBuilder.AlterTable("QueryPartRecord", table => table
|
||||
.AddColumn<string>("VersionScope", c => c.WithLength(15)));
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
public int UpdateFrom5() {
|
||||
SchemaBuilder.AlterTable("PropertyRecord", table => table
|
||||
.AddColumn<string>("RewriteOutputCondition", c => c.Unlimited())
|
||||
);
|
||||
|
||||
foreach (var property in _propertyRecordRepository.Table)
|
||||
if (property.RewriteOutput) property.RewriteOutputCondition = "true";
|
||||
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Orchard.Projections.Models {
|
||||
public class PropertyRecord {
|
||||
@ -42,7 +43,9 @@ namespace Orchard.Projections.Models {
|
||||
public virtual bool HideEmpty { get; set; }
|
||||
|
||||
// Rewrite Result
|
||||
[Obsolete("Set RewriteOutputCondition to \"true\" instead.")]
|
||||
public virtual bool RewriteOutput { get; set; }
|
||||
public virtual string RewriteOutputCondition { get; set; }
|
||||
public virtual string RewriteText { get; set; }
|
||||
public virtual bool StripHtmlTags { get; set; }
|
||||
public virtual bool TrimLength { get; set; }
|
||||
|
@ -6,4 +6,4 @@ Version: 1.10.3
|
||||
OrchardVersion: 1.10.3
|
||||
Description: Provides methods to control how lists of content items are filtered and displayed
|
||||
Category: Content
|
||||
Dependencies: Orchard.Tokens, Orchard.Forms, Feeds, Title
|
||||
Dependencies: Orchard.Tokens, Orchard.Conditions, Orchard.Forms, Feeds, Title
|
||||
|
@ -150,6 +150,10 @@
|
||||
<Name>Orchard.Core</Name>
|
||||
<Private>$(MvcBuildViews)</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Conditions\Orchard.Conditions.csproj">
|
||||
<Project>{98251EAE-A41B-47B2-AA91-E28B8482DA70}</Project>
|
||||
<Name>Orchard.Conditions</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Forms\Orchard.Forms.csproj">
|
||||
<Project>{642A49D7-8752-4177-80D6-BFBBCFAD3DE0}</Project>
|
||||
<Name>Orchard.Forms</Name>
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Conditions.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Environment;
|
||||
@ -13,9 +14,12 @@ using Orchard.Utility.Extensions;
|
||||
namespace Orchard.Projections.Services {
|
||||
public class PropertyShapes : IDependency {
|
||||
private readonly Work<ITokenizer> _tokenizerWork;
|
||||
private readonly Work<IConditionManager> _conditionManagerWork;
|
||||
private readonly Dictionary<string, bool> _evaluations = new Dictionary<string, bool>();
|
||||
|
||||
public PropertyShapes(Work<ITokenizer> tokenizerWork) {
|
||||
public PropertyShapes(Work<ITokenizer> tokenizerWork, Work<IConditionManager> conditionManagerWork) {
|
||||
_tokenizerWork = tokenizerWork;
|
||||
_conditionManagerWork = conditionManagerWork;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@ -24,7 +28,7 @@ namespace Orchard.Projections.Services {
|
||||
[Shape]
|
||||
public void Properties(dynamic Display, TextWriter Output, HtmlHelper Html, IEnumerable<dynamic> Items) {
|
||||
foreach (var item in Items) {
|
||||
if((bool)item.Property.ExcludeFromDisplay) {
|
||||
if ((bool)item.Property.ExcludeFromDisplay) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -32,54 +36,55 @@ namespace Orchard.Projections.Services {
|
||||
}
|
||||
}
|
||||
|
||||
[Shape]
|
||||
[Shape]
|
||||
public void LayoutGroup(dynamic Display, TextWriter Output, HtmlHelper Html, dynamic Key, dynamic List) {
|
||||
Output.WriteLine(Display(Key));
|
||||
Output.WriteLine(Display(Key));
|
||||
Output.WriteLine(Display(List));
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public void PropertyWrapper(
|
||||
dynamic Display,
|
||||
TextWriter Output,
|
||||
dynamic Display,
|
||||
TextWriter Output,
|
||||
HtmlHelper Html,
|
||||
UrlHelper Url,
|
||||
UrlHelper Url,
|
||||
dynamic Item,
|
||||
ContentItem ContentItem,
|
||||
ContentItemMetadata ContentItemMetadata,
|
||||
PropertyRecord Property
|
||||
) {
|
||||
|
||||
// Display will encode any string which is not IHtmlString
|
||||
PropertyRecord Property) {
|
||||
// Display will encode any string which is not IHtmlString.
|
||||
string resultOutput = Convert.ToString(Display(Item));
|
||||
var resultIsEmpty = String.IsNullOrEmpty(resultOutput) || (resultOutput == "0" && Property.ZeroIsEmpty);
|
||||
|
||||
if(Property.HideEmpty && resultIsEmpty) {
|
||||
var tokenData = new Dictionary<string, object> { { "Text", resultOutput }, { "Content", ContentItem } };
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Property.RewriteOutputCondition) &&
|
||||
_conditionManagerWork.Value.Matches(_tokenizerWork.Value.Replace(Property.RewriteOutputCondition, tokenData)))
|
||||
resultOutput = string.IsNullOrWhiteSpace(Property.RewriteText) ? "" : _tokenizerWork.Value.Replace(Property.RewriteText, tokenData);
|
||||
|
||||
var resultIsEmpty = string.IsNullOrEmpty(resultOutput) || (resultOutput == "0" && Property.ZeroIsEmpty);
|
||||
|
||||
if (Property.HideEmpty && resultIsEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(Property.RewriteOutput) {
|
||||
resultOutput = _tokenizerWork.Value.Replace(Property.RewriteText, new Dictionary<string, object> { { "Text", resultOutput }, { "Content", ContentItem } });
|
||||
}
|
||||
|
||||
if(Property.StripHtmlTags) {
|
||||
if (Property.StripHtmlTags) {
|
||||
resultOutput = resultOutput.RemoveTags();
|
||||
}
|
||||
|
||||
if(Property.TrimLength) {
|
||||
if (Property.TrimLength) {
|
||||
var ellipsis = Property.AddEllipsis ? " …" : "";
|
||||
resultOutput = resultOutput.Ellipsize(Property.MaxLength, ellipsis, Property.TrimOnWordBoundary);
|
||||
}
|
||||
|
||||
if(Property.TrimWhiteSpace) {
|
||||
if (Property.TrimWhiteSpace) {
|
||||
resultOutput = resultOutput.Trim();
|
||||
}
|
||||
|
||||
if(Property.PreserveLines) {
|
||||
using(var sw = new StringWriter()) {
|
||||
using(var sr = new StringReader(resultOutput)) {
|
||||
if (Property.PreserveLines) {
|
||||
using (var sw = new StringWriter()) {
|
||||
using (var sr = new StringReader(resultOutput)) {
|
||||
string line;
|
||||
while(null != (line = sr.ReadLine())) {
|
||||
while (null != (line = sr.ReadLine())) {
|
||||
sw.WriteLine(line);
|
||||
sw.WriteLine("<br />");
|
||||
}
|
||||
@ -89,7 +94,7 @@ namespace Orchard.Projections.Services {
|
||||
}
|
||||
|
||||
var wrapperTag = new TagBuilder(Property.CustomizeWrapperHtml && !String.IsNullOrEmpty(Property.CustomWrapperTag) ? Property.CustomWrapperTag : "div");
|
||||
|
||||
|
||||
if (Property.CustomizeWrapperHtml && !String.IsNullOrEmpty(Property.CustomWrapperCss)) {
|
||||
wrapperTag.AddCssClass(_tokenizerWork.Value.Replace(Property.CustomWrapperCss, new Dictionary<string, object>()));
|
||||
}
|
||||
@ -113,11 +118,11 @@ namespace Orchard.Projections.Services {
|
||||
|
||||
if (!(Property.CustomizeLabelHtml && Property.CustomLabelTag == "-")) {
|
||||
Output.Write(labelTag.ToString(TagRenderMode.EndTag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var propertyTag = new TagBuilder(Property.CustomizePropertyHtml && !String.IsNullOrEmpty(Property.CustomPropertyTag) ? Property.CustomPropertyTag : "span");
|
||||
|
||||
|
||||
if (Property.CustomizePropertyHtml && !String.IsNullOrEmpty(Property.CustomPropertyCss)) {
|
||||
propertyTag.AddCssClass(_tokenizerWork.Value.Replace(Property.CustomPropertyCss, new Dictionary<string, object>()));
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace Orchard.Projections.ViewModels {
|
||||
public bool ZeroIsEmpty { get; set; }
|
||||
public bool HideEmpty { get; set; }
|
||||
|
||||
public bool RewriteOutput { get; set; }
|
||||
public string RewriteOutputCondition { get; set; }
|
||||
public string RewriteText { get; set; }
|
||||
public bool StripHtmlTags { get; set; }
|
||||
public bool TrimLength { get; set; }
|
||||
|
@ -141,16 +141,18 @@
|
||||
<div class="expando">
|
||||
<div>
|
||||
<div>
|
||||
@Html.CheckBoxFor(m => m.RewriteOutput)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.RewriteOutput)">@T("Rewrite output")</label>
|
||||
<span class="hint">@T("Check to override the output of this property.")</span>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.RewriteOutputCondition)">@T("Rewrite output condition")</label>
|
||||
@Html.TextBoxFor(m => m.RewriteOutputCondition, new { @class = "text large tokenized" })
|
||||
<span class="hint">@T("A condition that will be evaluated to decide whether to rewrite the output or not.")</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-controllerid="@Html.FieldIdFor(m => m.RewriteOutput)">
|
||||
<div>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.RewriteText)">@T("Rewrite text")</label>
|
||||
@Html.TextBoxFor(m => m.RewriteText, new { @class = "text large tokenized" })
|
||||
<span class="hint">@T("The text to write for this field. It may include HTML. {Text} can be used to inject the current property text.")</span>
|
||||
<span class="hint">@T("The tokenized text that will be evaluated and applied if \"Rewrite output condition\" evaluates to true. It may include HTML and {Text} can be used to inject the current property text.")</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user