Skip to content
This repository was archived by the owner on Feb 10, 2024. It is now read-only.

Commit 1bdd3e3

Browse files
authored
Merge pull request #174 from enkelmedia/173
Added ValueProcessors and solved #173
2 parents 8371a86 + 2a177f7 commit 1bdd3e3

9 files changed

+173
-0
lines changed

docs/developers-guide.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,47 @@ By inheriting from the `DocTypeGridEditorSurfaceController` base class, you'll a
207207

208208
---
209209

210+
### Value Processors
211+
Since Doc Type Grid Editor stores the data for each property as a JSON-blob, we're not processing the values in the same way as Umbraco-core before storing it. This also means that the values that comes back and are passed into a Property Value Converter might be in of a type/format that that Property Value Convert can't handle.
212+
213+
We've added something that we call "ValueProcessors" and these can be used to modify the raw property value before we send it to the property value converter. One example of where this is needed is the Tags-editor.
214+
215+
If you need to perform some processing of a value before it's sent to the property value converter you can add your own ValueProcessor.
216+
217+
```csharp
218+
public class UmbracoColorPickerValueProcessor : IDocTypeGridEditorValueProcessor
219+
{
220+
public bool IsProcessorFor(string propertyEditorAlias)
221+
=> propertyEditorAlias.Equals(Constants.PropertyEditors.Aliases.ColorPicker);
222+
223+
public object ProcessValue(object value)
224+
{
225+
// Do something with the value
226+
return value;
227+
}
228+
}
229+
```
230+
231+
Then register this during composition withing IUserComposer,
232+
```csharp
233+
public class MyCustomDocTypeGridEditorComposer : IUserComposer
234+
{
235+
public void Compose(Composition composition)
236+
{
237+
composition.DocTypeGridEditorValueProcessors()
238+
.Append<UmbracoColorPickerValueProcessor>();
239+
}
240+
}
241+
```
242+
243+
Dot Type Grid editor ships with a ValueProcessor for the Umbraco-Tags property.
244+
245+
**Note:** When using a Tag-editor inside a DTGE this would not create any relationship between the current node and that tag, if you need to tag a node you should use the Tags-editor as a property directly on the document type.
246+
247+
248+
249+
250+
210251
### Useful Links
211252

212253
* [Source Code](https://github.com/skttl/umbraco-doc-type-grid-editor)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Our.Umbraco.DocTypeGridEditor.Extensions;
2+
using Our.Umbraco.DocTypeGridEditor.ValueProcessing;
3+
using Umbraco.Core.Composing;
4+
5+
namespace Our.Umbraco.DocTypeGridEditor.Composing
6+
{
7+
/// <summary>
8+
/// Composes defaults for Doc Type Grid Editor
9+
/// </summary>
10+
public class DocTypeGridEditorComposer : IUserComposer
11+
{
12+
public void Compose(Composition composition)
13+
{
14+
composition.DocTypeGridEditorValueProcessors().Append<UmbracoTagsValueProcessor>();
15+
}
16+
}
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Our.Umbraco.DocTypeGridEditor.ValueProcessing.Collections;
2+
using Umbraco.Core.Composing;
3+
4+
namespace Our.Umbraco.DocTypeGridEditor.Extensions
5+
{
6+
public static class CompositionExtensions
7+
{
8+
/// <summary>
9+
/// Used to modify the collection of Value Processors for Doc Type Grid Editor
10+
/// </summary>
11+
/// <param name="composition"></param>
12+
/// <returns></returns>
13+
public static DocTypeGridEditorValueProcessorsCollectionBuilder DocTypeGridEditorValueProcessors(this Composition composition)
14+
=> composition.WithCollectionBuilder<DocTypeGridEditorValueProcessorsCollectionBuilder>();
15+
}
16+
}

src/Our.Umbraco.DocTypeGridEditor/Helpers/DocTypeGridEditorHelper.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Web.Mvc;
45
using Newtonsoft.Json;
56
using Newtonsoft.Json.Linq;
67
using Our.Umbraco.DocTypeGridEditor.Extensions;
78
using Our.Umbraco.DocTypeGridEditor.Models;
9+
using Our.Umbraco.DocTypeGridEditor.ValueProcessing;
10+
using Our.Umbraco.DocTypeGridEditor.ValueProcessing.Collections;
811
using Umbraco.Core;
912
using Umbraco.Core.Cache;
1013
using Umbraco.Web.Composing;
@@ -64,6 +67,14 @@ private static IPublishedElement ConvertValue(string id, string contentTypeAlias
6467

6568
var newValue = propEditor.GetValueEditor().FromEditor(contentPropData, jProp.Value);
6669

70+
// Performing "ValueProcessing" if any ValueProcessor is configured for this Property Editor-alias.
71+
var processorsCollection = Current.Factory.GetInstance<DocTypeGridEditorValueProcessorsCollection>();
72+
var processor = processorsCollection.FirstOrDefault(x => x.IsProcessorFor(propEditor.Alias));
73+
if (processor != null)
74+
{
75+
newValue = processor.ProcessValue(newValue);
76+
}
77+
6778
/* Now that we have the DB stored value, we actually need to then convert it into its
6879
* XML serialized state as expected by the published property by calling ConvertDbToString
6980
*/

src/Our.Umbraco.DocTypeGridEditor/Our.Umbraco.DocTypeGridEditor.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,12 @@
231231
<Compile Include="Models\UnpublishedProperty.cs" />
232232
<Compile Include="Properties\AssemblyInfo.cs" />
233233
<Compile Include="Properties\VersionInfo.cs" />
234+
<Compile Include="Composing\DocTypeGridEditorComposer.cs" />
235+
<Compile Include="Extensions\CompositionExtensions.cs" />
236+
<Compile Include="ValueProcessing\Collections\DocTypeGridEditorValueProcessorsCollection.cs" />
237+
<Compile Include="ValueProcessing\Collections\DocTypeGridEditorValueProcessorsCollectionBuilder.cs" />
238+
<Compile Include="ValueProcessing\IDocTypeGridEditorValueProcessor.cs" />
239+
<Compile Include="ValueProcessing\UmbracoTagsValueProcessor.cs" />
234240
<Compile Include="Web\Controllers\DocTypeGridEditorApiController.cs" />
235241
<Compile Include="Extensions\ContentTypeServiceExtensions.cs" />
236242
<Compile Include="Web\Controllers\DocTypeGridEditorSurfaceController.cs" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
using Umbraco.Core.Composing;
3+
4+
namespace Our.Umbraco.DocTypeGridEditor.ValueProcessing.Collections
5+
{
6+
/// <summary>
7+
/// Collection to hold references to Value Processors to be used with Doc Type Grid Editor. <see cref="IDocTypeGridEditorValueProcessor"/>
8+
/// </summary>
9+
public class DocTypeGridEditorValueProcessorsCollection : BuilderCollectionBase<IDocTypeGridEditorValueProcessor>
10+
{
11+
public DocTypeGridEditorValueProcessorsCollection(IEnumerable<IDocTypeGridEditorValueProcessor> items) : base(items)
12+
{ }
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Umbraco.Core.Composing;
2+
3+
namespace Our.Umbraco.DocTypeGridEditor.ValueProcessing.Collections
4+
{
5+
/// <summary>
6+
/// Collection builder for Value Processors <see cref="IDocTypeGridEditorValueProcessor"/>
7+
/// </summary>
8+
public class DocTypeGridEditorValueProcessorsCollectionBuilder : OrderedCollectionBuilderBase<DocTypeGridEditorValueProcessorsCollectionBuilder, DocTypeGridEditorValueProcessorsCollection, IDocTypeGridEditorValueProcessor>
9+
{
10+
protected override DocTypeGridEditorValueProcessorsCollectionBuilder This => this;
11+
}
12+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace Our.Umbraco.DocTypeGridEditor.ValueProcessing
2+
{
3+
/// <summary>
4+
/// Abstracts a ValueProcessor that is used to modify a property value before it's sent to a Property Value Converter
5+
/// These are useful when the data format stored for DTGE is different from what the PVC expects ie. like Umbraco.Tags
6+
/// </summary>
7+
public interface IDocTypeGridEditorValueProcessor
8+
{
9+
/// <summary>
10+
/// Returns if this processor can handle a certain property editor based on the property editors alias.
11+
/// </summary>
12+
/// <param name="propertyEditorAlias">Contains the alias of the property editor ie. "Umbraco.Tags" or "Umbraco.Picker".</param>
13+
/// <returns></returns>
14+
bool IsProcessorFor(string propertyEditorAlias);
15+
16+
/// <summary>
17+
/// Processes the value to de desired format/type. Most of the time this is to make sure that the object passed to the property value converters is
18+
/// of the correct type and in the correct format for the property value converter to handle.
19+
/// </summary>
20+
/// <param name="value"></param>
21+
/// <returns></returns>
22+
object ProcessValue(object value);
23+
}
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Newtonsoft.Json;
2+
using Umbraco.Core;
3+
4+
namespace Our.Umbraco.DocTypeGridEditor.ValueProcessing
5+
{
6+
/// <summary>
7+
/// Processes the value stored in DTGE to match the string-json-format that the Property Value Converter expects.
8+
/// </summary>
9+
/// <remarks>
10+
/// When we're setting a value on a Umbraco.Core.Models.Property it will be converted into the type that this Property expects.
11+
/// In the case with Tags, there will be a .ToString() that converts the object passed into a string, something like System.Linq.Enumerable+WhereSelectEnumerableIterator`2[Newtonsoft.Json.Linq.JToken,System.String]
12+
/// This value would be passed to the Property Value Converter which would blow up. The processing below will safely convert the value to a valid json-string before it's passed
13+
/// to the Property Value Converter.
14+
/// </remarks>
15+
public class UmbracoTagsValueProcessor : IDocTypeGridEditorValueProcessor
16+
{
17+
public bool IsProcessorFor(string propertyEditorAlias) => propertyEditorAlias.Equals(Constants.PropertyEditors.Aliases.Tags);
18+
19+
public object ProcessValue(object value)
20+
{
21+
if (value == null)
22+
{
23+
// When the value is null, we need to fake an empty array since this is
24+
// how Umbraco would store an empty "Umbraco.Tags"-property.
25+
return "[]";
26+
}
27+
28+
// Returns a string-version of the JArray that DTGE would pass.
29+
return JsonConvert.SerializeObject(value);
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)