Added tokenizable default value to ContentPickerFields (#8351)

This commit is contained in:
Matteo Piovanelli
2020-04-16 10:13:30 -07:00
committed by GitHub
parent dbc1e61069
commit d57af5860a
6 changed files with 66 additions and 9 deletions
@@ -7,13 +7,20 @@ using Orchard.ContentManagement.Handlers;
using Orchard.ContentPicker.ViewModels; using Orchard.ContentPicker.ViewModels;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Utility.Extensions; using Orchard.Utility.Extensions;
using Orchard.ContentPicker.Fields;
using Orchard.Tokens;
using System.Collections.Generic;
namespace Orchard.ContentPicker.Drivers { namespace Orchard.ContentPicker.Drivers {
public class ContentPickerFieldDriver : ContentFieldDriver<Fields.ContentPickerField> { public class ContentPickerFieldDriver : ContentFieldDriver<Fields.ContentPickerField> {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly ITokenizer _tokenizer;
public ContentPickerFieldDriver(IContentManager contentManager) { public ContentPickerFieldDriver(
IContentManager contentManager,
ITokenizer tokenizer) {
_contentManager = contentManager; _contentManager = contentManager;
_tokenizer = tokenizer;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
@@ -41,18 +48,38 @@ namespace Orchard.ContentPicker.Drivers {
protected override DriverResult Editor(ContentPart part, Fields.ContentPickerField field, dynamic shapeHelper) { protected override DriverResult Editor(ContentPart part, Fields.ContentPickerField field, dynamic shapeHelper) {
return ContentShape("Fields_ContentPicker_Edit", GetDifferentiator(field, part), return ContentShape("Fields_ContentPicker_Edit", GetDifferentiator(field, part),
() => { () => {
var ids = part.IsNew()
? GetDefaultids(part, field)
: field.Ids;
var model = new ContentPickerFieldViewModel { var model = new ContentPickerFieldViewModel {
Field = field, Field = field,
Part = part, 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)); 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) { protected override DriverResult Editor(ContentPart part, Fields.ContentPickerField field, IUpdateModel updater, dynamic shapeHelper) {
var model = new ContentPickerFieldViewModel { SelectedIds = string.Join(",", field.Ids) }; var model = new ContentPickerFieldViewModel { SelectedIds = string.Join(",", field.Ids) };
@@ -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()) { if (ids == null || !ids.Any()) {
return string.Empty; return string.Empty;
} }
@@ -30,12 +30,25 @@ namespace Orchard.ContentPicker.Fields {
return "{" + string.Join("},{", ids.ToArray()) + "}"; return "{" + string.Join("},{", ids.ToArray()) + "}";
} }
private int[] DecodeIds(string ids) { public static int[] DecodeIds(string ids) {
if(String.IsNullOrWhiteSpace(ids)) { if(String.IsNullOrWhiteSpace(ids)) {
return new int[0]; return new int[0];
} }
// if some of the slices of the string cannot be properly parsed,
return ids.Split(separator, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); // 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();
} }
} }
} }
@@ -26,6 +26,7 @@
<IISExpressWindowsAuthentication /> <IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode /> <IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile /> <UseGlobalApplicationHostFile />
<Use64BitIISExpress />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -196,6 +197,10 @@
<Project>{fbc8b571-ed50-49d8-8d9d-64ab7454a0d6}</Project> <Project>{fbc8b571-ed50-49d8-8d9d-64ab7454a0d6}</Project>
<Name>Orchard.Localization</Name> <Name>Orchard.Localization</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\Orchard.Tokens\Orchard.Tokens.csproj">
<Project>{6f759635-13d7-4e94-bcc9-80445d63f117}</Project>
<Name>Orchard.Tokens</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Views\ContentPicker.Edit.cshtml" /> <Content Include="Views\ContentPicker.Edit.cshtml" />
@@ -28,6 +28,7 @@ namespace Orchard.ContentPicker.Settings {
builder.WithSetting("ContentPickerFieldSettings.Multiple", model.Multiple.ToString(CultureInfo.InvariantCulture)); builder.WithSetting("ContentPickerFieldSettings.Multiple", model.Multiple.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("ContentPickerFieldSettings.ShowContentTab", model.ShowContentTab.ToString(CultureInfo.InvariantCulture)); builder.WithSetting("ContentPickerFieldSettings.ShowContentTab", model.ShowContentTab.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("ContentPickerFieldSettings.DisplayedContentTypes", model.DisplayedContentTypes); builder.WithSetting("ContentPickerFieldSettings.DisplayedContentTypes", model.DisplayedContentTypes);
builder.WithSetting("ContentPickerFieldSettings.DefaultValue", model.DefaultValue);
} }
yield return DefinitionTemplate(model); yield return DefinitionTemplate(model);
@@ -10,5 +10,7 @@
public bool ShowContentTab { get; set; } public bool ShowContentTab { get; set; }
public string DisplayedContentTypes { get; set; } public string DisplayedContentTypes { get; set; }
public string DefaultValue { get; set; }
} }
} }
@@ -14,7 +14,7 @@
</fieldset> </fieldset>
<fieldset> <fieldset>
<label for="@Html.FieldIdFor(m => m.Hint)">@T("Help text")</label> <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> <span class="hint">@T("The help text is written under the field when authors are selecting content items.")</span>
@Html.ValidationMessageFor(m => m.Hint) @Html.ValidationMessageFor(m => m.Hint)
</fieldset> </fieldset>
@@ -31,3 +31,12 @@
<span class="hint">@T("A comma separated value of all the content types or content parts to display.")</span> <span class="hint">@T("A comma separated value of all the content types or content parts to display.")</span>
</div> </div>
</fieldset> </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()