diff --git a/src/Umbraco.Core/Dynamics/DynamicDocument.cs b/src/Umbraco.Core/Dynamics/DynamicDocument.cs index 88a65dec8b..44e98fbc1e 100644 --- a/src/Umbraco.Core/Dynamics/DynamicDocument.cs +++ b/src/Umbraco.Core/Dynamics/DynamicDocument.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Dynamics /// public class DynamicDocument : DynamicObject { - private readonly IDocument _backingItem; + private readonly IDocument _document; private DynamicDocumentList _cachedChildren; private readonly ConcurrentDictionary _cachedMemberOutput = new ConcurrentDictionary(); @@ -28,7 +28,7 @@ namespace Umbraco.Core.Dynamics public DynamicDocument(IDocument node) { if (node == null) throw new ArgumentNullException("node"); - _backingItem = node; + _document = node; } /// @@ -107,82 +107,9 @@ namespace Umbraco.Core.Dynamics return DynamicDocumentWalker.Sibling(this, nodeTypeAlias); } - //public DynamicDocumentList XPath(string xPath) - //{ - // //if this DN was initialized with an underlying NodeFactory.Node - // if (n != null && n.Type == DynamicBackingItemType.Content) - // { - // //get the underlying xml content - // XmlDocument doc = umbraco.content.Instance.XmlContent; - // if (doc != null) - // { - // //get n as a XmlNode (to be used as the context point for the xpath) - // //rather than just applying the xPath to the root node, this lets us use .. etc from the DynamicNode point - - - // //in test mode, n.Id is 0, let this always succeed - // if (n.Id == 0) - // { - // List selfList = new List() { this }; - // return new DynamicDocumentList(selfList); - // } - // XmlNode node = doc.SelectSingleNode(string.Format("//*[@id='{0}']", n.Id)); - // if (node != null) - // { - // //got the current node (within the XmlContent instance) - // XmlNodeList nodes = node.SelectNodes(xPath); - // if (nodes.Count > 0) - // { - // //we got some resulting nodes - // List nodeFactoryNodeList = new List(); - // //attempt to convert each node in the set to a NodeFactory.Node - // foreach (XmlNode nodeXmlNode in nodes) - // { - // try - // { - // nodeFactoryNodeList.Add(new NodeFactory.Node(nodeXmlNode)); - // } - // catch (Exception) { } //swallow the exceptions - the returned nodes might not be full nodes, e.g. property - // } - // //Wanted to do this, but because we return DynamicDocumentList here, the only - // //common parent class is DynamicObject - // //maybe some future refactoring will solve this? - // //if (nodeFactoryNodeList.Count == 0) - // //{ - // // //if the xpath resulted in a node set, but none of them could be converted to NodeFactory.Node - // // XElement xElement = XElement.Parse(node.OuterXml); - // // //return - // // return new DynamicXml(xElement); - // //} - // //convert the NodeFactory nodelist to IEnumerable and return it as a DynamicDocumentList - // return new DynamicDocumentList(nodeFactoryNodeList.ConvertAll(nfNode => new DynamicNode((INode)nfNode))); - // } - // else - // { - // // XPath returned no nodes, return an empty DynamicDocumentList - // return new DynamicDocumentList(); - // } - // } - // else - // { - // throw new NullReferenceException("Couldn't locate the DynamicNode within the XmlContent"); - // } - // } - // else - // { - // throw new NullReferenceException("umbraco.content.Instance.XmlContent is null"); - // } - // } - // else - // { - // throw new NullReferenceException("DynamicNode wasn't initialized with an underlying NodeFactory.Node"); - // } - //} - - public bool HasProperty(string name) { - if (_backingItem != null) + if (_document != null) { try { @@ -240,7 +167,7 @@ namespace Umbraco.Core.Dynamics { try { - result = ExecuteExtensionMethod(args, binder.Name, false); + result = ExecuteExtensionMethod(args, binder.Name); return true; } catch (TargetInvocationException) @@ -269,7 +196,7 @@ namespace Umbraco.Core.Dynamics } - private object ExecuteExtensionMethod(object[] args, string name, bool argsContainsThis) + private object ExecuteExtensionMethod(object[] args, string name) { object result = null; @@ -350,7 +277,7 @@ namespace Umbraco.Core.Dynamics protected virtual Attempt TryGetChildrenByAlias(GetMemberBinder binder) { - var filteredTypeChildren = _backingItem.Children + var filteredTypeChildren = _document.Children .Where(x => x.DocumentTypeAlias.InvariantEquals(binder.Name) || x.DocumentTypeAlias.MakePluralName().InvariantEquals(binder.Name)) .ToArray(); if (filteredTypeChildren.Any()) @@ -403,7 +330,7 @@ namespace Umbraco.Core.Dynamics var result = userProperty.Value; - if (_backingItem.DocumentTypeAlias == null && userProperty.Alias == null) + if (_document.DocumentTypeAlias == null && userProperty.Alias == null) { throw new InvalidOperationException("No node alias or property alias available. Unable to look up the datatype of the property you are trying to fetch."); } @@ -496,7 +423,7 @@ namespace Umbraco.Core.Dynamics /// private PropertyResult GetReflectedProperty(string alias) { - return GetPropertyInternal(alias, _backingItem, false); + return GetPropertyInternal(alias, _document, false); } /// @@ -509,15 +436,15 @@ namespace Umbraco.Core.Dynamics { if (!recursive) { - return GetPropertyInternal(alias, _backingItem); + return GetPropertyInternal(alias, _document); } var context = this; - var prop = GetPropertyInternal(alias, _backingItem); + var prop = GetPropertyInternal(alias, _document); while (prop == null || !prop.HasValue()) { context = context.Parent; if (context == null) break; - prop = context.GetPropertyInternal(alias, context._backingItem); + prop = context.GetPropertyInternal(alias, context._document); } return prop; } @@ -830,7 +757,7 @@ namespace Umbraco.Core.Dynamics } internal DynamicDocumentList Descendants(Func func) { - var flattenedNodes = this._backingItem.Children.Map(func, (IDocument n) => n.Children); + var flattenedNodes = this._document.Children.Map(func, (IDocument n) => n.Children); return new DynamicDocumentList(flattenedNodes.ToList().ConvertAll(dynamicBackingItem => new DynamicDocument(dynamicBackingItem))); } public DynamicDocumentList DescendantsOrSelf(int level) @@ -847,14 +774,14 @@ namespace Umbraco.Core.Dynamics } internal DynamicDocumentList DescendantsOrSelf(Func func) { - if (this._backingItem != null) + if (this._document != null) { var thisNode = new List(); - if (func(this._backingItem)) + if (func(this._document)) { - thisNode.Add(this._backingItem); + thisNode.Add(this._document); } - var flattenedNodes = this._backingItem.Children.Map(func, (IDocument n) => n.Children); + var flattenedNodes = this._document.Children.Map(func, (IDocument n) => n.Children); return new DynamicDocumentList(thisNode.Concat(flattenedNodes).ToList().ConvertAll(dynamicBackingItem => new DynamicDocument(dynamicBackingItem))); } return new DynamicDocumentList(Enumerable.Empty()); @@ -906,11 +833,11 @@ namespace Umbraco.Core.Dynamics { get { - if (_backingItem.Parent != null) + if (_document.Parent != null) { - return new DynamicDocument(_backingItem.Parent); + return new DynamicDocument(_document.Parent); } - if (_backingItem != null && _backingItem.Id == 0) + if (_document != null && _document.Id == 0) { return this; } @@ -920,17 +847,17 @@ namespace Umbraco.Core.Dynamics public int TemplateId { - get { return _backingItem.TemplateId; } + get { return _document.TemplateId; } } public int SortOrder { - get { return _backingItem.SortOrder; } + get { return _document.SortOrder; } } public string Name { - get { return _backingItem.Name; } + get { return _document.Name; } } public bool Visible { @@ -948,66 +875,66 @@ namespace Umbraco.Core.Dynamics public string UrlName { - get { return _backingItem.UrlName; } + get { return _document.UrlName; } } public string DocumentTypeAlias { - get { return _backingItem.DocumentTypeAlias; } + get { return _document.DocumentTypeAlias; } } public string WriterName { - get { return _backingItem.WriterName; } + get { return _document.WriterName; } } public string CreatorName { - get { return _backingItem.CreatorName; } + get { return _document.CreatorName; } } public int WriterId { - get { return _backingItem.WriterId; } + get { return _document.WriterId; } } public int CreatorId { - get { return _backingItem.CreatorId; } + get { return _document.CreatorId; } } public string Path { - get { return _backingItem.Path; } + get { return _document.Path; } } public DateTime CreateDate { - get { return _backingItem.CreateDate; } + get { return _document.CreateDate; } } public int Id { - get { return _backingItem.Id; } + get { return _document.Id; } } public DateTime UpdateDate { - get { return _backingItem.UpdateDate; } + get { return _document.UpdateDate; } } public Guid Version { - get { return _backingItem.Version; } + get { return _document.Version; } } public int Level { - get { return _backingItem.Level; } + get { return _document.Level; } } public IEnumerable Properties { - get { return _backingItem.Properties; } + get { return _document.Properties; } } public IEnumerable Children @@ -1016,15 +943,15 @@ namespace Umbraco.Core.Dynamics { if (_cachedChildren == null) { - var children = _backingItem.Children; + var children = _document.Children; //testing, think this must be a special case for the root node ? - if (!children.Any() && _backingItem.Id == 0) + if (!children.Any() && _document.Id == 0) { - _cachedChildren = new DynamicDocumentList(new List { new DynamicDocument(this._backingItem) }); + _cachedChildren = new DynamicDocumentList(new List { new DynamicDocument(this._document) }); } else { - _cachedChildren = new DynamicDocumentList(_backingItem.Children.Select(x => new DynamicDocument(x))); + _cachedChildren = new DynamicDocumentList(_document.Children.Select(x => new DynamicDocument(x))); } } return _cachedChildren; diff --git a/src/Umbraco.Core/Dynamics/PropertyResult.cs b/src/Umbraco.Core/Dynamics/PropertyResult.cs index ebefc76ea5..bcabfd05e4 100644 --- a/src/Umbraco.Core/Dynamics/PropertyResult.cs +++ b/src/Umbraco.Core/Dynamics/PropertyResult.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Dynamics { internal class PropertyResult : IDocumentProperty, IHtmlString { - public PropertyResult(IDocumentProperty source, PropertyResultType type) + internal PropertyResult(IDocumentProperty source, PropertyResultType type) { if (source == null) throw new ArgumentNullException("source"); @@ -16,7 +16,7 @@ namespace Umbraco.Core.Dynamics Version = source.Version; PropertyType = type; } - public PropertyResult(string alias, object value, Guid version, PropertyResultType type) + internal PropertyResult(string alias, object value, Guid version, PropertyResultType type) { if (alias == null) throw new ArgumentNullException("alias"); if (value == null) throw new ArgumentNullException("value"); @@ -32,10 +32,16 @@ namespace Umbraco.Core.Dynamics public string Alias { get; private set; } public object Value { get; private set; } - - public string ValueAsString + + /// + /// Returns the value as a string output, this is used in the final rendering process of a property + /// + internal string ValueAsString { - get { return Value == null ? "" : Convert.ToString(Value); } + get + { + return Value == null ? "" : Convert.ToString(Value); + } } public Guid Version { get; private set; } diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index 1defb0562e..d5a5e2e452 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -9,12 +9,14 @@ using System.Configuration; using System.Web; using System.Text.RegularExpressions; using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; namespace Umbraco.Core.IO { internal static class IOHelper { private static string _rootDir = ""; + // static compiled regex for faster performance private readonly static Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); @@ -49,46 +51,33 @@ namespace Umbraco.Core.IO return VirtualPathUtility.ToAbsolute(virtualPath, SystemDirectories.Root); } - + [Obsolete("Use Umbraco.Web.Templates.TemplateUtilities.ResolveUrlsFromTextString instead, this method on this class will be removed in future versions")] public static string ResolveUrlsFromTextString(string text) { if (UmbracoSettings.ResolveUrlsFromTextString) - { - var sw = new Stopwatch(); - sw.Start(); - Debug.WriteLine("Start: " + sw.ElapsedMilliseconds); - - // find all relative urls (ie. urls that contain ~) - var tags = - ResolveUrlPattern.Matches(text); - Debug.WriteLine("After regex: " + sw.ElapsedMilliseconds); - foreach (Match tag in tags) - { - Debug.WriteLine("-- inside regex: " + sw.ElapsedMilliseconds); - string url = ""; - if (tag.Groups[1].Success) - url = tag.Groups[1].Value; - - // The richtext editor inserts a slash in front of the url. That's why we need this little fix - // if (url.StartsWith("/")) - // text = text.Replace(url, ResolveUrl(url.Substring(1))); - // else - if (!String.IsNullOrEmpty(url)) - { - Debug.WriteLine("---- before resolve: " + sw.ElapsedMilliseconds); - string resolvedUrl = (url.Substring(0, 1) == "/") ? ResolveUrl(url.Substring(1)) : ResolveUrl(url); - Debug.WriteLine("---- after resolve: " + sw.ElapsedMilliseconds); - Debug.WriteLine("---- before replace: " + sw.ElapsedMilliseconds); - text = text.Replace(url, resolvedUrl); - Debug.WriteLine("---- after replace: " + sw.ElapsedMilliseconds); - } - - } - - Debug.WriteLine("total: " + sw.ElapsedMilliseconds); - sw.Stop(); - Debug.WriteLine("Resolve Urls", sw.ElapsedMilliseconds.ToString()); + { + using (var timer = DisposableTimer.DebugDuration(typeof(IOHelper), "ResolveUrlsFromTextString starting", "ResolveUrlsFromTextString complete")) + { + // find all relative urls (ie. urls that contain ~) + var tags = ResolveUrlPattern.Matches(text); + LogHelper.Debug(typeof(IOHelper), "After regex: " + timer.Stopwatch.ElapsedMilliseconds + " matched: " + tags.Count); + foreach (Match tag in tags) + { + string url = ""; + if (tag.Groups[1].Success) + url = tag.Groups[1].Value; + // The richtext editor inserts a slash in front of the url. That's why we need this little fix + // if (url.StartsWith("/")) + // text = text.Replace(url, ResolveUrl(url.Substring(1))); + // else + if (!String.IsNullOrEmpty(url)) + { + string resolvedUrl = (url.Substring(0, 1) == "/") ? ResolveUrl(url.Substring(1)) : ResolveUrl(url); + text = text.Replace(url, resolvedUrl); + } + } + } } return text; } diff --git a/src/Umbraco.Core/IO/SystemDirectories.cs b/src/Umbraco.Core/IO/SystemDirectories.cs index 1fc9a98c40..521407898a 100644 --- a/src/Umbraco.Core/IO/SystemDirectories.cs +++ b/src/Umbraco.Core/IO/SystemDirectories.cs @@ -10,7 +10,7 @@ using System.IO; namespace Umbraco.Core.IO { //all paths has a starting but no trailing / - internal class SystemDirectories + public class SystemDirectories { public static string Bin { diff --git a/src/Umbraco.Core/IO/SystemFiles.cs b/src/Umbraco.Core/IO/SystemFiles.cs index 59b2debf0a..f8a7a368e5 100644 --- a/src/Umbraco.Core/IO/SystemFiles.cs +++ b/src/Umbraco.Core/IO/SystemFiles.cs @@ -8,7 +8,7 @@ using System.Web; namespace Umbraco.Core.IO { - internal class SystemFiles + public class SystemFiles { public static string AccessXml @@ -96,7 +96,7 @@ namespace Umbraco.Core.IO { get { - if (ContentCacheXmlIsEphemeral) + if (ContentCacheXmlIsEphemeral && SystemUtilities.GetCurrentTrustLevel() == AspNetHostingPermissionLevel.Unrestricted) { return Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco.config"); } @@ -104,7 +104,7 @@ namespace Umbraco.Core.IO } } - public static bool ContentCacheXmlIsEphemeral + internal static bool ContentCacheXmlIsEphemeral { get { diff --git a/src/Umbraco.Web/Models/XmlDocumentProperty.cs b/src/Umbraco.Web/Models/XmlDocumentProperty.cs index 110e01d723..7affc17852 100644 --- a/src/Umbraco.Web/Models/XmlDocumentProperty.cs +++ b/src/Umbraco.Web/Models/XmlDocumentProperty.cs @@ -5,6 +5,7 @@ using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Models; +using Umbraco.Web.Templates; namespace Umbraco.Web.Models { @@ -25,9 +26,27 @@ namespace Umbraco.Web.Models get { return _alias; } } + private string _parsedValue; + + /// + /// Returns the value of a property from the XML cache + /// + /// + /// This ensures that the result has any {localLink} syntax parsed and that urls are resolved correctly. + /// This also ensures that the parsing is only done once as the result is cached in a private field of this object. + /// public object Value { - get { return IOHelper.ResolveUrlsFromTextString(_value); } + get + { + if (_parsedValue == null) + { + _parsedValue = TemplateUtilities.ResolveUrlsFromTextString( + TemplateUtilities.ParseInternalLinks( + _value)); + } + return _parsedValue; + } } public Guid Version diff --git a/src/Umbraco.Web/Mvc/RenderViewPage.cs b/src/Umbraco.Web/Mvc/RenderViewPage.cs index 61568e8ecf..8dcf775672 100644 --- a/src/Umbraco.Web/Mvc/RenderViewPage.cs +++ b/src/Umbraco.Web/Mvc/RenderViewPage.cs @@ -71,10 +71,5 @@ namespace Umbraco.Web.Mvc get { return _helper ?? (_helper = new UmbracoHelper(UmbracoContext)); } } - public override void Write(object value) - { - base.Write(value); - } - } } \ No newline at end of file diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs index a46e1673b6..6e55c42c2c 100644 --- a/src/Umbraco.Web/Templates/TemplateUtilities.cs +++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs @@ -1,5 +1,10 @@ -using System.Text.RegularExpressions; +using System; +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 { @@ -32,6 +37,47 @@ namespace Umbraco.Web.Templates return text; } + // static compiled regex for faster performance + private readonly static Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + + /// + /// The RegEx matches any HTML attribute values that start with a tilde (~), those that match are passed to ResolveUrl to replace the tilde with the application path. + /// + /// + /// + /// + /// When used with a Virtual-Directory set-up, this would resolve all URLs correctly. + /// The recommendation is that the "ResolveUrlsFromTextString" option (in umbracoSettings.config) is set to false for non-Virtual-Directory installs. + /// + public static string ResolveUrlsFromTextString(string text) + { + if (UmbracoSettings.ResolveUrlsFromTextString) + { + using (var timer = DisposableTimer.DebugDuration(typeof(IOHelper), "ResolveUrlsFromTextString starting", "ResolveUrlsFromTextString complete")) + { + // find all relative urls (ie. urls that contain ~) + var tags = ResolveUrlPattern.Matches(text); + LogHelper.Debug(typeof(IOHelper), "After regex: " + timer.Stopwatch.ElapsedMilliseconds + " matched: " + tags.Count); + foreach (Match tag in tags) + { + string url = ""; + if (tag.Groups[1].Success) + url = tag.Groups[1].Value; + + // The richtext editor inserts a slash in front of the url. That's why we need this little fix + // if (url.StartsWith("/")) + // text = text.Replace(url, ResolveUrl(url.Substring(1))); + // else + if (!String.IsNullOrEmpty(url)) + { + string resolvedUrl = (url.Substring(0, 1) == "/") ? IOHelper.ResolveUrl(url.Substring(1)) : ResolveUrl(url); + text = text.Replace(url, resolvedUrl); + } + } + } + } + return text; + } } } diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index 75bdf4e7f2..2de4c1d2b8 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -17,6 +17,7 @@ using System.Web.UI.WebControls; using System.Xml; using System.Xml.Xsl; using Umbraco.Core; +using Umbraco.Web.Templates; using umbraco.BusinessLogic; using umbraco.BusinessLogic.Utils; using umbraco.cms.businesslogic.macro; @@ -757,7 +758,7 @@ namespace umbraco // Do transformation UmbracoContext.Current.Trace.Write("umbracoMacro", "Before performing transformation"); xslt.Transform(macroXML.CreateNavigator(), xslArgs, tw); - return IOHelper.ResolveUrlsFromTextString(tw.ToString()); + return TemplateUtilities.ResolveUrlsFromTextString(tw.ToString()); } public static XsltArgumentList AddXsltExtensions() diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/nodeFactory/Page_Legacy.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/nodeFactory/Page_Legacy.cs index c758cb9373..af162f6681 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/nodeFactory/Page_Legacy.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/nodeFactory/Page_Legacy.cs @@ -4,6 +4,7 @@ using System.Data; using System.Xml; using System.Xml.Serialization; using System.Xml.XPath; +using Umbraco.Web.Templates; using umbraco.cms.businesslogic; using umbraco.cms.businesslogic.propertytype; @@ -543,9 +544,11 @@ namespace umbraco.presentation.nodeFactory get { return _alias; } } + private string _parsedValue; + public string Value { - get { return IO.IOHelper.ResolveUrlsFromTextString(_value); } + get { return _parsedValue ?? (_parsedValue = TemplateUtilities.ResolveUrlsFromTextString(_value)); } } public Guid Version diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/nodeFactory/Property.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/nodeFactory/Property.cs index 7e06cac940..caee1f6689 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/nodeFactory/Property.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/nodeFactory/Property.cs @@ -1,6 +1,7 @@ using System; using System.Xml; using System.Xml.Serialization; +using Umbraco.Web.Templates; using umbraco.interfaces; namespace umbraco.NodeFactory @@ -18,9 +19,10 @@ namespace umbraco.NodeFactory get { return _alias; } } + private string _parsedValue; public string Value { - get { return IO.IOHelper.ResolveUrlsFromTextString(_value); } + get { return _parsedValue ?? (_parsedValue = TemplateUtilities.ResolveUrlsFromTextString(_value)); } } public Guid Version diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/ItemRenderer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/ItemRenderer.cs index bedcc3a4cc..7a0b7a50f9 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/ItemRenderer.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/ItemRenderer.cs @@ -8,6 +8,7 @@ using System.Web; using System.Web.UI; using System.Xml; using Umbraco.Core.Macros; +using Umbraco.Web.Templates; using umbraco.cms.businesslogic; using umbraco.cms.businesslogic.property; using umbraco.cms.businesslogic.web; @@ -65,7 +66,7 @@ namespace umbraco.presentation.templateControls // handle text before/after xsltTransformedOutput = AddBeforeAfterText(xsltTransformedOutput, helper.FindAttribute(item.LegacyAttributes, "insertTextBefore"), helper.FindAttribute(item.LegacyAttributes, "insertTextAfter")); string finalResult = xsltTransformedOutput.Trim().Length > 0 ? xsltTransformedOutput : GetEmptyText(item); - writer.Write(IOHelper.ResolveUrlsFromTextString(finalResult)); + writer.Write(TemplateUtilities.ResolveUrlsFromTextString(finalResult)); } catch (Exception renderException) { diff --git a/src/umbraco.businesslogic/IO/IOHelper.cs b/src/umbraco.businesslogic/IO/IOHelper.cs index 8bc3f886b2..3679e1cdfa 100644 --- a/src/umbraco.businesslogic/IO/IOHelper.cs +++ b/src/umbraco.businesslogic/IO/IOHelper.cs @@ -36,7 +36,7 @@ namespace umbraco.IO return Umbraco.Core.IO.IOHelper.ResolveUrl(virtualPath); } - + [Obsolete("Use Umbraco.Web.Templates.TemplateUtilities.ResolveUrlsFromTextString instead, this method on this class will be removed in future versions")] public static string ResolveUrlsFromTextString(string text) { return Umbraco.Core.IO.IOHelper.ResolveUrlsFromTextString(text);