Implements ContentPicker localization options discussed in ()

* Squashed commit of the following:

commit bd1e2bf3d386a1d6f12a5d062639929a17ba6c46
Author: matteo.piovanelli <matteo.piovanelli@laser-group.com>
Date:   Thu Nov 10 12:02:09 2016 +0100

    Added notifications about what the localization methods for ContentPickerField will do or have done.

commit 04eb7074dcfef2c8beb65f0322821dc654902cfb
Author: matteo.piovanelli <matteo.piovanelli@laser-group.com>
Date:   Wed Nov 9 17:48:59 2016 +0100

    Added the TryTranslate option and its suboptions

commit fad9fa87f3f3a8c555d088e8971dd04a337cf4dc
Author: matteo.piovanelli <matteo.piovanelli@laser-group.com>
Date:   Wed Nov 9 15:31:44 2016 +0100

    Added a new feature to the ContentPicker module.
    So far, it stops saving/publication when the items in the ContentPickerField are the "wrong" culture

commit b90629dc3e
Merge: 578b21b c486355
Author: matteo.piovanelli <matteo.piovanelli@laser-group.com>
Date:   Tue Nov 8 09:37:30 2016 +0100

    Merge remote-tracking branch 'remotes/OrchardCMS.Orchard/1.10.x' into Laser/1.10.x

commit 578b21b75e
Merge: 395976f 3c53ffb
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Nov 4 13:45:51 2016 +0100

    Merge branch 'feature/6688_RequestTokens_Chaintext' into Laser/1.10.x

commit 3c53ffb09a
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Nov 4 13:43:38 2016 +0100

    - replaced Regex.Replace with String.Trim(char[]) as suggested
    - ran Orchard.Tokens.Tests: 66/66 passed

commit 395976fa60
Merge: 708ed79 a15557e
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 28 16:34:50 2016 +0200

    Merge branch 'Laser/1.10.x' of https://github.com/LaserSrl/Orchard into Laser/1.10.x

commit 708ed79ccb
Merge: 5fe0b69 68acf26
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 28 16:32:52 2016 +0200

    Merge branch '1.10.x' of https://github.com/LaserSrl/Orchard into Laser/1.10.x

commit 5fe0b69c6b
Merge: 0daad70 e3a7059
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 28 16:32:31 2016 +0200

    Merge branch 'feature/6196_SupportForAttachments' into Laser/1.10.x

commit e3a7059edf
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 28 15:22:48 2016 +0200

    - Addition of an existing png (OrchardLogo.png) as attachment within "Test Smtp Settings" Section, in order to demonstrate functionality of support for attachments in email

commit f095dea5e5
Merge: 7b09747 68acf26
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 28 12:37:55 2016 +0200

    Merge remote-tracking branch 'remotes/OrchardCMS.Orchard/1.10.x' into feature/6688_RequestTokens_Chaintext

commit a15557e5f3
Merge: 0daad70 ce8a61e
Author: matteo.piovanelli <matteo.piovanelli@laser-group.com>
Date:   Thu Oct 27 17:10:53 2016 +0200

    Merge branch 'issues/7346_WidgetsViewQueryString' into Laser/1.10.x

commit 0daad70219
Merge: 927d18b 7b09747
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Thu Oct 27 09:07:58 2016 +0200

    Merge remote-tracking branch 'remotes/Laser.Orchard/feature/6688_RequestTokens_Chaintext' into 1.10.x

commit 7b09747fc9
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Thu Oct 27 09:05:17 2016 +0200

    inserted a better explanation on how to use the chains

commit 927d18b1c2
Merge: f8cbc63 17ebdd2
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 26 19:00:44 2016 +0200

    Merge remote-tracking branch 'remotes/Laser.Orchard/feature/6688_RequestTokens_Chaintext' into 1.10.x

commit 17ebdd2bfc
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 26 18:57:48 2016 +0200

    - typo

commit f8cbc63fc0
Merge: 9f42664 1b511b2
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 26 18:53:11 2016 +0200

    Merge branch 'feature/6688_RequestTokens_Chaintext' into 1.10.x

commit 1b511b2692
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 26 18:50:35 2016 +0200

    - Implement what described in 

    Supported Syntaxes for Request and Form tokens are:
    1. QueryString:(param1) or Form:(param1)
    2. QueryString:param1 or Form:param1
    3. QueryString:(param1).SomeOtherTextToken or Form:(param1).SomeOtherTextToken

    If you want to Chain TextTokens you have to use the 3rd syntax
    the element (here param1) has been surrounded with brackets in order to preserve backward compatibility.

commit ce8a61ed86
Author: matteo.piovanelli <matteo.piovanelli@laser-group.com>
Date:   Wed Oct 26 11:46:24 2016 +0200

    Fixes 

commit 9f4266401a
Merge: 60aa1cc f6cfe32
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Tue Oct 25 09:20:57 2016 +0200

    Merge branch '1.10.x' of https://github.com/LaserSrl/Orchard into 1.10.x

commit 60aa1cc2f4
Merge: c1b1c4d 7a16cf5
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Tue Oct 25 09:20:28 2016 +0200

    Merge branch '1.10.x' of https://github.com/OrchardCMS/Orchard into 1.10.x

commit c1b1c4dc06
Merge: bf2201c e50bd60
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Tue Oct 25 09:19:54 2016 +0200

    Merge remote-tracking branch 'remotes/Laser.Orchard/feature/6196_SupportForAttachments' into 1.10.x

commit e50bd607b7
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Tue Oct 25 09:18:24 2016 +0200

    - Formatted Code (Rebracer)

commit f6cfe324b1
Merge: 7a16cf5 bf2201c
Author: matteo.piovanelli <matteo.piovanelli@laser-group.com>
Date:   Mon Oct 24 09:24:57 2016 +0200

    Merge remote-tracking branch 'remotes/Laser.Orchard/1.10.x' into 1.10.x
    Ho fatto pull della 1.10 remota di Orchard

commit bf2201c2a9
Merge: 67af300 580b79c
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 21 18:40:21 2016 +0200

    Merge branch 'feature/6196_SupportForAttachments' into 1.10.x

    # Conflicts:
    #	src/Orchard.Web/Modules/Orchard.Email/Services/SmtpMessageChannel.cs

commit 580b79c24d
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 21 11:46:08 2016 +0200

    - Added attachments logic

commit 67af300783
Merge: d4d4a32 a4c816b
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 21 11:56:13 2016 +0200

    Merge branch 'feature/6196_SupportForAttachments' into 1.10.x

commit a4c816b291
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 21 11:55:38 2016 +0200

    - missing Attachments Key fix

commit d4d4a322bc
Merge: 297e586 2bb81ee
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 21 11:46:40 2016 +0200

    Merge branch 'feature/6196_SupportForAttachments' into 1.10.x

commit 2bb81eef31
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 21 11:46:08 2016 +0200

    - Added attachments logic

commit 297e586a19
Merge: 54a1bdf 548b5d7
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 21 09:39:11 2016 +0200

    Merge branch 'feature/5790_partecipate_in_cache_key_generation' into 1.10.x

commit 548b5d7d8f
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Fri Oct 21 09:37:07 2016 +0200

    - Method renamed
    - try catch removed

commit 54a1bdf03a
Merge: b7ee130 794b9b0
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 19 17:51:29 2016 +0200

    Merge remote-tracking branch 'remotes/Laser.Orchard/feature/5790_partecipate_in_cache_key_generation' into 1.10.x

commit 794b9b0252
Merge: 1dcee8a 350cbbd
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 19 17:44:35 2016 +0200

    Merge branch 'feature/5790_partecipate_in_cache_key_generation' of https://github.com/LaserSrl/Orchard into feature/5790_partecipate_in_cache_key_generation

commit 1dcee8aae8
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 19 16:30:12 2016 +0200

    - typo chaching > caching

    - added EventHandler in order to partecipate in cachekey generation

commit 350cbbd183
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 19 17:40:58 2016 +0200

    - typo chaching > caching

commit b7ee130847
Merge: c9e14f9 58e59e2
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 19 16:32:13 2016 +0200

    Merge remote-tracking branch 'remotes/Laser.Orchard/feature/5790_partecipate_in_cache_key_generation' into 1.10.x

commit 58e59e2fca
Author: HermesSbicego-Laser <hermes.sbicego@laser-group.com>
Date:   Wed Oct 19 16:30:12 2016 +0200

    - added EventHandler in order to partecipate in cachekey generation

commit c9e14f9b82
Author: matteo.piovanelli <matteo.piovanelli@laser-group.com>
Date:   Mon Oct 17 12:54:53 2016 +0200

    Modified the OutputCache Module based on the enhancement proposed in Issue 5811,
    by adding a VaryByRequestCookies property to the CacheSettingsPart to enable the generation of the Cache Key based on cookies

* Changed the view as reccomended by @sebastienros in his comments

* Added culture information to the contentpickerfield editor view

* Fixed a bug in the handler (!= instead of ==)

* showing displaytext in warnings and notifications rather than content item's id

* Cleanup. I
ContentPickerFieldLocalizationDriver Editor methods are executed correctly on validation errors, so they load the additional javascript correctly
This commit is contained in:
Matteo Piovanelli 2016-11-17 21:47:58 +01:00 committed by Sébastien Ros
parent 1254a11b8d
commit f697fbb06a
9 changed files with 300 additions and 0 deletions

View File

@ -0,0 +1,44 @@
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentPicker.Fields;
using Orchard.ContentPicker.ViewModels;
using Orchard.Environment.Extensions;
namespace Orchard.ContentPicker.Drivers {
[OrchardFeature("Orchard.ContentPicker.LocalizationExtensions")]
public class ContentPickerFieldLocalizationDriver : ContentFieldDriver<Fields.ContentPickerField> {
private readonly IContentManager _contentManager;
public ContentPickerFieldLocalizationDriver(IContentManager contentManager) {
_contentManager = contentManager;
}
private static string GetPrefix(Fields.ContentPickerField field, ContentPart part) {
return part.PartDefinition.Name + "." + field.Name;
}
private static string GetDifferentiator(Fields.ContentPickerField field, ContentPart part) {
return field.Name;
}
protected override DriverResult Editor(ContentPart part, Fields.ContentPickerField field, dynamic shapeHelper) {
return ContentShape("Fields_ContentPickerLocalization_Edit", GetDifferentiator(field, part),
() => {
var model = new ContentPickerFieldViewModel {
Field = field,
Part = part,
ContentItems = _contentManager.GetMany<ContentItem>(field.Ids, VersionOptions.Latest, QueryHints.Empty).ToList()
};
model.SelectedIds = string.Join(",", field.Ids);
return shapeHelper.EditorTemplate(TemplateName: "Fields/ContentPickerLocalization.Edit", Model: model, Prefix: GetPrefix(field, part));
});
}
protected override DriverResult Editor(ContentPart part, ContentPickerField field, IUpdateModel updater, dynamic shapeHelper) {
return Editor(part, field, shapeHelper);
}
}
}

View File

@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.ContentPicker.Fields;
using Orchard.ContentPicker.Settings;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Localization.Models;
using Orchard.Localization.Services;
using Orchard.UI.Notify;
namespace Orchard.ContentPicker.Handlers {
[OrchardFeature("Orchard.ContentPicker.LocalizationExtensions")]
public class ContentPickerFieldLocalizationExtensionHandler : ContentHandler {
private readonly IOrchardServices _orchardServices;
private readonly IContentManager _contentManager;
private readonly ILocalizationService _localizationService;
public Localizer T { get; set; }
public ContentPickerFieldLocalizationExtensionHandler(
IOrchardServices orchardServices,
IContentManager contentManager,
ILocalizationService localizationService) {
_orchardServices = orchardServices;
_contentManager = contentManager;
_localizationService = localizationService;
T = NullLocalizer.Instance;
}
protected override void UpdateEditorShape(UpdateEditorContext context) {
base.UpdateEditorShape(context);
//Here we implement the logic based on the settings introduced in ContentPickerFieldLocalizationSettings
//These settings should only be active if the ContentItem that is being updated has a LocalizationPart
if (context.ContentItem.Parts.Any(part => part is LocalizationPart)) {
var lPart = (LocalizationPart)context.ContentItem.Parts.Single(part => part is LocalizationPart);
var fields = context.ContentItem.Parts.SelectMany(x => x.Fields.Where(f => f.FieldDefinition.Name == typeof(ContentPickerField).Name)).Cast<ContentPickerField>();
foreach (var field in fields) {
var settings = field.PartFieldDefinition.Settings.GetModel<ContentPickerFieldLocalizationSettings>();
if (settings.TryToLocalizeItems) {
//try to replace items in the field with their translation
var itemsInField = _contentManager.GetMany<ContentItem>(field.Ids, VersionOptions.Published, QueryHints.Empty);
if (settings.RemoveItemsWithNoLocalizationPart && itemsInField.Where(ci => !ci.Parts.Any(part => part is LocalizationPart)).Any()) {
//keep only items that have a LocalizationPart
_orchardServices.Notifier.Warning(T(
"{0}: The following items could have no localization, so they were removed: {1}",
field.DisplayName,
string.Join(", ", itemsInField.Where(ci => !ci.Parts.Any(part => part is LocalizationPart)).Select(ci => _contentManager.GetItemMetadata(ci).DisplayText))
));
itemsInField = itemsInField.Where(ci => ci.Parts.Any(part => part is LocalizationPart));
}
//use an (int, int) tuple to track translations
var newIds = itemsInField.Select(ci => {
if (ci.Parts.Any(part => part is LocalizationPart)) {
if (_localizationService.GetContentCulture(ci) == lPart.Culture.Culture)
return new Tuple<int, int>(ci.Id, ci.Id); //this item is fine
var localized = _localizationService.GetLocalizations(ci).FirstOrDefault(lp => lp.Culture == lPart.Culture);
return localized == null ? new Tuple<int, int>(ci.Id, -ci.Id) : new Tuple<int, int>(ci.Id, localized.Id); //return negative id where we found no translation
}
else {
//we only go here if RemoveItemsWithNoLocalizationPart == false
return new Tuple<int, int>(ci.Id, ci.Id);
}
});
if (newIds.Any(tup => tup.Item2 < 0)) {
if (settings.RemoveItemsWithoutLocalization) {
//remove the items for which we could not find a localization
_orchardServices.Notifier.Warning(T(
"{0}: We could not find a localization for the following items, so they were removed: {1}",
field.DisplayName,
string.Join(", ", newIds.Where(tup => tup.Item2 < 0).Select(tup => _contentManager.GetItemMetadata(_contentManager.GetLatest(tup.Item1)).DisplayText))
));
newIds = newIds.Where(tup => tup.Item2 > 0);
}
else {
//negative Ids are made positive again
newIds = newIds.Select(tup => tup = new Tuple<int, int>(tup.Item1, Math.Abs(tup.Item2)));
}
}
if (newIds.Where(tup => tup.Item1 != tup.Item2).Any()) {
_orchardServices.Notifier.Warning(T(
"{0}: The following items were replaced by their correct localization: {1}",
field.DisplayName,
string.Join(", ", newIds.Where(tup => tup.Item1 != tup.Item2).Select(tup => _contentManager.GetItemMetadata(_contentManager.GetLatest(tup.Item1)).DisplayText))
));
}
field.Ids = newIds.Select(tup => tup.Item2).Distinct().ToArray();
}
if (settings.AssertItemsHaveSameCulture) {
//verify that the items in the ContentPickerField are all in the culture of the ContentItem whose editor we are updating
var itemsInField = _contentManager.GetMany<ContentItem>(field.Ids, VersionOptions.Published, QueryHints.Empty);
var itemsWithoutLocalizationPart = itemsInField.Where(ci => !ci.Parts.Any(part => part is LocalizationPart));
List<int> badItemIds = itemsInField.Where(ci => ci.Parts.Any(part => part is LocalizationPart && ((LocalizationPart)part).Culture != lPart.Culture)).Select(ci => ci.Id).ToList();
if (itemsWithoutLocalizationPart.Count() > 0) {
//Verify items from the ContentPickerField that cannot be localized
_orchardServices.Notifier.Warning(T("{0}: Some of the selected items cannot be localized: {1}",
field.DisplayName,
string.Join(", ", itemsWithoutLocalizationPart.Select(ci => _contentManager.GetItemMetadata(ci).DisplayText))
));
if (settings.BlockForItemsWithNoLocalizationPart) {
badItemIds.AddRange(itemsWithoutLocalizationPart.Select(ci => ci.Id));
}
}
if (badItemIds.Count > 0) {
context.Updater.AddModelError(field.DisplayName, T("Some of the items selected have the wrong localization: {0}",
string.Join(", ", badItemIds.Select(id => _contentManager.GetItemMetadata(_contentManager.GetLatest(id)).DisplayText))
));
}
}
}
}
}
}
}

View File

@ -10,3 +10,8 @@ Features:
Description: UI for selecting Content Items.
Dependencies: Contents, Navigation
Category: Input Editor
Orchard.ContentPicker.LocalizationExtensions:
Name: Orchard.ContentPicker.LocalizationExtensions
Description: Provides settings to enable advanced localization behaviours for ContentPickerFields.
Dependencies: Orchard.ContentPicker, Orchard.Localization, Orchard.Resources
Category: Input Editor

View File

@ -98,6 +98,10 @@
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="Drivers\ContentPickerFieldLocalizationDriver.cs" />
<Compile Include="Handlers\ContentPickerFieldLocalizationExtensionHandler.cs" />
<Compile Include="Settings\ContentPickerFieldLocalizationEditorEvents.cs" />
<Compile Include="Settings\ContentPickerFieldLocalizationSettings.cs" />
<Compile Include="ViewModels\NavigationPartViewModel.cs" />
<Content Include="Scripts\ContentPicker.js" />
<Content Include="Scripts\SelectableContentTab.js" />
@ -182,6 +186,10 @@
<Name>Orchard.Core</Name>
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\Orchard.Localization\Orchard.Localization.csproj">
<Project>{fbc8b571-ed50-49d8-8d9d-64ab7454a0d6}</Project>
<Name>Orchard.Localization</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Views\ContentPicker.Edit.cshtml" />
@ -189,6 +197,12 @@
<ItemGroup>
<Content Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\DefinitionTemplates\ContentPickerFieldLocalizationSettings.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Fields\ContentPickerLocalization.Edit.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@ -1,5 +1,6 @@
<Placement>
<Place Fields_ContentPicker_Edit="Content:2.3"/>
<Place Fields_ContentPickerLocalization_Edit="Content:2.3"/>
<Place Parts_Navigation_Edit="Content:10"/>
<Place Parts_ContentMenuItem_Edit="Content:10"/>

View File

@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Globalization;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.ContentManagement.ViewModels;
using Orchard.Environment.Extensions;
namespace Orchard.ContentPicker.Settings {
[OrchardFeature("Orchard.ContentPicker.LocalizationExtensions")]
public class ContentPickerFieldLocalizationEditorEvents : ContentDefinitionEditorEventsBase {
public override IEnumerable<TemplateViewModel> PartFieldEditor(ContentPartFieldDefinition definition) {
if (definition.FieldDefinition.Name == "ContentPickerField") {
var model = definition.Settings.GetModel<ContentPickerFieldLocalizationSettings>();
yield return DefinitionTemplate(model);
}
}
public override IEnumerable<TemplateViewModel> PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) {
if (builder.FieldType != "ContentPickerField") {
yield break;
}
var model = new ContentPickerFieldLocalizationSettings();
if (updateModel.TryUpdateModel(model, "ContentPickerFieldLocalizationSettings", null, null)) {
builder.WithSetting("ContentPickerFieldLocalizationSettings.TryToLocalizeItems", model.TryToLocalizeItems.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("ContentPickerFieldLocalizationSettings.RemoveItemsWithoutLocalization", model.RemoveItemsWithoutLocalization.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("ContentPickerFieldLocalizationSettings.RemoveItemsWithNoLocalizationPart", model.RemoveItemsWithNoLocalizationPart.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("ContentPickerFieldLocalizationSettings.AssertItemsHaveSameCulture", model.AssertItemsHaveSameCulture.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("ContentPickerFieldLocalizationSettings.BlockForItemsWithNoLocalizationPart", model.BlockForItemsWithNoLocalizationPart.ToString(CultureInfo.InvariantCulture));
}
yield return DefinitionTemplate(model);
}
}
}

View File

@ -0,0 +1,16 @@
using Orchard.Environment.Extensions;
namespace Orchard.ContentPicker.Settings {
[OrchardFeature("Orchard.ContentPicker.LocalizationExtensions")]
public class ContentPickerFieldLocalizationSettings {
public ContentPickerFieldLocalizationSettings() {
TryToLocalizeItems = true;
}
public bool TryToLocalizeItems { get; set; }
public bool RemoveItemsWithoutLocalization { get; set; }
public bool RemoveItemsWithNoLocalizationPart { get; set; }
public bool AssertItemsHaveSameCulture { get; set; }
public bool BlockForItemsWithNoLocalizationPart { get; set; }
}
}

View File

@ -0,0 +1,24 @@
@model Orchard.ContentPicker.Settings.ContentPickerFieldLocalizationSettings
<fieldset>
@Html.CheckBoxFor(m => m.TryToLocalizeItems)
<label for="@Html.FieldIdFor(m => m.TryToLocalizeItems)" class="forcheckbox">@T("Try to replace selected items with their correct localization.")</label>
<span class="hint">@T("Check to attempt to replace items selected in this field with their translation in the main ContentItem's culture. This only applies if the main ContentItem has a LocalizationPart.")</span>
<div data-controllerid="@Html.FieldIdFor(m => m.TryToLocalizeItems)">
@Html.CheckBoxFor(m => m.RemoveItemsWithoutLocalization)
<label for="@Html.FieldIdFor(m => m.RemoveItemsWithoutLocalization)" class="forcheckbox">@T("Remove items that do not have the correct translation.")</label>
<span class="hint">@T("Check to remove items from the ContentPickerField when the items selected do not have a version in the correct culture (they have a LocalizationPart, but not a translation in the main ContentItem's culture').")</span>
@Html.CheckBoxFor(m => m.RemoveItemsWithNoLocalizationPart)
<label for="@Html.FieldIdFor(m => m.RemoveItemsWithNoLocalizationPart)" class="forcheckbox">@T("Remove items that cannot be localized.")</label>
<span class="hint">@T("Check to remove items from the ContentPickerField when the items selected cannot be localized (do not have a LocalizationPart).")</span>
</div>
@Html.CheckBoxFor(m => m.AssertItemsHaveSameCulture)
<label for="@Html.FieldIdFor(m => m.AssertItemsHaveSameCulture)" class="forcheckbox">@T("Verify culture of selected items.")</label>
<span class="hint">@T("Check to prevent publication of contents when the items selected have a different culture. This only applies if the main ContentItem has a LocalizationPart.")</span>
<div data-controllerid="@Html.FieldIdFor(m => m.AssertItemsHaveSameCulture)">
@Html.CheckBoxFor(m => m.BlockForItemsWithNoLocalizationPart)
<label for="@Html.FieldIdFor(m => m.BlockForItemsWithNoLocalizationPart)" class="forcheckbox">@T("Do not admit items that cannot be localized.")</label>
<span class="hint">@T("Check to stop publication of contents when the items selected cannot be localized (do not have a LocalizationPart).")</span>
</div>
</fieldset>

View File

@ -0,0 +1,39 @@
@model Orchard.ContentPicker.ViewModels.ContentPickerFieldViewModel
@using Orchard.ContentPicker.Settings;
@using Orchard.Localization.Models;
@using Orchard.ContentManagement;
@{
Script.Require("jQuery").AtFoot();
var settings = Model.Field.PartFieldDefinition.Settings.GetModel<ContentPickerFieldLocalizationSettings>();
string tryTranslateMsg = T("Selected items with a localization different than the current one will be localized.").Text;
string removeMissingMsg = T("Selected items for which there is no correct localization will be removed.").Text;
string removeUnlocalizableMsg = T("Selected items that cannot have localizations will be removed.").Text;
if (settings.RemoveItemsWithoutLocalization) { tryTranslateMsg += " " + removeMissingMsg; }
if (settings.RemoveItemsWithNoLocalizationPart) { tryTranslateMsg += " " + removeUnlocalizableMsg; }
//We will use a script to find the fieldset for the field we are currently processing.
//The fieldset contains a span of class "hint". We will add tryTranslateMsg to it.
string dataPartName = HttpUtility.JavaScriptStringEncode(Model.Part.PartDefinition.Name);
string dataFieldName = HttpUtility.JavaScriptStringEncode(Model.Field.PartFieldDefinition.Name);
}
@using (Script.Foot()) {
<script type="text/javascript">
$(function () {
$("fieldset[data-part-name='@dataPartName'][data-field-name='@dataFieldName']").find("span.hint")[0].innerText += "@tryTranslateMsg";
});
@foreach (var contentItem in Model.ContentItems) {
var loc = contentItem.As<LocalizationPart>();
if (loc != null && loc.Culture!=null && !string.IsNullOrWhiteSpace(loc.Culture.Culture)) {
<text>
$(function () {
$("span[data-id='@contentItem.Id'][data-fieldid='@Html.FieldIdFor(m => m.Field.Ids)'].content-picker-item")[0].append(" (@loc.Culture.Culture)");
})
</text>
}
}
</script>
}