Skip to content

Commit 52457b4

Browse files
committed
Added advanced options for Lateral Fallback
Added options for clipping text at x characters and appending an ellipsis. This requires advanced XML based config settings in the field. See code for example.
1 parent f3e4618 commit 52457b4

File tree

4 files changed

+319
-230
lines changed

4 files changed

+319
-230
lines changed

src/Processors.Sitecore.Master/sitecore/templates/System/Templates/Sections/Fallback/Fallback/__FallbackFields.item

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ templatekey: Template field
1313
field: {AB162CC0-DC80-4ABF-8871-998EE5D7BA32}
1414
name: Type
1515
key: type
16-
content-length: 15
16+
content-length: 16
1717

18-
Name Value List
18+
Single-Line Text
1919
----field----
2020
field: {BA3F86A2-4A1C-4D78-B63D-91C2779C1B5E}
2121
name: __Sortorder
@@ -87,7 +87,7 @@ sitecore\admin
8787
----version----
8888
language: en
8989
version: 1
90-
revision: b2c9b530-8aa0-4214-92c8-500bc65e5676
90+
revision: 834742a5-dab0-4afe-b861-fd1dc079fd82
9191

9292
----field----
9393
field: {19A69332-A23E-4E70-8D16-B2640CB24CC8}
@@ -144,21 +144,21 @@ name: __Revision
144144
key: __revision
145145
content-length: 36
146146

147-
b2c9b530-8aa0-4214-92c8-500bc65e5676
147+
834742a5-dab0-4afe-b861-fd1dc079fd82
148148
----field----
149149
field: {D9CF14B1-FA16-4BA6-9288-E8A174D4D522}
150150
name: __Updated
151151
key: __updated
152152
content-length: 34
153153

154-
20120702T103009:634768218094173456
154+
20130923T124654:635155372147379973
155155
----field----
156156
field: {BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}
157157
name: __Updated by
158158
key: __updated by
159159
content-length: 14
160160

161-
sitecore\Admin
161+
sitecore\admin
162162
----version----
163163
language: ja-JP
164164
version: 1

src/Processors/Data/Items/FallbackItem.cs

Lines changed: 120 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using System.Collections.Specialized;
33
using System.Linq;
4+
using System.Xml;
45
using FieldFallback.Data;
56
using Sitecore.Data;
67
using Sitecore.Data.Fields;
@@ -13,14 +14,11 @@ internal class FallbackItem : CustomItemBase
1314
{
1415
public static readonly ID FallbackFields = new ID("{8A826BE2-C878-49DA-A0F7-32DB6718E2FB}");
1516

16-
private NameValueCollection _fallbackConfiguration;
17-
private Dictionary<ID, List<Field>> _fallbackDefinition;
18-
1917
private FallbackItem(Item innerItem) : base(innerItem)
2018
{
21-
19+
Initialize();
2220
}
23-
21+
2422
public static implicit operator FallbackItem(Item item)
2523
{
2624
if (item == null)
@@ -30,7 +28,7 @@ public static implicit operator FallbackItem(Item item)
3028

3129
return new FallbackItem(item);
3230
}
33-
31+
3432
/// <summary>
3533
/// Gets a value indicating whether this item has lateral fallback configured.
3634
/// </summary>
@@ -41,58 +39,32 @@ public bool HasLateralFallback
4139
{
4240
get
4341
{
44-
return FallbackConfiguration.HasKeys();
45-
}
46-
}
47-
48-
/// <summary>
49-
/// Gets the fallback configuration from the "FallbackFields" field.
50-
/// </summary>
51-
/// <value>The fallback configuration.</value>
52-
protected NameValueCollection FallbackConfiguration
53-
{
54-
get
55-
{
56-
if (_fallbackConfiguration == null)
57-
{
58-
// don't use fallback on this configuration field
59-
using (new FallbackDisabler())
60-
{
61-
_fallbackConfiguration = WebUtil.ParseUrlParameters(InnerItem[FallbackFields]);
62-
}
63-
}
64-
return _fallbackConfiguration ?? new NameValueCollection(0);
42+
return FallbackDefinition.Keys.Count > 0;
6543
}
6644
}
6745

6846
/// <summary>
6947
/// Gets the fallback definition.
7048
/// </summary>
7149
/// <value>The fallback definition.</value>
72-
protected Dictionary<ID, List<Field>> FallbackDefinition
50+
protected Dictionary<ID, Setting> FallbackDefinition
7351
{
74-
get
75-
{
76-
if (_fallbackDefinition == null)
77-
{
78-
_fallbackDefinition = InitializeLateralFallbackConfiguration();
79-
}
80-
return _fallbackDefinition;
81-
}
52+
get;
53+
private set;
8254
}
8355

8456
/// <summary>
8557
/// Gets the fallback fields for the given field.
8658
/// </summary>
8759
/// <param name="field">The field.</param>
8860
/// <returns></returns>
89-
public List<Field> GetFallbackFields(Field field)
61+
public Setting GetFallbackFields(Field field)
9062
{
9163
if (DoesFieldHaveLateralFallback(field))
9264
{
9365
return FallbackDefinition[field.ID];
9466
}
95-
return new List<Field>(0);
67+
return null;
9668
}
9769

9870
/// <summary>
@@ -114,51 +86,134 @@ public IEnumerable<ID> GetFieldsThatFallbackTo(Field field)
11486
{
11587
foreach (ID key in FallbackDefinition.Keys)
11688
{
117-
if (FallbackDefinition[key].Any(f => f.ID == field.ID))
89+
if (FallbackDefinition[key].SourceFields.Any(f => f.ID == field.ID))
11890
{
11991
yield return key;
12092
}
12193
}
12294
}
12395

124-
/// <summary>
125-
/// Converts the NameValueCollection into Dictionary<ID, List<Field>>
126-
/// where the key is the ID of the field to recieve the fallback value
127-
/// and the values are the list of fields to check for a fallback value
128-
/// </summary>
129-
/// <returns></returns>
130-
private Dictionary<ID, List<Field>> InitializeLateralFallbackConfiguration()
96+
private void Initialize()
13197
{
132-
Dictionary<ID, List<Field>> dic;
133-
if (!HasLateralFallback)
98+
var _fallbackDefinition = new Dictionary<ID, Setting>();
99+
100+
// don't use fallback on this configuration field
101+
using (new FallbackDisabler())
134102
{
135-
dic = new Dictionary<ID, List<Field>>(0);
103+
// try to get this fields as an XML field
104+
// Original version of this field was key/value pair
105+
// It was converted to XML to support advanced options
106+
XmlField test = InnerItem.Fields[FallbackFields];
107+
if (test.Xml == null)
108+
{
109+
ParseNameValueConfiguration(InnerItem[FallbackFields], _fallbackDefinition);
110+
}
111+
else
112+
{
113+
ParseXmlConfiguration(test, _fallbackDefinition);
114+
}
136115
}
137-
else
116+
FallbackDefinition = _fallbackDefinition;
117+
}
118+
119+
private void ParseNameValueConfiguration(string oldConfigurationValue, Dictionary<ID, Setting> settings)
120+
{
121+
NameValueCollection fallbackConfiguration = WebUtil.ParseUrlParameters(oldConfigurationValue);
122+
foreach (string fieldName in fallbackConfiguration.AllKeys)
138123
{
139-
dic = new Dictionary<ID, List<Field>>();
140-
foreach (string fieldName in FallbackConfiguration.AllKeys)
141-
{
142-
Field mainField = InnerItem.Fields[fieldName];
124+
Field mainField = InnerItem.Fields[fieldName];
143125

144-
if (mainField != null)
126+
if (mainField != null)
127+
{
128+
List<Field> fallbackFields = new List<Field>();
129+
List<string> fallbackFieldNames = fallbackConfiguration.GetValues(fieldName).FirstOrDefault().Split(new char[] { '|', ',', ';' }, System.StringSplitOptions.RemoveEmptyEntries).ToList();
130+
foreach (string fallbackFieldName in fallbackFieldNames)
145131
{
146-
List<Field> fallbackFields = new List<Field>();
147-
List<string> fallbackFieldNames = FallbackConfiguration.GetValues(fieldName).FirstOrDefault().Split(new char[]{'|', ',', ';'}, System.StringSplitOptions.RemoveEmptyEntries).ToList();
148-
foreach (string fallbackFieldName in fallbackFieldNames)
132+
Field f = InnerItem.Fields[fallbackFieldName];
133+
if (f != null)
149134
{
150-
Field f = InnerItem.Fields[fallbackFieldName];
151-
if (f != null)
152-
{
153-
fallbackFields.Add(f);
154-
}
135+
fallbackFields.Add(f);
155136
}
137+
}
138+
139+
Setting setting = new Setting();
140+
setting.SourceFields = fallbackFields;
156141

157-
dic.Add(mainField.ID, fallbackFields);
142+
settings.Add(mainField.ID, setting);
143+
}
144+
}
145+
}
146+
147+
private void ParseXmlConfiguration(XmlField fallbackField, Dictionary<ID, Setting> settings)
148+
{
149+
// complex structure...
150+
// TODO: Create a nice Sitecore field editing interface for this
151+
152+
/// <fallback>
153+
/// <setting target="{id}" source="{id}|{id}|{id}..." enableEllipsis="true|false" clipAt="{number chars}" />
154+
/// <setting target="{id}" source="{id}|{id}|{id}..." enableEllipsis="true|false" clipAt="{number chars}" />
155+
/// ...
156+
/// </fallback>
157+
158+
foreach (XmlNode child in fallbackField.Xml.FirstChild.ChildNodes)
159+
{
160+
XmlAttribute target = child.Attributes["target"];
161+
XmlAttribute source = child.Attributes["source"];
162+
XmlAttribute enableEllipsis = child.Attributes["enableEllipsis"];
163+
XmlAttribute clipAt = child.Attributes["clipAt"];
164+
165+
/// TODO: Guard against improper input.. move to factory
166+
Setting setting = new Setting();
167+
168+
if (enableEllipsis != null)
169+
{
170+
setting.UseEllipsis = bool.Parse(enableEllipsis.Value);
171+
}
172+
173+
if (clipAt != null)
174+
{
175+
int i;
176+
if (int.TryParse(clipAt.Value, out i) && i > 0)
177+
{
178+
setting.ClipAt = i;
179+
}
180+
}
181+
182+
List<Field> fallbackFields = new List<Field>();
183+
List<string> fallbackFieldNames = source.Value.Split(new char[] { '|', ',', ';' }, System.StringSplitOptions.RemoveEmptyEntries).ToList();
184+
foreach (string fallbackFieldName in fallbackFieldNames)
185+
{
186+
Field f = InnerItem.Fields[fallbackFieldName];
187+
if (f != null)
188+
{
189+
fallbackFields.Add(f);
158190
}
159191
}
192+
193+
setting.SourceFields = fallbackFields;
194+
195+
ID targetID = new Sitecore.Data.ID(target.Value);
196+
197+
settings.Add(targetID, setting);
198+
160199
}
161-
return dic;
200+
}
201+
202+
internal class Setting
203+
{
204+
public List<Sitecore.Data.Fields.Field> SourceFields { get; set; }
205+
206+
public bool TruncateText
207+
{
208+
get
209+
{
210+
return ClipAt.HasValue;
211+
}
212+
}
213+
214+
public bool UseEllipsis { get; set; }
215+
216+
public int? ClipAt { get; set; }
162217
}
163218
}
164219
}

0 commit comments

Comments
 (0)