Skip to content

Commit f3e4618

Browse files
committed
Enable nested fallback with language processors
1 parent bbf7477 commit f3e4618

File tree

3 files changed

+98
-71
lines changed

3 files changed

+98
-71
lines changed

src/Processors.Globalization/App_Config/Include/FieldFallback_02.config

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
The field is translated from the value on the 'masterLanguageName' version to the current language.
2424
The text can only be translated to one of the listed 'supportedLanguages'
2525
TranslationService is an implementation of the `FieldFallback.Processors.Translation.ITranslationService, FieldFallback.Processors.Globalization` interface.
26-
There is an implementation provided that uses the Microsoft/Azure Translation Service. https://datamarket.azure.com/dataset/bing/microsofttranslator
27-
* Please input your account key
26+
There is an implementation provided that uses the Microsoft/Azure Translation Service. https://datamarket.azure.com/dataset/bing/microsofttranslator
27+
* Please input your account key
28+
EnableNestedFallback - In certain scenarios a field may be configured with multiple fallback processors.
29+
For instance, AncestorFallback. Should the Ancestor value be determined before translation happens?
2830

2931
Usage:
3032
Each field definition has an "EnableTranslation" field. Set to 'true'.
@@ -34,6 +36,7 @@
3436
<processor type="FieldFallback.Processors.TranslationProcessor, FieldFallback.Processors.Globalization">
3537
<param name="masterLanguageName" desc="The character code for the master language that is the source of all translation">en</param>
3638
<param name="supportedLanguages" desc="The list of languages that can be translated">ar,bg,ca,cs,da,de,el,en,es,et,fa,fi,fr,he,hi,ht,hu,id,it,ja,ko,lt,lv,ms,mww,nl,no,pl,pt,ro,ru,sk,sl,sv,th,tr,uk,ur,vi,zh-CHS,zh-CHT</param>
39+
<EnableNestedFallback>true</EnableNestedFallback>
3740
<TranslationService type="FieldFallback.Processors.Translation.MicrosoftTranslator, FieldFallback.Processors.Globalization">
3841
<param name="accountKey" desc="The Account Key for the Microsoft Translation service">** YOUR KEY HERE **</param>
3942
</TranslationService>
@@ -45,7 +48,9 @@
4548
-->
4649
<!--
4750
<processor patch:before="*[1]"
48-
type="FieldFallback.Processors.Globalization.PartialLanguageFallbackProcessor, FieldFallback.Processors.Globalization" />
51+
type="FieldFallback.Processors.Globalization.PartialLanguageFallbackProcessor, FieldFallback.Processors.Globalization">
52+
<EnableNestedFallback>true</EnableNestedFallback>
53+
</processor>
4954
-->
5055
</fieldFallback>
5156
</pipelines>
Lines changed: 78 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,78 @@
1-
using System.Collections.Generic;
2-
using FieldFallback.Pipelines.FieldFallbackPipeline;
3-
using FieldFallback.Processors.Globalization.Data.Fields;
4-
using Sitecore.Data;
5-
using Sitecore.Data.Fields;
6-
using Sitecore.Data.Items;
7-
using Sitecore.Diagnostics;
8-
using Sitecore.Globalization;
9-
10-
namespace FieldFallback.Processors.Globalization
11-
{
12-
public class PartialLanguageFallbackProcessor : FieldFallbackProcessor
13-
{
14-
protected override bool IsEnabledForField(Field field)
15-
{
16-
TemplateFallbackFieldItem fallbackField = field;
17-
return (fallbackField != null && fallbackField.EnableLanguageFallback);
18-
}
19-
20-
protected override string GetFallbackValue(FieldFallbackPipelineArgs args)
21-
{
22-
Assert.IsNotNull(args.Field, "Field is null");
23-
24-
if (IsEnabledForField(args.Field))
25-
{
26-
Item fallbackItem = GetFallbackItem(args.Field);
27-
28-
if (fallbackItem != null)
29-
{
30-
// Get field's value from the fallback item
31-
return fallbackItem.Fields[args.Field.ID].GetValueSafe(true, true, false);
32-
}
33-
}
34-
return null;
35-
}
36-
37-
/// <summary>
38-
/// Gets the fallback item that has a version with a value for the field.
39-
/// </summary>
40-
/// <param name="field">The field.</param>
41-
/// <returns></returns>
42-
private Item GetFallbackItem(Field field)
43-
{
44-
Item item = field.Item;
45-
Database database = field.Database;
46-
Language language = field.Language;
47-
48-
Item fallbackItem = null;
49-
50-
// get the fallback languages
51-
IEnumerable<Language> fallbackLanguages = language.GetFallbackLanguages(database);
52-
53-
foreach (Language fallbackLanguage in fallbackLanguages)
54-
{
55-
fallbackItem = database.GetItem(item.ID, fallbackLanguage);
56-
57-
// first fallback item in the chain of fallback languages with a value wins
58-
if (fallbackItem != null && fallbackItem.Versions.Count > 0 && DoesItemHaveFieldWithValue(fallbackItem, field.ID, true))
59-
{
60-
break;
61-
}
62-
}
63-
64-
return fallbackItem;
65-
}
66-
}
67-
}
1+
using System.Collections.Generic;
2+
using FieldFallback.Pipelines.FieldFallbackPipeline;
3+
using FieldFallback.Processors.Globalization.Data.Fields;
4+
using Sitecore.Data;
5+
using Sitecore.Data.Fields;
6+
using Sitecore.Data.Items;
7+
using Sitecore.Diagnostics;
8+
using Sitecore.Globalization;
9+
10+
namespace FieldFallback.Processors.Globalization
11+
{
12+
public class PartialLanguageFallbackProcessor : FieldFallbackProcessor
13+
{
14+
/// <summary>
15+
/// Should a fallback value fallback to a language?
16+
/// <remarks>
17+
/// In certain scenarios a field may be configured with multiple fallback
18+
/// processors. If enabled, then when the source fields are checked for a value
19+
/// they will be checked using their fallback values.
20+
/// This could be problematic/inefficient with certain configurations.
21+
/// </remarks>
22+
/// </summary>
23+
public bool EnableNestedFallback { get; set; }
24+
25+
protected override bool IsEnabledForField(Field field)
26+
{
27+
TemplateFallbackFieldItem fallbackField = field;
28+
return (fallbackField != null && fallbackField.EnableLanguageFallback);
29+
}
30+
31+
protected override string GetFallbackValue(FieldFallbackPipelineArgs args)
32+
{
33+
Assert.IsNotNull(args.Field, "Field is null");
34+
35+
if (IsEnabledForField(args.Field))
36+
{
37+
Item fallbackItem = GetFallbackItem(args.Field);
38+
39+
if (fallbackItem != null)
40+
{
41+
// Get field's value from the fallback item
42+
return fallbackItem.Fields[args.Field.ID].GetValueSafe(true, true, EnableNestedFallback);
43+
}
44+
}
45+
return null;
46+
}
47+
48+
/// <summary>
49+
/// Gets the fallback item that has a version with a value for the field.
50+
/// </summary>
51+
/// <param name="field">The field.</param>
52+
/// <returns></returns>
53+
private Item GetFallbackItem(Field field)
54+
{
55+
Item item = field.Item;
56+
Database database = field.Database;
57+
Language language = field.Language;
58+
59+
Item fallbackItem = null;
60+
61+
// get the fallback languages
62+
IEnumerable<Language> fallbackLanguages = language.GetFallbackLanguages(database);
63+
64+
foreach (Language fallbackLanguage in fallbackLanguages)
65+
{
66+
fallbackItem = database.GetItem(item.ID, fallbackLanguage);
67+
68+
// first fallback item in the chain of fallback languages with a value wins
69+
if (fallbackItem != null && fallbackItem.Versions.Count > 0 && DoesItemHaveFieldWithValue(fallbackItem, field.ID, true))
70+
{
71+
break;
72+
}
73+
}
74+
75+
return fallbackItem;
76+
}
77+
}
78+
}

src/Processors.Globalization/TranslationProcessor.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ public class TranslationProcessor : FieldFallbackProcessor
2222
/// </summary>
2323
public ITranslationService TranslationService { get; set; }
2424

25+
/// <summary>
26+
/// Should a fallback value be translated?
27+
/// <remarks>
28+
/// In certain scenarios a field may be configured with multiple fallback
29+
/// processors. If enabled, then when the source fields are checked for a value
30+
/// they will be checked using their fallback values.
31+
/// This could be problematic/inefficient with certain configurations.
32+
/// </remarks>
33+
/// </summary>
34+
public bool EnableNestedFallback { get; set; }
35+
2536
/// <summary>
2637
/// The master language to use as the source for translation
2738
/// </summary>
@@ -62,7 +73,7 @@ protected override string GetFallbackValue(FieldFallbackPipelineArgs args)
6273
if (masterItem != null)
6374
{
6475
// Get the value of the field, from the master item, so we can translate it
65-
string translateMe = masterItem.Fields[args.Field.ID].GetValueSafe(true, false, false);
76+
string translateMe = masterItem.Fields[args.Field.ID].GetValueSafe(true, false, EnableNestedFallback);
6677

6778
// Call the translation service
6879
fieldValue = TranslationService.Translate(translateMe, _masterLanguage.CultureInfo, args.Field.Language.CultureInfo);

0 commit comments

Comments
 (0)