Created new IPropertyEditorValueConverter for use with DynamicDocument so we don't have to rely on

any more xml configuration sections to created and add value 'mappers' / converters. This saves on tons
of code and makes it really easy for devs to handle their own conversions for use with dynamic node.
This commit is contained in:
Shannon Deminick
2012-08-18 11:39:18 +06:00
parent 7175860ae0
commit 56a13c5e0c
8 changed files with 180 additions and 68 deletions

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core
{
@@ -109,6 +110,14 @@ namespace Umbraco.Core
ActionsResolver.Current = new ActionsResolver(
PluginManager.Current.ResolveActions());
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
new []
{
typeof(DatePickerPropertyEditorValueConverter),
typeof(TinyMcePropertyEditorValueConverter),
typeof(YesNoPropertyEditorValueConverter)
});
}
}
}

View File

@@ -135,23 +135,6 @@ namespace Umbraco.Core.Dynamics
return DynamicDocumentWalker.Sibling(this, nodeTypeAlias);
}
private DynamicDocumentList GetChildren()
{
if (_cachedChildren == null)
{
var children = _backingItem.Children;
//testing
if (!children.Any() && _backingItem.Id == 0)
{
_cachedChildren = new DynamicDocumentList(new List<DynamicDocument> { new DynamicDocument(this._backingItem) });
}
else
{
_cachedChildren = new DynamicDocumentList(_backingItem.Children.Select(x => new DynamicDocument(x)));
}
}
return _cachedChildren;
}
//public DynamicNodeList XPath(string xPath)
//{
// //if this DN was initialized with an underlying NodeFactory.Node
@@ -464,7 +447,7 @@ namespace Umbraco.Core.Dynamics
if (name.InvariantEquals("ChildrenAsList") || name.InvariantEquals("Children"))
{
result = GetChildren();
result = Children;
return true;
}
if (name.InvariantEquals("parentId"))
@@ -660,37 +643,15 @@ namespace Umbraco.Core.Dynamics
//}
private bool ConvertPropertyValueByDataType(ref object result, Guid dataType)
{
//First lets check all registered converters:
// TODO: Look up new converters!
//the resulting property is a string, but to support some of the nice linq stuff in .Where
//we should really check some more types
string sResult = string.Format("{0}", result).Trim();
//boolean
if (dataType == DATATYPE_YESNO_GUID)
{
bool parseResult;
if (string.IsNullOrEmpty(string.Format("{0}", result)))
{
result = false;
return true;
}
if (Boolean.TryParse(sResult.Replace("1", "true").Replace("0", "false"), out parseResult))
{
result = parseResult;
return true;
}
}
////integer
////this will eat csv strings, so only do it if the decimal also includes a decimal seperator (according to the current culture)
//if (dataType == DATATYPE_INTEGER_GUID)
//{
// int iResult = 0;
// if (int.TryParse(sResult, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.CurrentCulture, out iResult))
// {
// result = iResult;
// return true;
// }
//}
//this will eat csv strings, so only do it if the decimal also includes a decimal seperator (according to the current culture)
if (sResult.Contains(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator))
@@ -703,28 +664,7 @@ namespace Umbraco.Core.Dynamics
return true;
}
}
if (dataType == DATATYPE_DATETIMEPICKER_GUID || dataType == DATATYPE_DATEPICKER_GUID)
{
//date
DateTime dtResult = DateTime.MinValue;
if (DateTime.TryParse(string.Format("{0}", result), out dtResult))
{
result = dtResult;
return true;
}
else
{
result = new DynamicNull();
return true;
}
}
// Rich text editor (return IHtmlString so devs doesn't need to decode html
if (dataType == DATATYPE_TINYMCE_GUID)
{
result = new HtmlString(result.ToString());
return true;
}
if (string.Equals("true", sResult, StringComparison.CurrentCultureIgnoreCase))
@@ -1144,7 +1084,23 @@ namespace Umbraco.Core.Dynamics
public IEnumerable<DynamicDocument> Children
{
get { return GetChildren(); }
get
{
if (_cachedChildren == null)
{
var children = _backingItem.Children;
//testing
if (!children.Any() && _backingItem.Id == 0)
{
_cachedChildren = new DynamicDocumentList(new List<DynamicDocument> { new DynamicDocument(this._backingItem) });
}
else
{
_cachedChildren = new DynamicDocumentList(_backingItem.Children.Select(x => new DynamicDocument(x)));
}
}
return _cachedChildren;
}
}
#region GetProperty methods which can be used with the dynamic object

View File

@@ -0,0 +1,36 @@
using System;
using System.Linq;
namespace Umbraco.Core.PropertyEditors
{
internal class DatePickerPropertyEditorValueConverter : IPropertyEditorValueConverter
{
public bool CanConvertForEditor(Guid propertyEditorId)
{
return (new[]
{
Guid.Parse("b6fb1622-afa5-4bbf-a3cc-d9672a442222"),
Guid.Parse("23e93522-3200-44e2-9f29-e61a6fcbb79a")
}).Contains(propertyEditorId);
}
/// <summary>
/// return a DateTime object even if the value is a string
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public Attempt<object> ConvertPropertyValue(object value)
{
if (value == null) return new Attempt<object>(false, null);
//if its already a DateTime
if (TypeHelper.IsTypeAssignableFrom<DateTime>(value))
return new Attempt<object>(true, value);
//convert to string
var asString = Convert.ToString(value);
DateTime dt;
return DateTime.TryParse(asString, out dt)
? new Attempt<object>(true, dt)
: new Attempt<object>(false, null);
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using Umbraco.Core.Dynamics;
namespace Umbraco.Core.PropertyEditors
{
internal interface IPropertyEditorValueConverter
{
/// <summary>
/// Returns true if this converter can perform the value conversion for the specified property editor id
/// </summary>
/// <param name="propertyEditorId"></param>
/// <returns></returns>
bool CanConvertForEditor(Guid propertyEditorId);
/// <summary>
/// Attempts to convert the value specified into a useable value on the front-end
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <remarks>
/// This is used to convert the value stored in the repository into a usable value on the front-end.
/// For example, if a 0 or 1 is stored for a boolean, we'd want to convert this to a real boolean.
///
/// Also note that the value might not come in as a 0 or 1 but as a "0" or "1"
/// </remarks>
Attempt<object> ConvertPropertyValue(object value);
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Manages the list of IPropertyEditorValueConverter's
/// </summary>
internal class PropertyEditorValueConvertersResolver : ManyObjectsResolverBase<PropertyEditorValueConvertersResolver, IPropertyEditorValueConverter>
{
public PropertyEditorValueConvertersResolver(IEnumerable<Type> converters)
: base(converters)
{
}
public IEnumerable<IPropertyEditorValueConverter> Converters
{
get { return Values; }
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Web;
namespace Umbraco.Core.PropertyEditors
{
internal class TinyMcePropertyEditorValueConverter : IPropertyEditorValueConverter
{
public bool CanConvertForEditor(Guid propertyEditorId)
{
return Guid.Parse("5e9b75ae-face-41c8-b47e-5f4b0fd82f83").Equals(propertyEditorId);
}
/// <summary>
/// Return IHtmlString so devs doesn't need to decode html
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public Attempt<object> ConvertPropertyValue(object value)
{
return new Attempt<object>(true, new HtmlString(value.ToString()));
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
namespace Umbraco.Core.PropertyEditors
{
internal class YesNoPropertyEditorValueConverter : IPropertyEditorValueConverter
{
public bool CanConvertForEditor(Guid propertyEditorId)
{
return Guid.Parse("38b352c1-e9f8-4fd8-9324-9a2eab06d97a").Equals(propertyEditorId);
}
/// <summary>
/// Convert from string boolean or 0 or 1 to real boolean
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public Attempt<object> ConvertPropertyValue(object value)
{
if (value == null) return new Attempt<object>(false, null);
//if its already a bool
if (TypeHelper.IsTypeAssignableFrom<bool>(value))
return new Attempt<object>(true, value);
//convert to string
var asString = Convert.ToString(value);
bool asBool;
return bool.TryParse(asString, out asBool)
? new Attempt<object>(true, asBool)
: bool.TryParse(asString.Replace("1", "true").Replace("0", "false"), out asBool) //convert 0 or 1 to true or false
? new Attempt<object>(true, asBool)
: new Attempt<object>(false, null);
}
}
}

View File

@@ -82,6 +82,8 @@
<Compile Include="Dynamics\ExtensionMethodFinder.cs" />
<Compile Include="Dynamics\ExtensionMethods.cs" />
<Compile Include="Dynamics\Grouping.cs" />
<Compile Include="PropertyEditors\DatePickerPropertyEditorValueConverter.cs" />
<Compile Include="PropertyEditors\IPropertyEditorValueConverter.cs" />
<Compile Include="HtmlTagWrapper.cs" />
<Compile Include="HtmlTagWrapperBase.cs" />
<Compile Include="HtmlTagWrapperTextNode.cs" />
@@ -120,6 +122,9 @@
<Compile Include="ObjectResolution\MacroFieldEditorsResolver.cs" />
<Compile Include="Macros\PersistableMacroProperty.cs" />
<Compile Include="ObjectExtensions.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueConvertersResolver.cs" />
<Compile Include="PropertyEditors\TinyMcePropertyEditorValueConverter.cs" />
<Compile Include="PropertyEditors\YesNoPropertyEditorValueConverter.cs" />
<Compile Include="RazorDataTypeModelStaticMappingItem.cs" />
<Compile Include="ObjectResolution\ManyObjectsResolverBase.cs" />
<Compile Include="ObjectResolution\ObjectLifetimeScope.cs" />