From 44ccfc0262d9c0cc6ec3c37103e8777123f31fdf Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Sun, 9 Dec 2012 03:22:11 +0500 Subject: [PATCH] Adds 'Url', 'ItemType' and the Indexed property alias to IPublishedContent. Changes Properties to ICollection instead of Collection for IPublishedContent. Creates PublishedContentBase object which handles the Url and Indexed property on IPublishedContent automatically so implementors should use this base class instead. Moves GetPropertyValue extensions to the Umbraco.Web project instead of the Umbraco.Core project because this method needs to parse internal links if the value is a string. We require the UmbracoContext to do this so they must exist in the Web project. --- src/Umbraco.Core/Models/IPublishedContent.cs | 16 +- src/Umbraco.Core/Models/PublishedItemType.cs | 11 ++ .../PublishedContentExtensions.cs | 83 --------- src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../PublishedContentDataTableTests.cs | 19 +- .../StronglyTypedQueryTests.cs | 47 ++++- src/Umbraco.Web/DefaultPublishedMediaStore.cs | 171 ++++++++++++++---- .../Models/DynamicPublishedContent.cs | 17 +- .../Models/PublishedContentBase.cs | 70 +++++++ src/Umbraco.Web/Models/XmlPublishedContent.cs | 53 +++--- src/Umbraco.Web/PublishedContentExtensions.cs | 109 +++++++++++ .../Templates/TemplateUtilities.cs | 1 - src/Umbraco.Web/Umbraco.Web.csproj | 1 + 13 files changed, 444 insertions(+), 155 deletions(-) create mode 100644 src/Umbraco.Core/Models/PublishedItemType.cs create mode 100644 src/Umbraco.Web/Models/PublishedContentBase.cs diff --git a/src/Umbraco.Core/Models/IPublishedContent.cs b/src/Umbraco.Core/Models/IPublishedContent.cs index 869a6ae696..213a0e5ed3 100644 --- a/src/Umbraco.Core/Models/IPublishedContent.cs +++ b/src/Umbraco.Core/Models/IPublishedContent.cs @@ -5,7 +5,7 @@ using System.Collections.ObjectModel; namespace Umbraco.Core.Models { /// - /// Defines a PublishedContent in Umbraco + /// Defines a published item in Umbraco /// /// /// A replacement for INode which needs to occur since INode doesn't contain the document type alias @@ -13,7 +13,6 @@ namespace Umbraco.Core.Models /// public interface IPublishedContent { - IPublishedContent Parent { get; } int Id { get; } int TemplateId { get; } int SortOrder { get; } @@ -30,9 +29,20 @@ namespace Umbraco.Core.Models DateTime UpdateDate { get; } Guid Version { get; } int Level { get; } - Collection Properties { get; } + string Url { get; } + PublishedItemType ItemType { get; } + IPublishedContent Parent { get; } IEnumerable Children { get; } + ICollection Properties { get; } + + /// + /// Returns the property value for the property alias specified + /// + /// + /// + object this[string propertyAlias] { get; } + /// /// Returns a property on the object based on an alias /// diff --git a/src/Umbraco.Core/Models/PublishedItemType.cs b/src/Umbraco.Core/Models/PublishedItemType.cs new file mode 100644 index 0000000000..b9fb603735 --- /dev/null +++ b/src/Umbraco.Core/Models/PublishedItemType.cs @@ -0,0 +1,11 @@ +namespace Umbraco.Core.Models +{ + /// + /// The type of published item + /// + public enum PublishedItemType + { + Content, + Media + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/PublishedContentExtensions.cs b/src/Umbraco.Core/PublishedContentExtensions.cs index bda88f115e..9d54198982 100644 --- a/src/Umbraco.Core/PublishedContentExtensions.cs +++ b/src/Umbraco.Core/PublishedContentExtensions.cs @@ -14,8 +14,6 @@ namespace Umbraco.Core public static class PublishedContentExtensions { - - #region GetProperty public static IPublishedContentProperty GetProperty(this IPublishedContent content, string alias, bool recursive) { @@ -40,37 +38,6 @@ namespace Umbraco.Core } #endregion - #region GetPropertyValue - public static object GetPropertyValue(this IPublishedContent doc, string alias) - { - return doc.GetPropertyValue(alias, false); - } - public static object GetPropertyValue(this IPublishedContent doc, string alias, string fallback) - { - var prop = doc.GetPropertyValue(alias); - return (prop != null && !Convert.ToString(prop).IsNullOrWhiteSpace()) ? prop : fallback; - } - public static object GetPropertyValue(this IPublishedContent doc, string alias, bool recursive) - { - var p = doc.GetProperty(alias, recursive); - if (p == null) return null; - - //Here we need to put the value through the IPropertyEditorValueConverter's - //get the data type id for the current property - var dataType = PublishedContentHelper.GetDataType(doc.DocumentTypeAlias, alias); - //convert the string value to a known type - var converted = PublishedContentHelper.ConvertPropertyValue(p.Value, dataType, doc.DocumentTypeAlias, alias); - return converted.Success - ? converted.Result - : p.Value; - } - public static object GetPropertyValue(this IPublishedContent doc, string alias, bool recursive, string fallback) - { - var prop = doc.GetPropertyValue(alias, recursive); - return (prop != null && !Convert.ToString(prop).IsNullOrWhiteSpace()) ? prop : fallback; - } - #endregion - #region HasValue public static bool HasValue(this IPublishedContentProperty prop) @@ -129,57 +96,7 @@ namespace Umbraco.Core return false; } - /// - /// Returns the property as the specified type, if the property is not found or does not convert - /// then the default value of type T is returned. - /// - /// - /// - /// - /// - public static T GetPropertyValue(this IPublishedContent doc, string alias) - { - return doc.GetPropertyValue(alias, default(T)); - } - public static T GetPropertyValue(this IPublishedContent prop, string alias, bool recursive, T ifCannotConvert) - { - var p = prop.GetProperty(alias, recursive); - if (p == null) - return ifCannotConvert; - - //before we try to convert it manually, lets see if the PropertyEditorValueConverter does this for us - //Here we need to put the value through the IPropertyEditorValueConverter's - //get the data type id for the current property - var dataType = PublishedContentHelper.GetDataType(prop.DocumentTypeAlias, alias); - //convert the value to a known type - var converted = PublishedContentHelper.ConvertPropertyValue(p.Value, dataType, prop.DocumentTypeAlias, alias); - if (converted.Success) - { - //if its successful, check if its the correct type and return it - if (converted.Result is T) - { - return (T)converted.Result; - } - //if that's not correct, try converting the converted type - var reConverted = converted.Result.TryConvertTo(); - if (reConverted.Success) - { - return reConverted.Result; - } - } - - //last, if all the above has failed, we'll just try converting the raw value straight to 'T' - var manualConverted = p.Value.TryConvertTo(); - if (manualConverted.Success) - return manualConverted.Result; - return ifCannotConvert; - } - - public static T GetPropertyValue(this IPublishedContent prop, string alias, T ifCannotConvert) - { - return prop.GetPropertyValue(alias, false, ifCannotConvert); - } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 71d95811a2..3717354a71 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -159,6 +159,7 @@ + diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs index 6d8b00e5eb..c6ce668a40 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs @@ -169,6 +169,17 @@ namespace Umbraco.Tests.PublishedContent private class TestPublishedContent : IPublishedContent { + public string Url { get; set; } + public PublishedItemType ItemType { get; set; } + + IPublishedContent IPublishedContent.Parent + { + get { return Parent; } + } + IEnumerable IPublishedContent.Children + { + get { return Children; } + } public IPublishedContent Parent { get; set; } public int Id { get; set; } public int TemplateId { get; set; } @@ -186,7 +197,13 @@ namespace Umbraco.Tests.PublishedContent public DateTime UpdateDate { get; set; } public Guid Version { get; set; } public int Level { get; set; } - public Collection Properties { get; set; } + public ICollection Properties { get; set; } + + public object this[string propertyAlias] + { + get { return GetProperty(propertyAlias).Value; } + } + public IEnumerable Children { get; set; } public IPublishedContentProperty GetProperty(string alias) { diff --git a/src/Umbraco.Tests/PublishedContent/StronglyTypedQueryTests.cs b/src/Umbraco.Tests/PublishedContent/StronglyTypedQueryTests.cs index 39695065ac..5053279617 100644 --- a/src/Umbraco.Tests/PublishedContent/StronglyTypedQueryTests.cs +++ b/src/Umbraco.Tests/PublishedContent/StronglyTypedQueryTests.cs @@ -5,19 +5,37 @@ using System.Linq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; +using Umbraco.Core.PropertyEditors; using Umbraco.Tests.TestHelpers; using Umbraco.Web; +using Umbraco.Web.Routing; namespace Umbraco.Tests.PublishedContent { [TestFixture] - public class StronglyTypedQueryTests : BaseWebTest + public class StronglyTypedQueryTests : BaseRoutingTest { protected override bool RequiresDbSetup { get { return false; } } + public override void Initialize() + { + base.Initialize(); + + var routingCtx = GetRoutingContext("/test", 1234); + UmbracoContext.Current = routingCtx.UmbracoContext; + PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(Enumerable.Empty()); + } + + public override void TearDown() + { + base.TearDown(); + UmbracoContext.Current = null; + PropertyEditorValueConvertersResolver.Reset(); + } + protected override string GetXmlContent(int templateId) { return @" @@ -62,7 +80,7 @@ namespace Umbraco.Tests.PublishedContent internal IPublishedContent GetNode(int id) { - var ctx = GetUmbracoContext("/test", 1234); + var ctx = UmbracoContext.Current; var contentStore = new DefaultPublishedContentStore(); var doc = contentStore.GetDocumentById(ctx, id); Assert.IsNotNull(doc); @@ -160,7 +178,7 @@ namespace Umbraco.Tests.PublishedContent if (content.DocumentTypeAlias == alias) return creator(content); throw new InvalidOperationException("The content type cannot be cast to " + typeof(T).FullName + " since it is type: " + content.DocumentTypeAlias); } - + public static HomeContentItem AsHome(this IPublishedContent content) { return content.AsDocumentType("Home", x => new HomeContentItem(x)); @@ -211,6 +229,16 @@ namespace Umbraco.Tests.PublishedContent WrappedContent = content; } + public string Url + { + get { return WrappedContent.Url; } + } + + public PublishedItemType ItemType + { + get { return WrappedContent.ItemType; } + } + public IPublishedContent Parent { get { return WrappedContent.Parent; } @@ -280,10 +308,16 @@ namespace Umbraco.Tests.PublishedContent { get { return WrappedContent.Level; } } - public Collection Properties + public ICollection Properties { get { return WrappedContent.Properties; } } + + public object this[string propertyAlias] + { + get { return GetProperty(propertyAlias).Value; } + } + public IEnumerable Children { get { return WrappedContent.Children; } @@ -295,8 +329,9 @@ namespace Umbraco.Tests.PublishedContent } public partial class HomeContentItem : ContentPageContentItem - { - public HomeContentItem(IPublishedContent content) : base(content) + { + public HomeContentItem(IPublishedContent content) + : base(content) { } diff --git a/src/Umbraco.Web/DefaultPublishedMediaStore.cs b/src/Umbraco.Web/DefaultPublishedMediaStore.cs index 0ea46a5efd..1834e1252f 100644 --- a/src/Umbraco.Web/DefaultPublishedMediaStore.cs +++ b/src/Umbraco.Web/DefaultPublishedMediaStore.cs @@ -10,6 +10,7 @@ using Lucene.Net.Documents; using Umbraco.Core; using Umbraco.Core.Dynamics; using Umbraco.Core.Models; +using Umbraco.Web.Models; using umbraco; using umbraco.cms.businesslogic; using ContentType = umbraco.cms.businesslogic.ContentType; @@ -366,7 +367,7 @@ namespace Umbraco.Web /// This is a helper class and definitely not intended for public use, it expects that all of the values required /// to create an IPublishedContent exist in the dictionary by specific aliases. /// - internal class DictionaryPublishedContent : IPublishedContent + internal class DictionaryPublishedContent : PublishedContentBase { public DictionaryPublishedContent( @@ -386,21 +387,21 @@ namespace Umbraco.Web LoadedFromExamine = fromExamine; - ValidateAndSetProperty(valueDictionary, val => Id = int.Parse(val), "id", "nodeId", "__NodeId"); //should validate the int! - ValidateAndSetProperty(valueDictionary, val => TemplateId = int.Parse(val), "template", "templateId"); - ValidateAndSetProperty(valueDictionary, val => SortOrder = int.Parse(val), "sortOrder"); - ValidateAndSetProperty(valueDictionary, val => Name = val, "nodeName", "__nodeName"); - ValidateAndSetProperty(valueDictionary, val => UrlName = val, "urlName"); - ValidateAndSetProperty(valueDictionary, val => DocumentTypeAlias = val, "nodeTypeAlias", "__NodeTypeAlias"); - ValidateAndSetProperty(valueDictionary, val => DocumentTypeId = int.Parse(val), "nodeType"); - ValidateAndSetProperty(valueDictionary, val => WriterName = val, "writerName"); - ValidateAndSetProperty(valueDictionary, val => CreatorName = val, "creatorName", "writerName"); //this is a bit of a hack fix for: U4-1132 - ValidateAndSetProperty(valueDictionary, val => WriterId = int.Parse(val), "writerID"); - ValidateAndSetProperty(valueDictionary, val => CreatorId = int.Parse(val), "creatorID", "writerID"); //this is a bit of a hack fix for: U4-1132 - ValidateAndSetProperty(valueDictionary, val => Path = val, "path", "__Path"); - ValidateAndSetProperty(valueDictionary, val => CreateDate = ParseDateTimeValue(val), "createDate"); - ValidateAndSetProperty(valueDictionary, val => UpdateDate = ParseDateTimeValue(val), "updateDate"); - ValidateAndSetProperty(valueDictionary, val => Level = int.Parse(val), "level"); + ValidateAndSetProperty(valueDictionary, val => _id = int.Parse(val), "id", "nodeId", "__NodeId"); //should validate the int! + ValidateAndSetProperty(valueDictionary, val => _templateId = int.Parse(val), "template", "templateId"); + ValidateAndSetProperty(valueDictionary, val => _sortOrder = int.Parse(val), "sortOrder"); + ValidateAndSetProperty(valueDictionary, val => _name = val, "nodeName", "__nodeName"); + ValidateAndSetProperty(valueDictionary, val => _urlName = val, "urlName"); + ValidateAndSetProperty(valueDictionary, val => _documentTypeAlias = val, "nodeTypeAlias", "__NodeTypeAlias"); + ValidateAndSetProperty(valueDictionary, val => _documentTypeId = int.Parse(val), "nodeType"); + ValidateAndSetProperty(valueDictionary, val => _writerName = val, "writerName"); + ValidateAndSetProperty(valueDictionary, val => _creatorName = val, "creatorName", "writerName"); //this is a bit of a hack fix for: U4-1132 + ValidateAndSetProperty(valueDictionary, val => _writerId = int.Parse(val), "writerID"); + ValidateAndSetProperty(valueDictionary, val => _creatorId = int.Parse(val), "creatorID", "writerID"); //this is a bit of a hack fix for: U4-1132 + ValidateAndSetProperty(valueDictionary, val => _path = val, "path", "__Path"); + ValidateAndSetProperty(valueDictionary, val => _createDate = ParseDateTimeValue(val), "createDate"); + ValidateAndSetProperty(valueDictionary, val => _updateDate = ParseDateTimeValue(val), "updateDate"); + ValidateAndSetProperty(valueDictionary, val => _level = int.Parse(val), "level"); ValidateAndSetProperty(valueDictionary, val => { int pId; @@ -411,13 +412,13 @@ namespace Umbraco.Web } }, "parentID"); - Properties = new Collection(); + _properties = new Collection(); //loop through remaining values that haven't been applied foreach (var i in valueDictionary.Where(x => !_keysAdded.Contains(x.Key))) { //this is taken from examine - Properties.Add(i.Key.InvariantStartsWith("__") + _properties.Add(i.Key.InvariantStartsWith("__") ? new PropertyResult(i.Key, i.Value, Guid.Empty, PropertyResultType.CustomProperty) : new PropertyResult(i.Key, i.Value, Guid.Empty, PropertyResultType.UserProperty)); } @@ -450,40 +451,134 @@ namespace Umbraco.Web private readonly Func> _getChildren; private readonly Func _getProperty; - public IPublishedContent Parent + /// + /// Returns 'Media' as the item type + /// + public override PublishedItemType ItemType + { + get { return PublishedItemType.Media; } + } + + public override IPublishedContent Parent { get { return _getParent(this); } } public int ParentId { get; private set; } - public int Id { get; private set; } - public int TemplateId { get; private set; } - public int SortOrder { get; private set; } - public string Name { get; private set; } - public string UrlName { get; private set; } - public string DocumentTypeAlias { get; private set; } - public int DocumentTypeId { get; private set; } - public string WriterName { get; private set; } - public string CreatorName { get; private set; } - public int WriterId { get; private set; } - public int CreatorId { get; private set; } - public string Path { get; private set; } - public DateTime CreateDate { get; private set; } - public DateTime UpdateDate { get; private set; } - public Guid Version { get; private set; } - public int Level { get; private set; } - public Collection Properties { get; private set; } - public IEnumerable Children + public override int Id + { + get { return _id; } + } + + public override int TemplateId + { + get { return _templateId; } + } + + public override int SortOrder + { + get { return _sortOrder; } + } + + public override string Name + { + get { return _name; } + } + + public override string UrlName + { + get { return _urlName; } + } + + public override string DocumentTypeAlias + { + get { return _documentTypeAlias; } + } + + public override int DocumentTypeId + { + get { return _documentTypeId; } + } + + public override string WriterName + { + get { return _writerName; } + } + + public override string CreatorName + { + get { return _creatorName; } + } + + public override int WriterId + { + get { return _writerId; } + } + + public override int CreatorId + { + get { return _creatorId; } + } + + public override string Path + { + get { return _path; } + } + + public override DateTime CreateDate + { + get { return _createDate; } + } + + public override DateTime UpdateDate + { + get { return _updateDate; } + } + + public override Guid Version + { + get { return _version; } + } + + public override int Level + { + get { return _level; } + } + + public override ICollection Properties + { + get { return _properties; } + } + + public override IEnumerable Children { get { return _getChildren(this); } } - public IPublishedContentProperty GetProperty(string alias) + public override IPublishedContentProperty GetProperty(string alias) { return _getProperty(this, alias); } private readonly List _keysAdded = new List(); + private int _id; + private int _templateId; + private int _sortOrder; + private string _name; + private string _urlName; + private string _documentTypeAlias; + private int _documentTypeId; + private string _writerName; + private string _creatorName; + private int _writerId; + private int _creatorId; + private string _path; + private DateTime _createDate; + private DateTime _updateDate; + private Guid _version; + private int _level; + private readonly ICollection _properties; + private void ValidateAndSetProperty(IDictionary valueDictionary, Action setProperty, params string[] potentialKeys) { var key = potentialKeys.FirstOrDefault(x => valueDictionary.ContainsKey(x) && valueDictionary[x] != null); diff --git a/src/Umbraco.Web/Models/DynamicPublishedContent.cs b/src/Umbraco.Web/Models/DynamicPublishedContent.cs index a4c4a29d81..f03d06f607 100644 --- a/src/Umbraco.Web/Models/DynamicPublishedContent.cs +++ b/src/Umbraco.Web/Models/DynamicPublishedContent.cs @@ -529,11 +529,26 @@ namespace Umbraco.Web.Models get { return PublishedContent.Level; } } + public string Url + { + get { return PublishedContent.Url; } + } + + public PublishedItemType ItemType + { + get { return PublishedContent.ItemType; } + } + public IEnumerable Properties { get { return PublishedContent.Properties; } } + public object this[string propertyAlias] + { + get { return PublishedContent[propertyAlias]; } + } + public DynamicPublishedContentList Children { get @@ -739,7 +754,7 @@ namespace Umbraco.Web.Models get { return PublishedContent.Level; } } - System.Collections.ObjectModel.Collection IPublishedContent.Properties + ICollection IPublishedContent.Properties { get { return PublishedContent.Properties; } } diff --git a/src/Umbraco.Web/Models/PublishedContentBase.cs b/src/Umbraco.Web/Models/PublishedContentBase.cs new file mode 100644 index 0000000000..186e0b5bd0 --- /dev/null +++ b/src/Umbraco.Web/Models/PublishedContentBase.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Web.Templates; + +namespace Umbraco.Web.Models +{ + + /// + /// An abstract base class to use for IPublishedContent which ensures that the Url and Indexed property return values + /// are consistently returned. + /// + public abstract class PublishedContentBase : IPublishedContent + { + /// + /// Returns the Url for this content item + /// + public virtual string Url + { + get + { + if (UmbracoContext.Current == null) + throw new InvalidOperationException("Cannot resolve a Url for a content item with a null UmbracoContext.Current reference"); + if (UmbracoContext.Current.NiceUrlProvider == null) + throw new InvalidOperationException("Cannot resolve a Url for a content item with a null UmbracoContext.Current.NiceUrlProvider reference"); + return UmbracoContext.Current.NiceUrlProvider.GetNiceUrl(this.Id); + } + } + + public abstract PublishedItemType ItemType { get; } + public abstract int Id { get; } + public abstract int TemplateId { get; } + public abstract int SortOrder { get; } + public abstract string Name { get; } + public abstract string UrlName { get; } + public abstract string DocumentTypeAlias { get; } + public abstract int DocumentTypeId { get; } + public abstract string WriterName { get; } + public abstract string CreatorName { get; } + public abstract int WriterId { get; } + public abstract int CreatorId { get; } + public abstract string Path { get; } + public abstract DateTime CreateDate { get; } + public abstract DateTime UpdateDate { get; } + public abstract Guid Version { get; } + public abstract int Level { get; } + public abstract ICollection Properties { get; } + + /// + /// Returns the property value for the property alias specified + /// + /// + /// + /// + /// Ensures that the value is executed through the IPropertyEditorValueConverters and that all internal links are are to date + /// + public virtual object this[string propertyAlias] + { + get { return this.GetPropertyValue(propertyAlias); } + } + + public abstract IPublishedContentProperty GetProperty(string alias); + public abstract IPublishedContent Parent { get; } + public abstract IEnumerable Children { get; } + } +} diff --git a/src/Umbraco.Web/Models/XmlPublishedContent.cs b/src/Umbraco.Web/Models/XmlPublishedContent.cs index 41e134bee2..18bfbe8115 100644 --- a/src/Umbraco.Web/Models/XmlPublishedContent.cs +++ b/src/Umbraco.Web/Models/XmlPublishedContent.cs @@ -8,6 +8,7 @@ using System.Xml.XPath; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Models; +using Umbraco.Web.Routing; namespace Umbraco.Web.Models { @@ -17,7 +18,7 @@ namespace Umbraco.Web.Models /// [Serializable] [XmlType(Namespace = "http://umbraco.org/webservices/")] - internal class XmlPublishedContent : IPublishedContent + internal class XmlPublishedContent : PublishedContentBase { /// /// Constructor @@ -65,7 +66,7 @@ namespace Umbraco.Web.Models private int _sortOrder; private int _level; - public IEnumerable Children + public override IEnumerable Children { get { @@ -75,12 +76,20 @@ namespace Umbraco.Web.Models } } - public IPublishedContentProperty GetProperty(string alias) + public override IPublishedContentProperty GetProperty(string alias) { return Properties.FirstOrDefault(x => x.Alias.InvariantEquals(alias)); } - public IPublishedContent Parent + /// + /// returns 'Content' as the ItemType + /// + public override PublishedItemType ItemType + { + get { return PublishedItemType.Content; } + } + + public override IPublishedContent Parent { get { @@ -90,7 +99,7 @@ namespace Umbraco.Web.Models } } - public int Id + public override int Id { get { @@ -100,7 +109,7 @@ namespace Umbraco.Web.Models } } - public int TemplateId + public override int TemplateId { get { @@ -110,7 +119,7 @@ namespace Umbraco.Web.Models } } - public int SortOrder + public override int SortOrder { get { @@ -120,7 +129,7 @@ namespace Umbraco.Web.Models } } - public string Name + public override string Name { get { @@ -129,8 +138,8 @@ namespace Umbraco.Web.Models return _name; } } - - public string DocumentTypeAlias + + public override string DocumentTypeAlias { get { @@ -140,7 +149,7 @@ namespace Umbraco.Web.Models } } - public int DocumentTypeId + public override int DocumentTypeId { get { @@ -150,7 +159,7 @@ namespace Umbraco.Web.Models } } - public string WriterName + public override string WriterName { get { @@ -160,7 +169,7 @@ namespace Umbraco.Web.Models } } - public string CreatorName + public override string CreatorName { get { @@ -170,7 +179,7 @@ namespace Umbraco.Web.Models } } - public int WriterId + public override int WriterId { get { @@ -180,7 +189,7 @@ namespace Umbraco.Web.Models } } - public int CreatorId + public override int CreatorId { get { @@ -191,7 +200,7 @@ namespace Umbraco.Web.Models } - public string Path + public override string Path { get { @@ -201,7 +210,7 @@ namespace Umbraco.Web.Models } } - public DateTime CreateDate + public override DateTime CreateDate { get { @@ -211,7 +220,7 @@ namespace Umbraco.Web.Models } } - public DateTime UpdateDate + public override DateTime UpdateDate { get { @@ -221,7 +230,7 @@ namespace Umbraco.Web.Models } } - public Guid Version + public override Guid Version { get { @@ -231,7 +240,7 @@ namespace Umbraco.Web.Models } } - public string UrlName + public override string UrlName { get { @@ -241,7 +250,7 @@ namespace Umbraco.Web.Models } } - public int Level + public override int Level { get { @@ -251,7 +260,7 @@ namespace Umbraco.Web.Models } } - public Collection Properties + public override ICollection Properties { get { diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 93e6d9be72..c5e892780c 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Dynamics; using Umbraco.Core.Models; using Umbraco.Web.Models; using Umbraco.Web.Routing; +using Umbraco.Web.Templates; using umbraco; using umbraco.cms.businesslogic; using Umbraco.Core; @@ -73,6 +74,114 @@ namespace Umbraco.Web return template.Alias; } + #region GetPropertyValue + + /// + /// if the val is a string, ensures all internal local links are parsed + /// + /// + /// + internal static object GetValueWithParsedLinks(object val) + { + //if it is a string send it through the url parser + var text = val as string; + if (text != null) + { + return TemplateUtilities.ResolveUrlsFromTextString( + TemplateUtilities.ParseInternalLinks(text)); + } + //its not a string + return val; + } + + public static object GetPropertyValue(this IPublishedContent doc, string alias) + { + return doc.GetPropertyValue(alias, false); + } + public static object GetPropertyValue(this IPublishedContent doc, string alias, string fallback) + { + var prop = doc.GetPropertyValue(alias); + return (prop != null && !Convert.ToString(prop).IsNullOrWhiteSpace()) ? prop : fallback; + } + public static object GetPropertyValue(this IPublishedContent doc, string alias, bool recursive) + { + var p = doc.GetProperty(alias, recursive); + if (p == null) return null; + + //Here we need to put the value through the IPropertyEditorValueConverter's + //get the data type id for the current property + var dataType = PublishedContentHelper.GetDataType(doc.DocumentTypeAlias, alias); + //convert the string value to a known type + var converted = PublishedContentHelper.ConvertPropertyValue(p.Value, dataType, doc.DocumentTypeAlias, alias); + return converted.Success + ? GetValueWithParsedLinks(converted.Result) + : GetValueWithParsedLinks(p.Value); + } + public static object GetPropertyValue(this IPublishedContent doc, string alias, bool recursive, string fallback) + { + var prop = doc.GetPropertyValue(alias, recursive); + return (prop != null && !Convert.ToString(prop).IsNullOrWhiteSpace()) ? prop : fallback; + } + + /// + /// Returns the property as the specified type, if the property is not found or does not convert + /// then the default value of type T is returned. + /// + /// + /// + /// + /// + public static T GetPropertyValue(this IPublishedContent doc, string alias) + { + return doc.GetPropertyValue(alias, default(T)); + } + + public static T GetPropertyValue(this IPublishedContent prop, string alias, bool recursive, T ifCannotConvert) + { + var p = prop.GetProperty(alias, recursive); + if (p == null) + return ifCannotConvert; + + //before we try to convert it manually, lets see if the PropertyEditorValueConverter does this for us + //Here we need to put the value through the IPropertyEditorValueConverter's + //get the data type id for the current property + var dataType = PublishedContentHelper.GetDataType(prop.DocumentTypeAlias, alias); + //convert the value to a known type + var converted = PublishedContentHelper.ConvertPropertyValue(p.Value, dataType, prop.DocumentTypeAlias, alias); + object parsedLinksVal; + if (converted.Success) + { + parsedLinksVal = GetValueWithParsedLinks(converted.Result); + + //if its successful, check if its the correct type and return it + if (parsedLinksVal is T) + { + return (T)parsedLinksVal; + } + //if that's not correct, try converting the converted type + var reConverted = converted.Result.TryConvertTo(); + if (reConverted.Success) + { + return reConverted.Result; + } + } + + //first, parse links if possible + parsedLinksVal = GetValueWithParsedLinks(p.Value); + //last, if all the above has failed, we'll just try converting the raw value straight to 'T' + var manualConverted = parsedLinksVal.TryConvertTo(); + if (manualConverted.Success) + return manualConverted.Result; + return ifCannotConvert; + } + + public static T GetPropertyValue(this IPublishedContent prop, string alias, T ifCannotConvert) + { + return prop.GetPropertyValue(alias, false, ifCannotConvert); + } + + #endregion + #region Search public static IEnumerable Search(this IPublishedContent d, string term, bool useWildCards = true, string searchProvider = null) { diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs index c730461f70..94b36323f0 100644 --- a/src/Umbraco.Web/Templates/TemplateUtilities.cs +++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs @@ -3,7 +3,6 @@ using System.Text.RegularExpressions; using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Logging; -using umbraco; using UmbracoSettings = Umbraco.Core.Configuration.UmbracoSettings; namespace Umbraco.Web.Templates diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 2e8a5068c7..97b7a43e98 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -264,6 +264,7 @@ +