From f697fbb06ac03ba1cc7cedf10d36b3c599c35cd5 Mon Sep 17 00:00:00 2001 From: Matteo Piovanelli Date: Thu, 17 Nov 2016 21:47:58 +0100 Subject: [PATCH] Implements ContentPicker localization options discussed in #7352 (#7391) * Squashed commit of the following: commit bd1e2bf3d386a1d6f12a5d062639929a17ba6c46 Author: matteo.piovanelli 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 Date: Wed Nov 9 17:48:59 2016 +0100 Added the TryTranslate option and its suboptions commit fad9fa87f3f3a8c555d088e8971dd04a337cf4dc Author: matteo.piovanelli 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 b90629dc3e2fe5092d247ef24bb5c49f2c9ba066 Merge: 578b21b c486355 Author: matteo.piovanelli 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 578b21b75ec4ad0ac7ee0808fd254ea3ee4dfa8d Merge: 395976f 3c53ffb Author: HermesSbicego-Laser Date: Fri Nov 4 13:45:51 2016 +0100 Merge branch 'feature/6688_RequestTokens_Chaintext' into Laser/1.10.x commit 3c53ffb09a923c5eccf571f4f8be68c76de10d1f Author: HermesSbicego-Laser 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 395976fa60828e574563416d8e060ba23c628672 Merge: 708ed79 a15557e Author: HermesSbicego-Laser 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 708ed79ccb5a6b1075bd0c22c2f58d92d5032ee1 Merge: 5fe0b69 68acf26 Author: HermesSbicego-Laser 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 5fe0b69c6bc904a29debc93f8a175a6bf23d899d Merge: 0daad70 e3a7059 Author: HermesSbicego-Laser Date: Fri Oct 28 16:32:31 2016 +0200 Merge branch 'feature/6196_SupportForAttachments' into Laser/1.10.x commit e3a7059edf212b6bffcafe2076f3da45487d0260 Author: HermesSbicego-Laser 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 f095dea5e5ecbf7a7f62bf03895d4a78f430c90b Merge: 7b09747 68acf26 Author: HermesSbicego-Laser 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 a15557e5f3f23b59d3a1b1aa1b520942a3127bd4 Merge: 0daad70 ce8a61e Author: matteo.piovanelli Date: Thu Oct 27 17:10:53 2016 +0200 Merge branch 'issues/7346_WidgetsViewQueryString' into Laser/1.10.x commit 0daad702192b6286714f29212dc8fee50e76542f Merge: 927d18b 7b09747 Author: HermesSbicego-Laser 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 7b09747fc9eaea71f653365e81d00cf2d82e964d Author: HermesSbicego-Laser Date: Thu Oct 27 09:05:17 2016 +0200 inserted a better explanation on how to use the chains commit 927d18b1c2b81cf69e5b33ce46c503f5e6b183e2 Merge: f8cbc63 17ebdd2 Author: HermesSbicego-Laser 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 17ebdd2bfc53c7028aa71d36443b11942ac2a320 Author: HermesSbicego-Laser Date: Wed Oct 26 18:57:48 2016 +0200 - typo commit f8cbc63fc03fda1bc47209a1849a1e287d698c4f Merge: 9f42664 1b511b2 Author: HermesSbicego-Laser Date: Wed Oct 26 18:53:11 2016 +0200 Merge branch 'feature/6688_RequestTokens_Chaintext' into 1.10.x commit 1b511b2692d1890b658b13f9dfd32f5caca3da09 Author: HermesSbicego-Laser Date: Wed Oct 26 18:50:35 2016 +0200 - Implement what described in #6688 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 ce8a61ed86f66a50c67adce24c6d84440cc61787 Author: matteo.piovanelli Date: Wed Oct 26 11:46:24 2016 +0200 Fixes #7346 commit 9f4266401a9c06bc8426c73055a6b5257c7b15bb Merge: 60aa1cc f6cfe32 Author: HermesSbicego-Laser 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 60aa1cc2f4f45a06de6a4416eeb9f0726697d11e Merge: c1b1c4d 7a16cf5 Author: HermesSbicego-Laser 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 c1b1c4dc06b6c941f5f7eced5a81ed30bd5d66fa Merge: bf2201c e50bd60 Author: HermesSbicego-Laser Date: Tue Oct 25 09:19:54 2016 +0200 Merge remote-tracking branch 'remotes/Laser.Orchard/feature/6196_SupportForAttachments' into 1.10.x commit e50bd607b7f8e4047bf2a2c58fd31cf626aa198e Author: HermesSbicego-Laser Date: Tue Oct 25 09:18:24 2016 +0200 - Formatted Code (Rebracer) commit f6cfe324b1a393b1b4b192577ed5211f91f8285c Merge: 7a16cf5 bf2201c Author: matteo.piovanelli 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 bf2201c2a9a05fcdc9467eca8023a7209c0b6298 Merge: 67af300 580b79c Author: HermesSbicego-Laser 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 580b79c24db2da9b7d97039b4fd6db03412fb5c6 Author: HermesSbicego-Laser Date: Fri Oct 21 11:46:08 2016 +0200 - Added attachments logic commit 67af300783983bd823f059bfaf91b7975157ab81 Merge: d4d4a32 a4c816b Author: HermesSbicego-Laser Date: Fri Oct 21 11:56:13 2016 +0200 Merge branch 'feature/6196_SupportForAttachments' into 1.10.x commit a4c816b29180dde88964e9d55207efd73de4d561 Author: HermesSbicego-Laser Date: Fri Oct 21 11:55:38 2016 +0200 - missing Attachments Key fix commit d4d4a322bc432198068c6c96ad8b4768ca8af7d0 Merge: 297e586 2bb81ee Author: HermesSbicego-Laser Date: Fri Oct 21 11:46:40 2016 +0200 Merge branch 'feature/6196_SupportForAttachments' into 1.10.x commit 2bb81eef31b092c8f78b19d9e8f21300d32cf3ba Author: HermesSbicego-Laser Date: Fri Oct 21 11:46:08 2016 +0200 - Added attachments logic commit 297e586a19853f709e66691ad390adfced23807a Merge: 54a1bdf 548b5d7 Author: HermesSbicego-Laser Date: Fri Oct 21 09:39:11 2016 +0200 Merge branch 'feature/5790_partecipate_in_cache_key_generation' into 1.10.x commit 548b5d7d8fd95982cc04adc42272152ec327d1c0 Author: HermesSbicego-Laser Date: Fri Oct 21 09:37:07 2016 +0200 - Method renamed - try catch removed commit 54a1bdf03aba22032c4cfbd7e56a3f924d426f2e Merge: b7ee130 794b9b0 Author: HermesSbicego-Laser 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 794b9b025227339f6cf840c58b54ea5d4cd1eb0e Merge: 1dcee8a 350cbbd Author: HermesSbicego-Laser 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 1dcee8aae85741975c6589664acbfd80f92514f8 Author: HermesSbicego-Laser Date: Wed Oct 19 16:30:12 2016 +0200 - typo chaching > caching - added EventHandler in order to partecipate in cachekey generation commit 350cbbd183414a41cf0886967c918d9482e47fea Author: HermesSbicego-Laser Date: Wed Oct 19 17:40:58 2016 +0200 - typo chaching > caching commit b7ee130847b44df2c5fde8469e73ddc061f5ed19 Merge: c9e14f9 58e59e2 Author: HermesSbicego-Laser 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 58e59e2fca8d9d672d45dee661e11b9a7616dc19 Author: HermesSbicego-Laser Date: Wed Oct 19 16:30:12 2016 +0200 - added EventHandler in order to partecipate in cachekey generation commit c9e14f9b82c05f96bb6cef494099103aacf7758b Author: matteo.piovanelli 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 --- .../ContentPickerFieldLocalizationDriver.cs | 44 +++++++ ...PickerFieldLocalizationExtensionHandler.cs | 119 ++++++++++++++++++ .../Modules/Orchard.ContentPicker/Module.txt | 5 + .../Orchard.ContentPicker.csproj | 14 +++ .../Orchard.ContentPicker/Placement.info | 1 + ...tentPickerFieldLocalizationEditorEvents.cs | 38 ++++++ .../ContentPickerFieldLocalizationSettings.cs | 16 +++ ...tentPickerFieldLocalizationSettings.cshtml | 24 ++++ .../ContentPickerLocalization.Edit.cshtml | 39 ++++++ 9 files changed, 300 insertions(+) create mode 100644 src/Orchard.Web/Modules/Orchard.ContentPicker/Drivers/ContentPickerFieldLocalizationDriver.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentPicker/Handlers/ContentPickerFieldLocalizationExtensionHandler.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentPicker/Settings/ContentPickerFieldLocalizationEditorEvents.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentPicker/Settings/ContentPickerFieldLocalizationSettings.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ContentPicker/Views/DefinitionTemplates/ContentPickerFieldLocalizationSettings.cshtml create mode 100644 src/Orchard.Web/Modules/Orchard.ContentPicker/Views/EditorTemplates/Fields/ContentPickerLocalization.Edit.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Drivers/ContentPickerFieldLocalizationDriver.cs b/src/Orchard.Web/Modules/Orchard.ContentPicker/Drivers/ContentPickerFieldLocalizationDriver.cs new file mode 100644 index 00000000000..1f56bafebf9 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Drivers/ContentPickerFieldLocalizationDriver.cs @@ -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 { + 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(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); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Handlers/ContentPickerFieldLocalizationExtensionHandler.cs b/src/Orchard.Web/Modules/Orchard.ContentPicker/Handlers/ContentPickerFieldLocalizationExtensionHandler.cs new file mode 100644 index 00000000000..7b604f2f10b --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Handlers/ContentPickerFieldLocalizationExtensionHandler.cs @@ -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(); + + foreach (var field in fields) { + var settings = field.PartFieldDefinition.Settings.GetModel(); + if (settings.TryToLocalizeItems) { + //try to replace items in the field with their translation + var itemsInField = _contentManager.GetMany(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(ci.Id, ci.Id); //this item is fine + var localized = _localizationService.GetLocalizations(ci).FirstOrDefault(lp => lp.Culture == lPart.Culture); + return localized == null ? new Tuple(ci.Id, -ci.Id) : new Tuple(ci.Id, localized.Id); //return negative id where we found no translation + } + else { + //we only go here if RemoveItemsWithNoLocalizationPart == false + return new Tuple(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(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(field.Ids, VersionOptions.Published, QueryHints.Empty); + var itemsWithoutLocalizationPart = itemsInField.Where(ci => !ci.Parts.Any(part => part is LocalizationPart)); + List 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)) + )); + } + } + } + } + } + + } +} diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Module.txt b/src/Orchard.Web/Modules/Orchard.ContentPicker/Module.txt index 7bc8a95b77f..fd0def349f7 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentPicker/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Module.txt @@ -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 diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Orchard.ContentPicker.csproj b/src/Orchard.Web/Modules/Orchard.ContentPicker/Orchard.ContentPicker.csproj index 3306448051e..cc9fe0d430b 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentPicker/Orchard.ContentPicker.csproj +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Orchard.ContentPicker.csproj @@ -98,6 +98,10 @@ + + + + @@ -182,6 +186,10 @@ Orchard.Core false + + {fbc8b571-ed50-49d8-8d9d-64ab7454a0d6} + Orchard.Localization + @@ -189,6 +197,12 @@ + + + + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Placement.info b/src/Orchard.Web/Modules/Orchard.ContentPicker/Placement.info index cf849e55bc6..68d147e41f9 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentPicker/Placement.info +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Placement.info @@ -1,5 +1,6 @@  + diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Settings/ContentPickerFieldLocalizationEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.ContentPicker/Settings/ContentPickerFieldLocalizationEditorEvents.cs new file mode 100644 index 00000000000..e06cf2c167f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Settings/ContentPickerFieldLocalizationEditorEvents.cs @@ -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 PartFieldEditor(ContentPartFieldDefinition definition) { + if (definition.FieldDefinition.Name == "ContentPickerField") { + var model = definition.Settings.GetModel(); + yield return DefinitionTemplate(model); + } + } + + public override IEnumerable 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); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Settings/ContentPickerFieldLocalizationSettings.cs b/src/Orchard.Web/Modules/Orchard.ContentPicker/Settings/ContentPickerFieldLocalizationSettings.cs new file mode 100644 index 00000000000..b8aea7e4373 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Settings/ContentPickerFieldLocalizationSettings.cs @@ -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; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/DefinitionTemplates/ContentPickerFieldLocalizationSettings.cshtml b/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/DefinitionTemplates/ContentPickerFieldLocalizationSettings.cshtml new file mode 100644 index 00000000000..fbcfebf61a3 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/DefinitionTemplates/ContentPickerFieldLocalizationSettings.cshtml @@ -0,0 +1,24 @@ +@model Orchard.ContentPicker.Settings.ContentPickerFieldLocalizationSettings + +
+ @Html.CheckBoxFor(m => m.TryToLocalizeItems) + + @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.") +
+ @Html.CheckBoxFor(m => m.RemoveItemsWithoutLocalization) + + @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').") + @Html.CheckBoxFor(m => m.RemoveItemsWithNoLocalizationPart) + + @T("Check to remove items from the ContentPickerField when the items selected cannot be localized (do not have a LocalizationPart).") +
+ + @Html.CheckBoxFor(m => m.AssertItemsHaveSameCulture) + + @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.") +
+ @Html.CheckBoxFor(m => m.BlockForItemsWithNoLocalizationPart) + + @T("Check to stop publication of contents when the items selected cannot be localized (do not have a LocalizationPart).") +
+
diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/EditorTemplates/Fields/ContentPickerLocalization.Edit.cshtml b/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/EditorTemplates/Fields/ContentPickerLocalization.Edit.cshtml new file mode 100644 index 00000000000..41f232d1a76 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/EditorTemplates/Fields/ContentPickerLocalization.Edit.cshtml @@ -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(); + + 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()) { + +} \ No newline at end of file