Changed IPublishedContentStore and IPublishedMediaStore back to internal as we don't need to expose these yet. Instead have added
an UmbracoHelper property to the PluginController class which will expose any methods needed by devs to retreive media or content. Have updated UmbracoHelper with loads of new helpful methods and moved the Wrap methods to HtmlHelper extensions because this is purely to do with rendering html (have written unit tests for it too). Updated some 'library' methods to proxy calls to UmbracoHelper so we only have to maintain one set of code. Added a convenience property to UmbracoContext to return the current NiceUrlProvider so you don't have to go through the RoutingContext to get it.
This commit is contained in:
33
src/Umbraco.Tests/HtmlHelperExtensionMethodsTests.cs
Normal file
33
src/Umbraco.Tests/HtmlHelperExtensionMethodsTests.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Web.Mvc;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Web;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class HtmlHelperExtensionMethodsTests
|
||||
{
|
||||
[SetUp]
|
||||
public virtual void Initialize()
|
||||
{
|
||||
//create an empty htmlHelper
|
||||
_htmlHelper = new HtmlHelper(new ViewContext(), new ViewPage());
|
||||
}
|
||||
|
||||
private HtmlHelper _htmlHelper;
|
||||
|
||||
[Test]
|
||||
public void Wrap_Simple()
|
||||
{
|
||||
var output = _htmlHelper.Wrap("div", "hello world");
|
||||
Assert.AreEqual("<div>hello world</div>", output.ToHtmlString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Wrap_Object_Attributes()
|
||||
{
|
||||
var output = _htmlHelper.Wrap("div", "hello world", new {style = "color:red;", onclick = "void();"});
|
||||
Assert.AreEqual("<div style=\"color:red;\" onclick=\"void();\">hello world</div>", output.ToHtmlString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Web.Mvc;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="ContentStores\PublishMediaStoreTests.cs" />
|
||||
<Compile Include="DynamicDocument\DocumentTests.cs" />
|
||||
<Compile Include="HtmlHelperExtensionMethodsTests.cs" />
|
||||
<Compile Include="Resolvers\ActionsResolverTests.cs" />
|
||||
<Compile Include="AsynchronousRollingFileAppenderTests.cs" />
|
||||
<Compile Include="BusinessLogic\ApplicationTest.cs" />
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<add key="umbracoDbDSN" value="server=.\sqlexpress;database=v4;user id=sa;password=test;Application Name=Umbraco41"/>
|
||||
<add key="umbracoConfigurationStatus" value="4.10.0"/>
|
||||
<add key="umbracoReservedUrls" value="~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd" />
|
||||
<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/account/" />
|
||||
<add key="umbracoReservedPaths" value="~/umbraco,~/install/" />
|
||||
<add key="umbracoContentXML" value="~/App_Data/umbraco.config"/>
|
||||
<add key="umbracoStorageDirectory" value="~/App_Data"/>
|
||||
<add key="umbracoPath" value="~/umbraco" />
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Text;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Mvc.Html;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Dynamics;
|
||||
using Umbraco.Web.Mvc;
|
||||
using umbraco;
|
||||
|
||||
@@ -16,59 +17,6 @@ namespace Umbraco.Web
|
||||
/// </summary>
|
||||
public static class HtmlHelperRenderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for rendering out the Form for BeginUmbracoForm
|
||||
/// </summary>
|
||||
internal class UmbracoForm : MvcForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an UmbracoForm
|
||||
/// </summary>
|
||||
/// <param name="viewContext"></param>
|
||||
/// <param name="surfaceController"></param>
|
||||
/// <param name="surfaceAction"></param>
|
||||
/// <param name="area"></param>
|
||||
/// <param name="additionalRouteVals"></param>
|
||||
public UmbracoForm(
|
||||
ViewContext viewContext,
|
||||
string surfaceController,
|
||||
string surfaceAction,
|
||||
string area,
|
||||
object additionalRouteVals = null)
|
||||
: base(viewContext)
|
||||
{
|
||||
//need to create a params string as Base64 to put into our hidden field to use during the routes
|
||||
var surfaceRouteParams = string.Format("c={0}&a={1}&ar={2}",
|
||||
viewContext.HttpContext.Server.UrlEncode(surfaceController),
|
||||
viewContext.HttpContext.Server.UrlEncode(surfaceAction),
|
||||
area);
|
||||
|
||||
var additionalRouteValsAsQuery = additionalRouteVals.ToDictionary<object>().ToQueryString();
|
||||
if (!additionalRouteValsAsQuery.IsNullOrWhiteSpace())
|
||||
surfaceRouteParams = "&" + additionalRouteValsAsQuery;
|
||||
|
||||
_base64String = Convert.ToBase64String(Encoding.UTF8.GetBytes(surfaceRouteParams));
|
||||
|
||||
_textWriter = viewContext.Writer;
|
||||
}
|
||||
|
||||
|
||||
private bool _disposed;
|
||||
private readonly string _base64String;
|
||||
private readonly TextWriter _textWriter;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (this._disposed)
|
||||
return;
|
||||
this._disposed = true;
|
||||
|
||||
//write out the hidden surface form routes
|
||||
_textWriter.Write("<input name='uformpostroutevals' type='hidden' value='" + _base64String + "' />");
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
public static MvcHtmlString EditorFor<T>(this HtmlHelper htmlHelper, string templateName = "", string htmlFieldName = "", object additionalViewData = null)
|
||||
where T : new()
|
||||
@@ -108,6 +56,63 @@ namespace Umbraco.Web
|
||||
return filteredHtmlHelper.ValidationSummary(excludePropertyErrors, message, htmlAttributes);
|
||||
}
|
||||
|
||||
#region BeginUmbracoForm
|
||||
|
||||
/// <summary>
|
||||
/// Used for rendering out the Form for BeginUmbracoForm
|
||||
/// </summary>
|
||||
internal class UmbracoForm : MvcForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an UmbracoForm
|
||||
/// </summary>
|
||||
/// <param name="viewContext"></param>
|
||||
/// <param name="surfaceController"></param>
|
||||
/// <param name="surfaceAction"></param>
|
||||
/// <param name="area"></param>
|
||||
/// <param name="additionalRouteVals"></param>
|
||||
public UmbracoForm(
|
||||
ViewContext viewContext,
|
||||
string surfaceController,
|
||||
string surfaceAction,
|
||||
string area,
|
||||
object additionalRouteVals = null)
|
||||
: base(viewContext)
|
||||
{
|
||||
//need to create a params string as Base64 to put into our hidden field to use during the routes
|
||||
var surfaceRouteParams = string.Format("c={0}&a={1}&ar={2}",
|
||||
viewContext.HttpContext.Server.UrlEncode(surfaceController),
|
||||
viewContext.HttpContext.Server.UrlEncode(surfaceAction),
|
||||
area);
|
||||
|
||||
var additionalRouteValsAsQuery = additionalRouteVals.ToDictionary<object>().ToQueryString();
|
||||
if (!additionalRouteValsAsQuery.IsNullOrWhiteSpace())
|
||||
surfaceRouteParams = "&" + additionalRouteValsAsQuery;
|
||||
|
||||
_base64String = Convert.ToBase64String(Encoding.UTF8.GetBytes(surfaceRouteParams));
|
||||
|
||||
_textWriter = viewContext.Writer;
|
||||
}
|
||||
|
||||
|
||||
private bool _disposed;
|
||||
private readonly string _base64String;
|
||||
private readonly TextWriter _textWriter;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (this._disposed)
|
||||
return;
|
||||
this._disposed = true;
|
||||
|
||||
//write out the hidden surface form routes
|
||||
_textWriter.Write("<input name='uformpostroutevals' type='hidden' value='" + _base64String + "' />");
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
|
||||
/// </summary>
|
||||
@@ -143,8 +148,8 @@ namespace Umbraco.Web
|
||||
/// <param name="htmlAttributes"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName,
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes)
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes)
|
||||
{
|
||||
return html.BeginUmbracoForm(action, controllerName, additionalRouteVals, htmlAttributes.ToDictionary<object>());
|
||||
}
|
||||
@@ -159,11 +164,11 @@ namespace Umbraco.Web
|
||||
/// <param name="htmlAttributes"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName,
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes)
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
Mandate.ParameterNotNullOrEmpty(action, "action");
|
||||
Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName");
|
||||
Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName");
|
||||
|
||||
var area = Umbraco.Core.Configuration.GlobalSettings.UmbracoMvcArea;
|
||||
return html.BeginUmbracoForm(action, controllerName, area, additionalRouteVals, htmlAttributes);
|
||||
@@ -189,9 +194,9 @@ namespace Umbraco.Web
|
||||
/// <param name="action"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action)
|
||||
where T: SurfaceController
|
||||
where T : SurfaceController
|
||||
{
|
||||
return html.BeginUmbracoForm(action, typeof (T));
|
||||
return html.BeginUmbracoForm(action, typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -203,7 +208,7 @@ namespace Umbraco.Web
|
||||
/// <param name="additionalRouteVals"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType,
|
||||
object additionalRouteVals)
|
||||
object additionalRouteVals)
|
||||
{
|
||||
return html.BeginUmbracoForm(action, surfaceType, additionalRouteVals, new Dictionary<string, object>());
|
||||
}
|
||||
@@ -219,7 +224,7 @@ namespace Umbraco.Web
|
||||
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action, object additionalRouteVals)
|
||||
where T : SurfaceController
|
||||
{
|
||||
return html.BeginUmbracoForm(action, typeof (T), additionalRouteVals);
|
||||
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -232,8 +237,8 @@ namespace Umbraco.Web
|
||||
/// <param name="htmlAttributes"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType,
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes)
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes)
|
||||
{
|
||||
return html.BeginUmbracoForm(action, surfaceType, additionalRouteVals, htmlAttributes.ToDictionary<object>());
|
||||
}
|
||||
@@ -247,12 +252,12 @@ namespace Umbraco.Web
|
||||
/// <param name="additionalRouteVals"></param>
|
||||
/// <param name="htmlAttributes"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action,
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes)
|
||||
where T: SurfaceController
|
||||
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action,
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes)
|
||||
where T : SurfaceController
|
||||
{
|
||||
return html.BeginUmbracoForm(action, typeof (T), additionalRouteVals, htmlAttributes);
|
||||
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals, htmlAttributes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -265,9 +270,9 @@ namespace Umbraco.Web
|
||||
/// <param name="htmlAttributes"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType,
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
Mandate.ParameterNotNullOrEmpty(action, "action");
|
||||
Mandate.ParameterNotNull(surfaceType, "surfaceType");
|
||||
|
||||
@@ -279,7 +284,7 @@ namespace Umbraco.Web
|
||||
if (!surfaceController.Metadata.AreaName.IsNullOrWhiteSpace())
|
||||
{
|
||||
//set the area to the plugin area
|
||||
area = surfaceController.Metadata.AreaName;
|
||||
area = surfaceController.Metadata.AreaName;
|
||||
}
|
||||
return html.BeginUmbracoForm(action, surfaceController.Metadata.ControllerName, area, additionalRouteVals, htmlAttributes);
|
||||
}
|
||||
@@ -293,12 +298,12 @@ namespace Umbraco.Web
|
||||
/// <param name="additionalRouteVals"></param>
|
||||
/// <param name="htmlAttributes"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action,
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes)
|
||||
where T: SurfaceController
|
||||
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action,
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes)
|
||||
where T : SurfaceController
|
||||
{
|
||||
return html.BeginUmbracoForm(action, typeof (T), additionalRouteVals, htmlAttributes);
|
||||
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals, htmlAttributes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -339,13 +344,13 @@ namespace Umbraco.Web
|
||||
/// This code is pretty much the same as the underlying MVC code that writes out the form
|
||||
/// </remarks>
|
||||
private static MvcForm RenderForm(this HtmlHelper htmlHelper,
|
||||
string formAction,
|
||||
FormMethod method,
|
||||
IDictionary<string, object> htmlAttributes,
|
||||
string surfaceController,
|
||||
string surfaceAction,
|
||||
string area,
|
||||
object additionalRouteVals = null)
|
||||
string formAction,
|
||||
FormMethod method,
|
||||
IDictionary<string, object> htmlAttributes,
|
||||
string surfaceController,
|
||||
string surfaceAction,
|
||||
string area,
|
||||
object additionalRouteVals = null)
|
||||
{
|
||||
|
||||
var tagBuilder = new TagBuilder("form");
|
||||
@@ -372,6 +377,75 @@ namespace Umbraco.Web
|
||||
return theForm;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Wrap
|
||||
|
||||
public static HtmlTagWrapper Wrap(this HtmlHelper html, string tag, string innerText, params IHtmlTagWrapper[] children)
|
||||
{
|
||||
var item = html.Wrap(tag, innerText, (object)null);
|
||||
foreach (var child in children)
|
||||
{
|
||||
item.AddChild(child);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public static HtmlTagWrapper Wrap(this HtmlHelper html, string tag, object inner, object anonymousAttributes, params IHtmlTagWrapper[] children)
|
||||
{
|
||||
string innerText = null;
|
||||
if (inner != null && inner.GetType() != typeof(DynamicNull))
|
||||
{
|
||||
innerText = string.Format("{0}", inner);
|
||||
}
|
||||
var item = html.Wrap(tag, innerText, anonymousAttributes);
|
||||
foreach (var child in children)
|
||||
{
|
||||
item.AddChild(child);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
public static HtmlTagWrapper Wrap(this HtmlHelper html, string tag, object inner)
|
||||
{
|
||||
string innerText = null;
|
||||
if (inner != null && inner.GetType() != typeof(DynamicNull))
|
||||
{
|
||||
innerText = string.Format("{0}", inner);
|
||||
}
|
||||
return html.Wrap(tag, innerText, (object)null);
|
||||
}
|
||||
|
||||
public static HtmlTagWrapper Wrap(this HtmlHelper html, string tag, string innerText, object anonymousAttributes, params IHtmlTagWrapper[] children)
|
||||
{
|
||||
var wrap = new HtmlTagWrapper(tag);
|
||||
if (anonymousAttributes != null)
|
||||
{
|
||||
wrap.ReflectAttributesFromAnonymousType(anonymousAttributes);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(innerText))
|
||||
{
|
||||
wrap.AddChild(new HtmlTagWrapperTextNode(innerText));
|
||||
}
|
||||
foreach (var child in children)
|
||||
{
|
||||
wrap.AddChild(child);
|
||||
}
|
||||
return wrap;
|
||||
}
|
||||
|
||||
public static HtmlTagWrapper Wrap(this HtmlHelper html, bool visible, string tag, string innerText, object anonymousAttributes, params IHtmlTagWrapper[] children)
|
||||
{
|
||||
var item = html.Wrap(tag, innerText, anonymousAttributes, children);
|
||||
item.Visible = visible;
|
||||
foreach (var child in children)
|
||||
{
|
||||
item.AddChild(child);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Web
|
||||
/// <summary>
|
||||
/// Defines the methods to access published content
|
||||
/// </summary>
|
||||
public interface IPublishedContentStore : IPublishedStore
|
||||
internal interface IPublishedContentStore : IPublishedStore
|
||||
{
|
||||
IDocument GetDocumentByRoute(UmbracoContext umbracoContext, string route, bool? hideTopLevelNode = null);
|
||||
IDocument GetDocumentByUrlAlias(UmbracoContext umbracoContext, int rootNodeId, string alias);
|
||||
|
||||
@@ -3,7 +3,7 @@ namespace Umbraco.Web
|
||||
/// <summary>
|
||||
/// Defines the methods to access published media
|
||||
/// </summary>
|
||||
public interface IPublishedMediaStore : IPublishedStore
|
||||
internal interface IPublishedMediaStore : IPublishedStore
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -25,16 +25,7 @@ namespace Umbraco.Web.Mvc
|
||||
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
|
||||
UmbracoContext = umbracoContext;
|
||||
InstanceId = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public IPublishedContentStore PublishedContentStore
|
||||
{
|
||||
get { return PublishedContentStoreResolver.Current.PublishedContentStore; }
|
||||
}
|
||||
|
||||
public IPublishedMediaStore PublishedMediaStore
|
||||
{
|
||||
get { return PublishedMediaStoreResolver.Current.PublishedMediaStore; }
|
||||
Umbraco = new UmbracoHelper(umbracoContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -42,6 +33,11 @@ namespace Umbraco.Web.Mvc
|
||||
/// </summary>
|
||||
internal Guid InstanceId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns an UmbracoHelper object
|
||||
/// </summary>
|
||||
public UmbracoHelper Umbraco { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current UmbracoContext
|
||||
/// </summary>
|
||||
|
||||
@@ -51,8 +51,6 @@ namespace Umbraco.Web.Mvc
|
||||
/// </summary>
|
||||
public dynamic CurrentPage { get; private set; }
|
||||
|
||||
private ICultureDictionary _cultureDictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the dictionary value for the key specified
|
||||
/// </summary>
|
||||
@@ -60,12 +58,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <returns></returns>
|
||||
public string GetDictionaryValue(string key)
|
||||
{
|
||||
if (_cultureDictionary == null)
|
||||
{
|
||||
var factory = CultureDictionaryFactoryResolver.Current.Factory;
|
||||
_cultureDictionary = factory.CreateDictionary();
|
||||
}
|
||||
return _cultureDictionary[key];
|
||||
return Umbraco.GetDictionaryValue(key);
|
||||
}
|
||||
|
||||
private UmbracoHelper _helper;
|
||||
|
||||
@@ -199,6 +199,22 @@ namespace Umbraco.Web
|
||||
get { return DocumentRequest != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A shortcut to the UmbracoContext's RoutingContext's NiceUrlProvider
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the RoutingContext is null, this will throw an exception.
|
||||
/// </remarks>
|
||||
internal NiceUrlProvider NiceUrlProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
if (RoutingContext == null)
|
||||
throw new InvalidOperationException("Cannot access the NiceUrlProvider when the UmbracoContext's RoutingContext is null");
|
||||
return RoutingContext.NiceUrlProvider;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the RoutingContext object
|
||||
/// </summary>
|
||||
|
||||
@@ -5,22 +5,27 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Security;
|
||||
using System.Web.UI;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using HtmlAgilityPack;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Dynamics;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using umbraco;
|
||||
using System.Collections.Generic;
|
||||
using umbraco.cms.businesslogic.member;
|
||||
using umbraco.cms.businesslogic.web;
|
||||
using umbraco.presentation.templateControls;
|
||||
using HtmlTagWrapper = Umbraco.Web.Mvc.HtmlTagWrapper;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A helper class that provides many useful methods and functionality for using Umbraco in templates
|
||||
/// </summary>
|
||||
@@ -191,7 +196,7 @@ namespace Umbraco.Web
|
||||
var attributesForItem = new AttributeCollectionAdapter(
|
||||
new AttributeCollection(
|
||||
new StateBag()));
|
||||
foreach(var i in attributes)
|
||||
foreach (var i in attributes)
|
||||
{
|
||||
attributesForItem.Add(i.Key, i.Value);
|
||||
}
|
||||
@@ -201,7 +206,7 @@ namespace Umbraco.Web
|
||||
Field = fieldAlias,
|
||||
TextIfEmpty = altText,
|
||||
LegacyAttributes = attributesForItem
|
||||
};
|
||||
};
|
||||
var containerPage = new FormlessPage();
|
||||
containerPage.Controls.Add(item);
|
||||
|
||||
@@ -217,8 +222,120 @@ namespace Umbraco.Web
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dictionary
|
||||
|
||||
private ICultureDictionary _cultureDictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the dictionary value for the key specified
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public string GetDictionaryValue(string key)
|
||||
{
|
||||
if (_cultureDictionary == null)
|
||||
{
|
||||
var factory = CultureDictionaryFactoryResolver.Current.Factory;
|
||||
_cultureDictionary = factory.CreateDictionary();
|
||||
}
|
||||
return _cultureDictionary[key];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Membership
|
||||
|
||||
/// <summary>
|
||||
/// Check if a document object is protected by the "Protect Pages" functionality in umbraco
|
||||
/// </summary>
|
||||
/// <param name="documentId">The identifier of the document object to check</param>
|
||||
/// <param name="path">The full path of the document object to check</param>
|
||||
/// <returns>True if the document object is protected</returns>
|
||||
public bool IsProtected(int documentId, string path)
|
||||
{
|
||||
return Access.IsProtected(documentId, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the current user has access to a document
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The identifier of the document object to check</param>
|
||||
/// <param name="path">The full path of the document object to check</param>
|
||||
/// <returns>True if the current user has access or if the current document isn't protected</returns>
|
||||
public bool MemberHasAccess(int nodeId, string path)
|
||||
{
|
||||
if (IsProtected(nodeId, path))
|
||||
{
|
||||
return Member.IsLoggedOn() && Access.HasAccess(nodeId, path, Membership.GetUser());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the current member is logged in (based on the membership provider)
|
||||
/// </summary>
|
||||
/// <returns>True is the current user is logged in</returns>
|
||||
public bool MemberIsLoggedOn()
|
||||
{
|
||||
/*
|
||||
MembershipUser u = Membership.GetUser();
|
||||
return u != null;
|
||||
*/
|
||||
return Member.IsLoggedOn();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region NiceUrls
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string with a friendly url from a node.
|
||||
/// IE.: Instead of having /482 (id) as an url, you can have
|
||||
/// /screenshots/developer/macros (spoken url)
|
||||
/// </summary>
|
||||
/// <param name="nodeId">Identifier for the node that should be returned</param>
|
||||
/// <returns>String with a friendly url from a node</returns>
|
||||
public string NiceUrl(int nodeId)
|
||||
{
|
||||
var niceUrlsProvider = UmbracoContext.Current.NiceUrlProvider;
|
||||
return niceUrlsProvider.GetNiceUrl(nodeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method will always add the domain to the path if the hostnames are set up correctly.
|
||||
/// </summary>
|
||||
/// <param name="nodeId">Identifier for the node that should be returned</param>
|
||||
/// <returns>String with a friendly url with full domain from a node</returns>
|
||||
public string NiceUrlWithDomain(int nodeId)
|
||||
{
|
||||
var niceUrlsProvider = UmbracoContext.Current.NiceUrlProvider;
|
||||
return niceUrlsProvider.GetNiceUrl(nodeId, UmbracoContext.Current.UmbracoUrl, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content
|
||||
|
||||
public IDocument GetContentById(int id)
|
||||
{
|
||||
return GetDocumentById(id, PublishedContentStoreResolver.Current.PublishedContentStore);
|
||||
}
|
||||
|
||||
public IDocument GetContentById(string id)
|
||||
{
|
||||
return GetDocumentById(id, PublishedContentStoreResolver.Current.PublishedContentStore);
|
||||
}
|
||||
|
||||
public IEnumerable<IDocument> GetContentByIds(params int[] ids)
|
||||
{
|
||||
return GetDocumentByIds(PublishedContentStoreResolver.Current.PublishedContentStore, ids);
|
||||
}
|
||||
|
||||
public IEnumerable<IDocument> GetContentByIds(params string[] ids)
|
||||
{
|
||||
return GetDocumentByIds(PublishedContentStoreResolver.Current.PublishedContentStore, ids);
|
||||
}
|
||||
|
||||
public dynamic ContentById(int id)
|
||||
{
|
||||
return DocumentById(id, PublishedContentStoreResolver.Current.PublishedContentStore);
|
||||
@@ -238,11 +355,31 @@ namespace Umbraco.Web
|
||||
{
|
||||
return DocumentByIds(PublishedContentStoreResolver.Current.PublishedContentStore, ids);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Media
|
||||
|
||||
public IDocument GetMediaById(int id)
|
||||
{
|
||||
return GetDocumentById(id, PublishedMediaStoreResolver.Current.PublishedMediaStore);
|
||||
}
|
||||
|
||||
public IDocument GetMediaById(string id)
|
||||
{
|
||||
return GetDocumentById(id, PublishedMediaStoreResolver.Current.PublishedMediaStore);
|
||||
}
|
||||
|
||||
public IEnumerable<IDocument> GetMediaByIds(params int[] ids)
|
||||
{
|
||||
return GetDocumentByIds(PublishedMediaStoreResolver.Current.PublishedMediaStore, ids);
|
||||
}
|
||||
|
||||
public IEnumerable<IDocument> GetMediaByIds(params string[] ids)
|
||||
{
|
||||
return GetDocumentByIds(PublishedMediaStoreResolver.Current.PublishedMediaStore, ids);
|
||||
}
|
||||
|
||||
public dynamic MediaById(int id)
|
||||
{
|
||||
return DocumentById(id, PublishedMediaStoreResolver.Current.PublishedMediaStore);
|
||||
@@ -267,6 +404,29 @@ namespace Umbraco.Web
|
||||
|
||||
#region Used by Content/Media
|
||||
|
||||
private IDocument GetDocumentById(int id, IPublishedStore store)
|
||||
{
|
||||
return store.GetDocumentById(UmbracoContext.Current, id);
|
||||
}
|
||||
|
||||
private IDocument GetDocumentById(string id, IPublishedStore store)
|
||||
{
|
||||
int docId;
|
||||
return int.TryParse(id, out docId)
|
||||
? DocumentById(docId, store)
|
||||
: null;
|
||||
}
|
||||
|
||||
private IEnumerable<IDocument> GetDocumentByIds(IPublishedStore store, params int[] ids)
|
||||
{
|
||||
return ids.Select(eachId => GetDocumentById(eachId, store));
|
||||
}
|
||||
|
||||
private IEnumerable<IDocument> GetDocumentByIds(IPublishedStore store, params string[] ids)
|
||||
{
|
||||
return ids.Select(eachId => GetDocumentById(eachId, store));
|
||||
}
|
||||
|
||||
private dynamic DocumentById(int id, IPublishedStore store)
|
||||
{
|
||||
var doc = store.GetDocumentById(UmbracoContext.Current, id);
|
||||
@@ -278,8 +438,8 @@ namespace Umbraco.Web
|
||||
private dynamic DocumentById(string id, IPublishedStore store)
|
||||
{
|
||||
int docId;
|
||||
return int.TryParse(id, out docId)
|
||||
? DocumentById(docId, store)
|
||||
return int.TryParse(id, out docId)
|
||||
? DocumentById(docId, store)
|
||||
: new DynamicNull();
|
||||
}
|
||||
|
||||
@@ -361,6 +521,29 @@ namespace Umbraco.Web
|
||||
|
||||
#region Strings
|
||||
|
||||
/// <summary>
|
||||
/// Replaces text line breaks with html line breaks
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <returns>The text with text line breaks replaced with html linebreaks (<br/>)</returns>
|
||||
public string ReplaceLineBreaksForHtml(string text)
|
||||
{
|
||||
if (bool.Parse(Umbraco.Core.Configuration.GlobalSettings.EditXhtmlMode))
|
||||
return text.Replace("\n", "<br/>\n");
|
||||
else
|
||||
return text.Replace("\n", "<br />\n");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an MD5 hash of the string specified
|
||||
/// </summary>
|
||||
/// <param name="text">The text to create a hash from</param>
|
||||
/// <returns>Md5 has of the string</returns>
|
||||
public string CreateMd5Hash(string text)
|
||||
{
|
||||
return text.ToMd5();
|
||||
}
|
||||
|
||||
public HtmlString StripHtml(IHtmlString html, params string[] tags)
|
||||
{
|
||||
return StripHtml(html.ToHtmlString(), tags);
|
||||
@@ -445,7 +628,7 @@ namespace Umbraco.Web
|
||||
|
||||
internal string Join<TIgnore>(string seperator, params object[] args)
|
||||
{
|
||||
var results = args.Where(arg => arg != null && arg.GetType() != typeof (TIgnore)).Select(arg => string.Format("{0}", arg)).Where(sArg => !string.IsNullOrWhiteSpace(sArg)).ToList();
|
||||
var results = args.Where(arg => arg != null && arg.GetType() != typeof(TIgnore)).Select(arg => string.Format("{0}", arg)).Where(sArg => !string.IsNullOrWhiteSpace(sArg)).ToList();
|
||||
return string.Join(seperator, results);
|
||||
}
|
||||
|
||||
@@ -645,71 +828,6 @@ namespace Umbraco.Web
|
||||
|
||||
#endregion
|
||||
|
||||
#region Wrap
|
||||
|
||||
public HtmlTagWrapper Wrap(string tag, string innerText, params IHtmlTagWrapper[] children)
|
||||
{
|
||||
var item = Wrap(tag, innerText, (object)null);
|
||||
foreach (var child in children)
|
||||
{
|
||||
item.AddChild(child);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public HtmlTagWrapper Wrap(string tag, object inner, object anonymousAttributes, params IHtmlTagWrapper[] children)
|
||||
{
|
||||
string innerText = null;
|
||||
if (inner != null && inner.GetType() != typeof(DynamicNull))
|
||||
{
|
||||
innerText = string.Format("{0}", inner);
|
||||
}
|
||||
var item = Wrap(tag, innerText, anonymousAttributes);
|
||||
foreach (var child in children)
|
||||
{
|
||||
item.AddChild(child);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
public HtmlTagWrapper Wrap(string tag, object inner)
|
||||
{
|
||||
string innerText = null;
|
||||
if (inner != null && inner.GetType() != typeof(DynamicNull))
|
||||
{
|
||||
innerText = string.Format("{0}", inner);
|
||||
}
|
||||
return Wrap(tag, innerText, (object)null);
|
||||
}
|
||||
|
||||
public HtmlTagWrapper Wrap(string tag, string innerText, object anonymousAttributes, params IHtmlTagWrapper[] children)
|
||||
{
|
||||
var wrap = new HtmlTagWrapper(tag);
|
||||
if (anonymousAttributes != null)
|
||||
{
|
||||
wrap.ReflectAttributesFromAnonymousType(anonymousAttributes);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(innerText))
|
||||
{
|
||||
wrap.AddChild(new HtmlTagWrapperTextNode(innerText));
|
||||
}
|
||||
foreach (var child in children)
|
||||
{
|
||||
wrap.AddChild(child);
|
||||
}
|
||||
return wrap;
|
||||
}
|
||||
|
||||
public HtmlTagWrapper Wrap(bool visible, string tag, string innerText, object anonymousAttributes, params IHtmlTagWrapper[] children)
|
||||
{
|
||||
var item = Wrap(tag, innerText, anonymousAttributes, children);
|
||||
item.Visible = visible;
|
||||
foreach (var child in children)
|
||||
{
|
||||
item.AddChild(child);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Xml;
|
||||
using System.Xml.XPath;
|
||||
|
||||
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web;
|
||||
using umbraco.BusinessLogic;
|
||||
using umbraco.cms.businesslogic;
|
||||
using umbraco.cms.businesslogic.media;
|
||||
@@ -25,11 +25,11 @@ using umbraco.DataLayer;
|
||||
using System.Web.Security;
|
||||
using umbraco.cms.businesslogic.language;
|
||||
using umbraco.IO;
|
||||
using umbraco.presentation;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using umbraco.cms.businesslogic.cache;
|
||||
using umbraco.NodeFactory;
|
||||
using UmbracoContext = umbraco.presentation.UmbracoContext;
|
||||
|
||||
namespace umbraco
|
||||
{
|
||||
@@ -42,6 +42,14 @@ namespace umbraco
|
||||
/// </summary>
|
||||
public class library
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a new UmbracoHelper so that we can start moving the logic from some of these methods to it
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static UmbracoHelper GetUmbracoHelper()
|
||||
{
|
||||
return new UmbracoHelper(Umbraco.Web.UmbracoContext.Current);
|
||||
}
|
||||
|
||||
#region Declarations
|
||||
|
||||
@@ -370,8 +378,7 @@ namespace umbraco
|
||||
/// <returns>String with a friendly url from a node</returns>
|
||||
public static string NiceUrl(int nodeID)
|
||||
{
|
||||
var niceUrlsProvider = Umbraco.Web.UmbracoContext.Current.RoutingContext.NiceUrlProvider;
|
||||
return niceUrlsProvider.GetNiceUrl(nodeID);
|
||||
return GetUmbracoHelper().NiceUrl(nodeID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -393,8 +400,7 @@ namespace umbraco
|
||||
/// <returns>String with a friendly url with full domain from a node</returns>
|
||||
public static string NiceUrlWithDomain(int nodeID)
|
||||
{
|
||||
var niceUrlsProvider = Umbraco.Web.UmbracoContext.Current.RoutingContext.NiceUrlProvider;
|
||||
return niceUrlsProvider.GetNiceUrl(nodeID, Umbraco.Web.UmbracoContext.Current.UmbracoUrl, true);
|
||||
return GetUmbracoHelper().NiceUrlWithDomain(nodeID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -413,7 +419,7 @@ namespace umbraco
|
||||
|
||||
public static string ResolveVirtualPath(string path)
|
||||
{
|
||||
return IOHelper.ResolveUrl(path);
|
||||
return Umbraco.Core.IO.IOHelper.ResolveUrl(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -659,12 +665,7 @@ namespace umbraco
|
||||
/// <returns>True is the current user is logged in</returns>
|
||||
public static bool IsLoggedOn()
|
||||
{
|
||||
/*
|
||||
MembershipUser u = Membership.GetUser();
|
||||
return u != null;
|
||||
*/
|
||||
|
||||
return Member.IsLoggedOn();
|
||||
return GetUmbracoHelper().MemberIsLoggedOn();
|
||||
}
|
||||
|
||||
public static XPathNodeIterator AllowedGroups(int documentId, string path)
|
||||
@@ -684,7 +685,7 @@ namespace umbraco
|
||||
/// <returns>True if the document object is protected</returns>
|
||||
public static bool IsProtected(int DocumentId, string Path)
|
||||
{
|
||||
return Access.IsProtected(DocumentId, Path);
|
||||
return GetUmbracoHelper().IsProtected(DocumentId, Path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -695,39 +696,18 @@ namespace umbraco
|
||||
/// <returns>True if the current user has access or if the current document isn't protected</returns>
|
||||
public static bool HasAccess(int NodeId, string Path)
|
||||
{
|
||||
if (IsProtected(NodeId, Path))
|
||||
{
|
||||
if (Member.IsLoggedOn())
|
||||
return Access.HasAccess(NodeId, Path, Membership.GetUser());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
return GetUmbracoHelper().MemberHasAccess(NodeId, Path);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Encrypts the string using md5
|
||||
/// Returns an MD5 hash of the string specified
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <returns>Md5 encrupted string</returns>
|
||||
/// <param name="text">The text to create a hash from</param>
|
||||
/// <returns>Md5 has of the string</returns>
|
||||
public static string md5(string text)
|
||||
{
|
||||
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
|
||||
byte[] bs = System.Text.Encoding.UTF8.GetBytes(text);
|
||||
|
||||
bs = x.ComputeHash(bs);
|
||||
|
||||
System.Text.StringBuilder s = new System.Text.StringBuilder();
|
||||
|
||||
foreach (byte b in bs)
|
||||
{
|
||||
s.Append(b.ToString("x2").ToLower());
|
||||
}
|
||||
|
||||
return s.ToString();
|
||||
return text.ToMd5();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1060,10 +1040,7 @@ namespace umbraco
|
||||
/// <returns>The text with text line breaks replaced with html linebreaks (<br/>)</returns>
|
||||
public static string ReplaceLineBreaks(string text)
|
||||
{
|
||||
if (bool.Parse(GlobalSettings.EditXhtmlMode))
|
||||
return text.Replace("\n", "<br/>\n");
|
||||
else
|
||||
return text.Replace("\n", "<br />\n");
|
||||
return GetUmbracoHelper().ReplaceLineBreaksForHtml(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.WebPages;
|
||||
using Umbraco.Core;
|
||||
using umbraco.cms.businesslogic.macro;
|
||||
using umbraco.interfaces;
|
||||
using umbraco.IO;
|
||||
@@ -24,14 +25,7 @@ namespace umbraco.MacroEngines
|
||||
}
|
||||
|
||||
public string GetMd5(string text) {
|
||||
var x = new System.Security.Cryptography.MD5CryptoServiceProvider();
|
||||
var bs = System.Text.Encoding.UTF8.GetBytes(text);
|
||||
bs = x.ComputeHash(bs);
|
||||
var s = new System.Text.StringBuilder();
|
||||
foreach (var b in bs) {
|
||||
s.Append(b.ToString("x2").ToLower());
|
||||
}
|
||||
return s.ToString();
|
||||
return text.ToMd5();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core.Dynamics;
|
||||
using Umbraco.Web;
|
||||
using umbraco.interfaces;
|
||||
@@ -17,6 +18,12 @@ namespace umbraco.MacroEngines.Library
|
||||
{
|
||||
private readonly INode _node;
|
||||
private readonly UmbracoHelper _umbracoHelper;
|
||||
|
||||
/// <summary>
|
||||
/// An empty HtmlHelper with a blank ViewContext, used only to access some htmlHelper extension methods
|
||||
/// </summary>
|
||||
private readonly HtmlHelper _htmlHelper;
|
||||
|
||||
public INode Node
|
||||
{
|
||||
get { return _node; }
|
||||
@@ -25,6 +32,7 @@ namespace umbraco.MacroEngines.Library
|
||||
{
|
||||
this._node = node;
|
||||
_umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
|
||||
_htmlHelper = new HtmlHelper(new ViewContext(), new ViewPage());
|
||||
}
|
||||
|
||||
public dynamic NodeById(int Id)
|
||||
@@ -194,24 +202,24 @@ namespace umbraco.MacroEngines.Library
|
||||
}
|
||||
|
||||
public Umbraco.Web.Mvc.HtmlTagWrapper Wrap(string tag, string innerText, params Umbraco.Web.Mvc.IHtmlTagWrapper[] children)
|
||||
{
|
||||
return _umbracoHelper.Wrap(tag, innerText, children);
|
||||
{
|
||||
return _htmlHelper.Wrap(tag, innerText, children);
|
||||
}
|
||||
public Umbraco.Web.Mvc.HtmlTagWrapper Wrap(string tag, object inner, object anonymousAttributes, params Umbraco.Web.Mvc.IHtmlTagWrapper[] children)
|
||||
{
|
||||
return _umbracoHelper.Wrap(tag, inner, anonymousAttributes, children);
|
||||
return _htmlHelper.Wrap(tag, inner, anonymousAttributes, children);
|
||||
}
|
||||
public Umbraco.Web.Mvc.HtmlTagWrapper Wrap(string tag, object inner)
|
||||
{
|
||||
return _umbracoHelper.Wrap(tag, inner);
|
||||
return _htmlHelper.Wrap(tag, inner);
|
||||
}
|
||||
public Umbraco.Web.Mvc.HtmlTagWrapper Wrap(string tag, string innerText, object anonymousAttributes, params Umbraco.Web.Mvc.IHtmlTagWrapper[] children)
|
||||
{
|
||||
return _umbracoHelper.Wrap(tag, innerText, anonymousAttributes, children);
|
||||
return _htmlHelper.Wrap(tag, innerText, anonymousAttributes, children);
|
||||
}
|
||||
public Umbraco.Web.Mvc.HtmlTagWrapper Wrap(bool visible, string tag, string innerText, object anonymousAttributes, params Umbraco.Web.Mvc.IHtmlTagWrapper[] children)
|
||||
{
|
||||
return _umbracoHelper.Wrap(visible, tag, innerText, anonymousAttributes, children);
|
||||
return _htmlHelper.Wrap(visible, tag, innerText, anonymousAttributes, children);
|
||||
}
|
||||
|
||||
public IHtmlString Truncate(IHtmlString html, int length)
|
||||
|
||||
Reference in New Issue
Block a user