Added tokenizable default value to ContentPickerFields (#8351)

This commit is contained in:
Matteo Piovanelli
2020-04-16 19:13:30 +02:00
committed by GitHub
parent dbc1e61069
commit d57af5860a
6 changed files with 66 additions and 9 deletions

View File

@@ -7,13 +7,20 @@ using Orchard.ContentManagement.Handlers;
using Orchard.ContentPicker.ViewModels;
using Orchard.Localization;
using Orchard.Utility.Extensions;
using Orchard.ContentPicker.Fields;
using Orchard.Tokens;
using System.Collections.Generic;
namespace Orchard.ContentPicker.Drivers {
public class ContentPickerFieldDriver : ContentFieldDriver<Fields.ContentPickerField> {
private readonly IContentManager _contentManager;
private readonly ITokenizer _tokenizer;
public ContentPickerFieldDriver(IContentManager contentManager) {
public ContentPickerFieldDriver(
IContentManager contentManager,
ITokenizer tokenizer) {
_contentManager = contentManager;
_tokenizer = tokenizer;
T = NullLocalizer.Instance;
}
@@ -41,18 +48,38 @@ namespace Orchard.ContentPicker.Drivers {
protected override DriverResult Editor(ContentPart part, Fields.ContentPickerField field, dynamic shapeHelper) {
return ContentShape("Fields_ContentPicker_Edit", GetDifferentiator(field, part),
() => {
var ids = part.IsNew()
? GetDefaultids(part, field)
: field.Ids;
var model = new ContentPickerFieldViewModel {
Field = field,
Part = part,
ContentItems = _contentManager.GetMany<ContentItem>(field.Ids, VersionOptions.Latest, QueryHints.Empty).ToList()
ContentItems = _contentManager
.GetMany<ContentItem>(ids, VersionOptions.Latest, QueryHints.Empty).ToList()
};
model.SelectedIds = string.Join(",", field.Ids);
model.SelectedIds = string.Join(",", ids);
return shapeHelper.EditorTemplate(TemplateName: "Fields/ContentPicker.Edit", Model: model, Prefix: GetPrefix(field, part));
});
}
private int[] GetDefaultids(ContentPart part, Fields.ContentPickerField field) {
var ids = new int[] { };
var settings = field.PartFieldDefinition.Settings.GetModel<ContentPickerFieldSettings>();
if (!string.IsNullOrWhiteSpace(settings?.DefaultValue)) {
var defaultIds = _tokenizer
.Replace(settings.DefaultValue,
new Dictionary<string, object> { { "Content", part.ContentItem } });
if (!string.IsNullOrWhiteSpace(defaultIds)) {
// attempt to parse the string we populated from tokens
ids = ContentPickerField.DecodeIds(defaultIds);
}
}
return ids;
}
protected override DriverResult Editor(ContentPart part, Fields.ContentPickerField field, IUpdateModel updater, dynamic shapeHelper) {
var model = new ContentPickerFieldViewModel { SelectedIds = string.Join(",", field.Ids) };

View File

@@ -21,7 +21,7 @@ namespace Orchard.ContentPicker.Fields {
}
}
private string EncodeIds(ICollection<int> ids) {
private static string EncodeIds(ICollection<int> ids) {
if (ids == null || !ids.Any()) {
return string.Empty;
}
@@ -30,12 +30,25 @@ namespace Orchard.ContentPicker.Fields {
return "{" + string.Join("},{", ids.ToArray()) + "}";
}
private int[] DecodeIds(string ids) {
public static int[] DecodeIds(string ids) {
if(String.IsNullOrWhiteSpace(ids)) {
return new int[0];
}
return ids.Split(separator, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
// if some of the slices of the string cannot be properly parsed,
// we still will return those that can.
return ids
.Split(separator, StringSplitOptions.RemoveEmptyEntries)
.Select(s => {
int i = -1;
if(int.TryParse(s, out i)) {
return i;
}
// if we can't parse return a negative value
return -1;
})
// take only those that parsed properly
.Where(i => i > 0)
.ToArray();
}
}
}

View File

@@ -26,6 +26,7 @@
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<Use64BitIISExpress />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -196,6 +197,10 @@
<Project>{fbc8b571-ed50-49d8-8d9d-64ab7454a0d6}</Project>
<Name>Orchard.Localization</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Tokens\Orchard.Tokens.csproj">
<Project>{6f759635-13d7-4e94-bcc9-80445d63f117}</Project>
<Name>Orchard.Tokens</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Views\ContentPicker.Edit.cshtml" />

View File

@@ -28,6 +28,7 @@ namespace Orchard.ContentPicker.Settings {
builder.WithSetting("ContentPickerFieldSettings.Multiple", model.Multiple.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("ContentPickerFieldSettings.ShowContentTab", model.ShowContentTab.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("ContentPickerFieldSettings.DisplayedContentTypes", model.DisplayedContentTypes);
builder.WithSetting("ContentPickerFieldSettings.DefaultValue", model.DefaultValue);
}
yield return DefinitionTemplate(model);

View File

@@ -10,5 +10,7 @@
public bool ShowContentTab { get; set; }
public string DisplayedContentTypes { get; set; }
public string DefaultValue { get; set; }
}
}

View File

@@ -14,7 +14,7 @@
</fieldset>
<fieldset>
<label for="@Html.FieldIdFor(m => m.Hint)">@T("Help text")</label>
@Html.TextAreaFor(m => m.Hint, new { @class = "text medium", rows = "5" } )
@Html.TextAreaFor(m => m.Hint, new { @class = "text medium", rows = "5" })
<span class="hint">@T("The help text is written under the field when authors are selecting content items.")</span>
@Html.ValidationMessageFor(m => m.Hint)
</fieldset>
@@ -27,7 +27,16 @@
<fieldset>
<div>
<label for="@Html.FieldIdFor(m => m.DisplayedContentTypes)">@T("Content Types and Parts")</label>
@Html.TextBoxFor(m => m.DisplayedContentTypes)
@Html.TextBoxFor(m => m.DisplayedContentTypes)
<span class="hint">@T("A comma separated value of all the content types or content parts to display.")</span>
</div>
</fieldset>
<fieldset>
<div>
<label for="@Html.FieldIdFor(m => m.DefaultValue)">@T("Default value for the array of selected Ids")</label>
@Html.TextBoxFor(m => m.DefaultValue, new { @class = "text large tokenized"})
<span class="hint">@T("A comma separated list of the ids of selected Items. It also accepts {{ or }} as separators, in line with the serialization normally used for this field.")</span>
</div>
</fieldset>
@Display.TokenHint()