2012-09-03 07:54:09 +07:00
using System ;
using System.Collections ;
using System.IO ;
2012-09-14 09:09:23 +07:00
using System.Linq ;
using System.Text ;
2012-09-03 07:54:09 +07:00
using System.Web ;
2012-09-27 08:30:35 +07:00
using System.Web.Security ;
2012-09-05 09:35:24 +07:00
using System.Web.UI ;
2012-09-14 09:09:23 +07:00
using System.Xml.Linq ;
using System.Xml.XPath ;
using HtmlAgilityPack ;
2012-09-03 07:54:09 +07:00
using Umbraco.Core ;
2012-09-27 08:30:35 +07:00
using Umbraco.Core.Dictionary ;
2012-09-14 09:09:23 +07:00
using Umbraco.Core.Dynamics ;
2012-09-05 09:35:24 +07:00
using Umbraco.Core.Models ;
2013-03-19 17:54:37 -01:00
using Umbraco.Core.Xml ;
2012-10-04 03:26:56 +05:00
using Umbraco.Web.Models ;
2013-02-05 06:31:13 -01:00
using Umbraco.Web.PublishedCache ;
2012-09-29 08:49:21 +07:00
using Umbraco.Web.Templates ;
2012-09-03 07:54:09 +07:00
using umbraco ;
2012-09-05 09:35:24 +07:00
using System.Collections.Generic ;
2012-09-27 08:30:35 +07:00
using umbraco.cms.businesslogic.member ;
using umbraco.cms.businesslogic.web ;
2012-09-05 09:35:24 +07:00
using umbraco.presentation.templateControls ;
2012-09-03 07:54:09 +07:00
namespace Umbraco.Web
{
2012-09-27 08:30:35 +07:00
2012-09-03 07:54:09 +07:00
/// <summary>
/// A helper class that provides many useful methods and functionality for using Umbraco in templates
/// </summary>
public class UmbracoHelper
{
private readonly UmbracoContext _umbracoContext ;
2012-10-02 01:35:39 +05:00
private readonly IPublishedContent _currentPage ;
2012-09-03 07:54:09 +07:00
2012-11-05 11:27:28 +06:00
/// <summary>
/// Custom constructor setting the current page to the parameter passed in
/// </summary>
/// <param name="umbracoContext"></param>
/// <param name="content"></param>
public UmbracoHelper ( UmbracoContext umbracoContext , IPublishedContent content )
: this ( umbracoContext )
{
if ( content = = null ) throw new ArgumentNullException ( "content" ) ;
_currentPage = content ;
}
/// <summary>
/// Standard constructor setting the current page to the page that has been routed to
/// </summary>
/// <param name="umbracoContext"></param>
2012-10-25 14:18:53 -10:00
public UmbracoHelper ( UmbracoContext umbracoContext )
2012-09-03 07:54:09 +07:00
{
2012-09-08 07:13:03 +07:00
if ( umbracoContext = = null ) throw new ArgumentNullException ( "umbracoContext" ) ;
2012-09-28 08:08:36 +07:00
if ( umbracoContext . RoutingContext = = null ) throw new NullReferenceException ( "The RoutingContext on the UmbracoContext cannot be null" ) ;
2012-09-03 07:54:09 +07:00
_umbracoContext = umbracoContext ;
2012-09-28 08:08:36 +07:00
if ( _umbracoContext . IsFrontEndUmbracoRequest )
{
2012-11-05 11:27:28 +06:00
_currentPage = _umbracoContext . PublishedContentRequest . PublishedContent ;
2012-09-28 08:08:36 +07:00
}
2012-09-03 07:54:09 +07:00
}
2013-01-25 06:13:47 +03:00
/// <summary>
/// Returns the current IPublishedContent item assigned to the UmbracoHelper
/// </summary>
/// <remarks>
/// Note that this is the assigned IPublishedContent item to the UmbracoHelper, this is not necessarily the Current IPublishedContent item
/// being rendered. This IPublishedContent object is contextual to the current UmbracoHelper instance.
///
/// In some cases accessing this property will throw an exception if there is not IPublishedContent assigned to the Helper
/// this will only ever happen if the Helper is constructed with an UmbracoContext and it is not a front-end request
/// </remarks>
/// <exception cref="InvalidOperationException">Thrown if the UmbracoHelper is constructed with an UmbracoContext and it is not a front-end request</exception>
public IPublishedContent AssignedContentItem
{
get
{
if ( _currentPage = = null )
throw new InvalidOperationException ( "Cannot return the " + typeof ( IPublishedContent ) . Name + " because the " + typeof ( UmbracoHelper ) . Name + " was constructed with an " + typeof ( UmbracoContext ) . Name + " and the current request is not a front-end request." ) ;
return _currentPage ;
}
}
/// <summary>
2012-11-14 10:47:40 +05:00
/// Renders the template for the specified pageId and an optional altTemplateId
/// </summary>
/// <param name="pageId"></param>
/// <param name="altTemplateId">If not specified, will use the template assigned to the node</param>
/// <returns></returns>
public IHtmlString RenderTemplate ( int pageId , int? altTemplateId = null )
{
var templateRenderer = new TemplateRenderer ( _umbracoContext , pageId , altTemplateId ) ;
using ( var sw = new StringWriter ( ) )
{
try
{
templateRenderer . Render ( sw ) ;
}
catch ( Exception ex )
{
sw . Write ( "<!-- Error rendering template with id {0}: '{1}' -->" , pageId , ex ) ;
}
return new HtmlString ( sw . ToString ( ) ) ;
}
}
2012-09-03 07:54:09 +07:00
#region RenderMacro
/// <summary>
/// Renders the macro with the specified alias.
/// </summary>
/// <param name="alias">The alias.</param>
/// <returns></returns>
public IHtmlString RenderMacro ( string alias )
{
return RenderMacro ( alias , new { } ) ;
}
/// <summary>
/// Renders the macro with the specified alias, passing in the specified parameters.
/// </summary>
/// <param name="alias">The alias.</param>
/// <param name="parameters">The parameters.</param>
/// <returns></returns>
public IHtmlString RenderMacro ( string alias , object parameters )
2012-09-08 07:13:03 +07:00
{
return RenderMacro ( alias , parameters . ToDictionary < object > ( ) ) ;
}
/// <summary>
/// Renders the macro with the specified alias, passing in the specified parameters.
/// </summary>
/// <param name="alias">The alias.</param>
/// <param name="parameters">The parameters.</param>
/// <returns></returns>
public IHtmlString RenderMacro ( string alias , IDictionary < string , object > parameters )
2012-09-03 07:54:09 +07:00
{
if ( alias = = null ) throw new ArgumentNullException ( "alias" ) ;
2012-11-15 13:41:44 -01:00
2012-09-03 07:54:09 +07:00
var m = macro . GetMacro ( alias ) ;
if ( _umbracoContext . PageId = = null )
{
throw new InvalidOperationException ( "Cannot render a macro when UmbracoContext.PageId is null." ) ;
}
2012-10-02 01:40:19 +05:00
if ( _umbracoContext . PublishedContentRequest = = null )
2012-09-03 07:54:09 +07:00
{
2012-10-02 01:40:19 +05:00
throw new InvalidOperationException ( "Cannot render a macro when there is no current PublishedContentRequest." ) ;
2012-09-03 07:54:09 +07:00
}
var macroProps = new Hashtable ( ) ;
2012-09-08 07:13:03 +07:00
foreach ( var i in parameters )
2012-09-03 07:54:09 +07:00
{
//TODO: We are doing at ToLower here because for some insane reason the UpdateMacroModel method of macro.cs
// looks for a lower case match. WTF. the whole macro concept needs to be rewritten.
macroProps . Add ( i . Key . ToLower ( ) , i . Value ) ;
2012-09-08 07:13:03 +07:00
}
var macroControl = m . renderMacro ( macroProps ,
2012-10-02 01:40:19 +05:00
UmbracoContext . Current . PublishedContentRequest . UmbracoPage . Elements ,
2012-09-03 07:54:09 +07:00
_umbracoContext . PageId . Value ) ;
2012-11-15 13:41:44 -01:00
string html ;
if ( macroControl is LiteralControl )
{
// no need to execute, we already have text
html = ( macroControl as LiteralControl ) . Text ;
}
else
2012-09-05 09:35:24 +07:00
{
2012-11-15 13:41:44 -01:00
var containerPage = new FormlessPage ( ) ;
containerPage . Controls . Add ( macroControl ) ;
2012-09-29 08:49:21 +07:00
2012-11-15 13:41:44 -01:00
using ( var output = new StringWriter ( ) )
{
// .Execute() does a PushTraceContext/PopTraceContext and writes trace output straight into 'output'
// and I do not see how we could wire the trace context to the current context... so it creates dirty
// trace output right in the middle of the page.
//
// The only thing we can do is fully disable trace output while .Execute() runs and restore afterwards
// which means trace output is lost if the macro is a control (.ascx or user control) that is invoked
// from within Razor -- which makes sense anyway because the control can _not_ run correctly from
// within Razor since it will never be inserted into the page pipeline (which may even not exist at all
// if we're running MVC).
//
2013-07-19 12:27:37 +10:00
// I'm sure there's more things that will get lost with this context changing but I guess we'll figure
// those out as we go along. One thing we lose is the content type response output.
// http://issues.umbraco.org/issue/U4-1599 if it is setup during the macro execution. So
// here we'll save the content type response and reset it after execute is called.
var contentType = _umbracoContext . HttpContext . Response . ContentType ;
2012-11-15 13:41:44 -01:00
var traceIsEnabled = containerPage . Trace . IsEnabled ;
containerPage . Trace . IsEnabled = false ;
_umbracoContext . HttpContext . Server . Execute ( containerPage , output , false ) ;
containerPage . Trace . IsEnabled = traceIsEnabled ;
2013-07-19 12:27:37 +10:00
//reset the content type
_umbracoContext . HttpContext . Response . ContentType = contentType ;
2012-11-15 13:41:44 -01:00
//Now, we need to ensure that local links are parsed
html = TemplateUtilities . ParseInternalLinks ( output . ToString ( ) ) ;
}
2012-09-05 09:35:24 +07:00
}
2012-11-15 13:41:44 -01:00
return new HtmlString ( html ) ;
2012-09-03 07:54:09 +07:00
}
#endregion
2012-09-05 09:35:24 +07:00
#region Field
/// <summary>
/// Renders an field to the template
/// </summary>
/// <param name="fieldAlias"></param>
/// <param name="altFieldAlias"></param>
/// <param name="altText"></param>
/// <param name="insertBefore"></param>
/// <param name="insertAfter"></param>
/// <param name="recursive"></param>
/// <param name="convertLineBreaks"></param>
/// <param name="removeParagraphTags"></param>
/// <param name="casing"></param>
/// <param name="encoding"></param>
2012-10-08 05:40:55 -10:00
/// <param name="formatAsDate"></param>
/// <param name="formatAsDateWithTime"></param>
/// <param name="formatAsDateWithTimeSeparator"></param>
//// <param name="formatString"></param>
2012-09-05 09:35:24 +07:00
/// <returns></returns>
2012-10-01 02:48:08 +05:00
public IHtmlString Field ( string fieldAlias ,
string altFieldAlias = "" , string altText = "" , string insertBefore = "" , string insertAfter = "" ,
2012-09-05 09:35:24 +07:00
bool recursive = false , bool convertLineBreaks = false , bool removeParagraphTags = false ,
RenderFieldCaseType casing = RenderFieldCaseType . Unchanged ,
2012-10-08 05:40:55 -10:00
RenderFieldEncodingType encoding = RenderFieldEncodingType . Unchanged ,
bool formatAsDate = false ,
bool formatAsDateWithTime = false ,
string formatAsDateWithTimeSeparator = "" )
//TODO: commented out until as it is not implemented by umbraco:item yet
//,string formatString = "")
2013-01-25 06:13:47 +03:00
{
return Field ( AssignedContentItem , fieldAlias , altFieldAlias ,
2012-10-08 05:40:55 -10:00
altText , insertBefore , insertAfter , recursive , convertLineBreaks , removeParagraphTags ,
casing , encoding , formatAsDate , formatAsDateWithTime , formatAsDateWithTimeSeparator ) ; // formatString);
2012-09-05 09:35:24 +07:00
}
/// <summary>
/// Renders an field to the template
/// </summary>
/// <param name="currentPage"></param>
/// <param name="fieldAlias"></param>
/// <param name="altFieldAlias"></param>
2012-09-05 09:36:30 +07:00
/// <param name="altText"></param>
2012-09-05 09:35:24 +07:00
/// <param name="insertBefore"></param>
/// <param name="insertAfter"></param>
/// <param name="recursive"></param>
/// <param name="convertLineBreaks"></param>
/// <param name="removeParagraphTags"></param>
/// <param name="casing"></param>
2012-10-08 05:40:55 -10:00
/// <param name="encoding"></param>
/// <param name="formatAsDate"></param>
/// <param name="formatAsDateWithTime"></param>
/// <param name="formatAsDateWithTimeSeparator"></param>
//// <param name="formatString"></param>
2012-09-05 09:35:24 +07:00
/// <returns></returns>
2012-10-02 01:35:39 +05:00
public IHtmlString Field ( IPublishedContent currentPage , string fieldAlias ,
2012-10-01 02:48:08 +05:00
string altFieldAlias = "" , string altText = "" , string insertBefore = "" , string insertAfter = "" ,
2012-09-05 09:35:24 +07:00
bool recursive = false , bool convertLineBreaks = false , bool removeParagraphTags = false ,
RenderFieldCaseType casing = RenderFieldCaseType . Unchanged ,
2012-10-08 05:40:55 -10:00
RenderFieldEncodingType encoding = RenderFieldEncodingType . Unchanged ,
bool formatAsDate = false ,
bool formatAsDateWithTime = false ,
string formatAsDateWithTimeSeparator = "" )
//TODO: commented out until as it is not implemented by umbraco:item yet
//,string formatString = "")
2012-09-05 09:35:24 +07:00
{
2012-09-29 08:07:00 +07:00
Mandate . ParameterNotNull ( currentPage , "currentPage" ) ;
Mandate . ParameterNotNullOrEmpty ( fieldAlias , "fieldAlias" ) ;
2012-09-05 09:35:24 +07:00
//TODO: This is real nasty and we should re-write the 'item' and 'ItemRenderer' class but si fine for now
var attributes = new Dictionary < string , string >
{
{ "field" , fieldAlias } ,
{ "recursive" , recursive . ToString ( ) . ToLowerInvariant ( ) } ,
2012-10-08 05:40:55 -10:00
{ "useifempty" , altFieldAlias } ,
{ "textifempty" , altText } ,
{ "stripparagraph" , removeParagraphTags . ToString ( ) . ToLowerInvariant ( ) } ,
2012-09-05 09:35:24 +07:00
{
"case" , casing = = RenderFieldCaseType . Lower ? "lower"
: casing = = RenderFieldCaseType . Upper ? "upper"
: casing = = RenderFieldCaseType . Title ? "title"
: string . Empty
} ,
2012-10-08 05:40:55 -10:00
{ "inserttextbefore" , insertBefore } ,
{ "inserttextafter" , insertAfter } ,
{ "convertlinebreaks" , convertLineBreaks . ToString ( ) . ToLowerInvariant ( ) } ,
{ "formatasdate" , formatAsDate . ToString ( ) . ToLowerInvariant ( ) } ,
{ "formatasdatewithtime" , formatAsDateWithTime . ToString ( ) . ToLowerInvariant ( ) } ,
{ "formatasdatewithtimeseparator" , formatAsDateWithTimeSeparator }
2012-09-05 09:35:24 +07:00
} ;
switch ( encoding )
{
case RenderFieldEncodingType . Url :
2012-10-08 05:40:55 -10:00
attributes . Add ( "urlencode" , "true" ) ;
2012-09-05 09:35:24 +07:00
break ;
case RenderFieldEncodingType . Html :
2012-10-08 05:40:55 -10:00
attributes . Add ( "htmlencode" , "true" ) ;
2012-09-05 09:35:24 +07:00
break ;
case RenderFieldEncodingType . Unchanged :
default :
break ;
}
//need to convert our dictionary over to this weird dictionary type
var attributesForItem = new AttributeCollectionAdapter (
new AttributeCollection (
new StateBag ( ) ) ) ;
2012-09-27 08:30:35 +07:00
foreach ( var i in attributes )
2012-09-05 09:35:24 +07:00
{
attributesForItem . Add ( i . Key , i . Value ) ;
}
2012-11-07 21:19:35 -10:00
2013-07-15 15:26:18 +10:00
var item = new Item ( currentPage )
2012-12-14 10:40:11 +05:00
{
2012-11-07 15:20:19 -10:00
Field = fieldAlias ,
TextIfEmpty = altText ,
LegacyAttributes = attributesForItem
} ;
2012-11-07 21:19:35 -10:00
2013-06-20 11:25:33 +10:00
//here we are going to check if we are in the context of an Umbraco routed page, if we are we
//will leave the NodeId empty since the underlying ItemRenderer will work ever so slightly faster
//since it already knows about the current page. Otherwise, we'll assign the id based on our
//currently assigned node. The PublishedContentRequest will be null if:
// * we are rendering a partial view or child action
// * we are rendering a view from a custom route
if ( _umbracoContext . PublishedContentRequest = = null
| | _umbracoContext . PublishedContentRequest . PublishedContent . Id ! = currentPage . Id )
{
2012-11-10 16:40:00 +00:00
item . NodeId = currentPage . Id . ToString ( ) ;
2013-06-20 11:25:33 +10:00
}
2012-09-05 09:35:24 +07:00
var containerPage = new FormlessPage ( ) ;
containerPage . Controls . Add ( item ) ;
using ( var output = new StringWriter ( ) )
using ( var htmlWriter = new HtmlTextWriter ( output ) )
{
ItemRenderer . Instance . Init ( item ) ;
ItemRenderer . Instance . Load ( item ) ;
ItemRenderer . Instance . Render ( item , htmlWriter ) ;
2012-09-29 08:49:21 +07:00
2012-09-29 11:35:31 +07:00
//because we are rendering the output through the legacy Item (webforms) stuff, the {localLinks} will already be replaced.
return new HtmlString ( output . ToString ( ) ) ;
2012-09-05 09:35:24 +07:00
}
}
#endregion
2012-09-27 08:30:35 +07:00
#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 )
{
2013-01-31 10:06:25 -01:00
var urlProvider = UmbracoContext . Current . UrlProvider ;
return urlProvider . GetUrl ( nodeId ) ;
2012-09-27 08:30:35 +07:00
}
/// <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 )
{
2013-01-31 10:06:25 -01:00
var urlProvider = UmbracoContext . Current . UrlProvider ;
return urlProvider . GetUrl ( nodeId , true ) ;
2012-09-27 08:30:35 +07:00
}
#endregion
2012-09-14 09:09:23 +07:00
#region Content
2012-11-21 09:09:37 +05:00
public IPublishedContent TypedContent ( object id )
{
2013-03-19 17:51:55 -01:00
return TypedDocumentById ( id , _umbracoContext . ContentCache ) ;
2012-11-21 09:09:37 +05:00
}
2012-10-02 22:10:18 +05:00
public IPublishedContent TypedContent ( int id )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentById ( id , _umbracoContext . ContentCache ) ;
2012-10-02 21:58:07 +05:00
}
2012-10-02 22:10:18 +05:00
public IPublishedContent TypedContent ( string id )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentById ( id , _umbracoContext . ContentCache ) ;
2012-10-02 21:58:07 +05:00
}
2013-03-19 17:54:37 -01:00
public IPublishedContent TypedContentSingleAtXPath ( string xpath , params XPathVariable [ ] vars )
{
return TypedDocumentByXPath ( xpath , vars , _umbracoContext . ContentCache ) ;
}
2012-11-21 09:09:37 +05:00
public IEnumerable < IPublishedContent > TypedContent ( params object [ ] ids )
{
2013-03-19 17:51:55 -01:00
return TypedDocumentsbyIds ( _umbracoContext . ContentCache , ids ) ;
2012-11-21 09:09:37 +05:00
}
2012-10-02 22:10:18 +05:00
public IEnumerable < IPublishedContent > TypedContent ( params int [ ] ids )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentsbyIds ( _umbracoContext . ContentCache , ids ) ;
2012-10-02 21:58:07 +05:00
}
2012-10-02 22:10:18 +05:00
public IEnumerable < IPublishedContent > TypedContent ( params string [ ] ids )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentsbyIds ( _umbracoContext . ContentCache , ids ) ;
2012-10-02 21:58:07 +05:00
}
2012-11-21 09:09:37 +05:00
public IEnumerable < IPublishedContent > TypedContent ( IEnumerable < object > ids )
{
return TypedContent ( ids . ToArray ( ) ) ;
}
2012-10-02 22:55:36 +05:00
public IEnumerable < IPublishedContent > TypedContent ( IEnumerable < string > ids )
{
return TypedContent ( ids . ToArray ( ) ) ;
}
public IEnumerable < IPublishedContent > TypedContent ( IEnumerable < int > ids )
{
return TypedContent ( ids . ToArray ( ) ) ;
}
2013-03-19 17:54:37 -01:00
public IEnumerable < IPublishedContent > TypedContentAtXPath ( string xpath , params XPathVariable [ ] vars )
{
return TypedDocumentsByXPath ( xpath , vars , _umbracoContext . ContentCache ) ;
}
2013-04-10 12:49:45 -02:00
public IEnumerable < IPublishedContent > TypedContentAtXPath ( XPathExpression xpath , params XPathVariable [ ] vars )
{
return TypedDocumentsByXPath ( xpath , vars , _umbracoContext . ContentCache ) ;
}
2013-02-02 03:22:30 +06:00
public IEnumerable < IPublishedContent > TypedContentAtRoot ( )
2013-02-01 06:28:54 -01:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentsAtRoot ( _umbracoContext . ContentCache ) ;
2013-02-01 06:28:54 -01:00
}
2012-11-21 09:09:37 +05:00
public dynamic Content ( object id )
{
2013-03-19 17:51:55 -01:00
return DocumentById ( id , _umbracoContext . ContentCache , new DynamicNull ( ) ) ;
2012-11-21 09:09:37 +05:00
}
2012-10-02 21:58:07 +05:00
public dynamic Content ( int id )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
return DocumentById ( id , _umbracoContext . ContentCache , new DynamicNull ( ) ) ;
2012-09-14 09:09:23 +07:00
}
2012-10-02 21:58:07 +05:00
public dynamic Content ( string id )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
return DocumentById ( id , _umbracoContext . ContentCache , new DynamicNull ( ) ) ;
2012-09-14 09:09:23 +07:00
}
2013-03-19 17:54:37 -01:00
public dynamic ContentSingleAtXPath ( string xpath , params XPathVariable [ ] vars )
{
return DocumentByXPath ( xpath , vars , _umbracoContext . ContentCache , new DynamicNull ( ) ) ;
}
2013-04-10 12:49:45 -02:00
public dynamic ContentSingleAtXPath ( XPathExpression xpath , params XPathVariable [ ] vars )
{
return DocumentByXPath ( xpath , vars , _umbracoContext . ContentCache , new DynamicNull ( ) ) ;
}
public dynamic Content ( params object [ ] ids )
2012-11-21 09:09:37 +05:00
{
2013-03-19 17:51:55 -01:00
return DocumentByIds ( _umbracoContext . ContentCache , ids ) ;
2012-11-21 09:09:37 +05:00
}
2012-10-02 21:58:07 +05:00
public dynamic Content ( params int [ ] ids )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
return DocumentByIds ( _umbracoContext . ContentCache , ids ) ;
2012-09-14 09:09:23 +07:00
}
2012-10-02 21:58:07 +05:00
public dynamic Content ( params string [ ] ids )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
return DocumentByIds ( _umbracoContext . ContentCache , ids ) ;
2012-09-14 09:09:23 +07:00
}
2012-09-27 08:30:35 +07:00
2012-11-21 09:09:37 +05:00
public dynamic Content ( IEnumerable < object > ids )
{
return Content ( ids . ToArray ( ) ) ;
}
2012-10-02 22:55:36 +05:00
public dynamic Content ( IEnumerable < int > ids )
{
return Content ( ids . ToArray ( ) ) ;
}
public dynamic Content ( IEnumerable < string > ids )
{
return Content ( ids . ToArray ( ) ) ;
}
2013-03-19 17:54:37 -01:00
public dynamic ContentAtXPath ( string xpath , params XPathVariable [ ] vars )
{
return DocumentsByXPath ( xpath , vars , _umbracoContext . ContentCache ) ;
}
2013-04-10 12:49:45 -02:00
public dynamic ContentAtXPath ( XPathExpression xpath , params XPathVariable [ ] vars )
{
return DocumentsByXPath ( xpath , vars , _umbracoContext . ContentCache ) ;
}
2013-02-01 06:28:54 -01:00
public dynamic ContentAtRoot ( )
{
2013-03-19 17:51:55 -01:00
return DocumentsAtRoot ( _umbracoContext . ContentCache ) ;
2013-02-01 06:28:54 -01:00
}
2012-09-14 09:09:23 +07:00
#endregion
#region Media
2012-11-21 09:09:37 +05:00
/// <summary>
/// Overloaded method accepting an 'object' type
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <remarks>
/// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass
/// this result in to this method.
/// This method will throw an exception if the value is not of type int or string.
/// </remarks>
public IPublishedContent TypedMedia ( object id )
{
2013-03-19 17:51:55 -01:00
return TypedDocumentById ( id , _umbracoContext . MediaCache ) ;
2012-11-21 09:09:37 +05:00
}
2012-10-02 22:10:18 +05:00
public IPublishedContent TypedMedia ( int id )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentById ( id , _umbracoContext . MediaCache ) ;
2012-10-02 21:58:07 +05:00
}
2012-09-27 08:30:35 +07:00
2012-10-02 22:10:18 +05:00
public IPublishedContent TypedMedia ( string id )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentById ( id , _umbracoContext . MediaCache ) ;
2012-10-02 21:58:07 +05:00
}
2012-11-21 09:09:37 +05:00
public IEnumerable < IPublishedContent > TypedMedia ( params object [ ] ids )
{
2013-03-19 17:51:55 -01:00
return TypedDocumentsbyIds ( _umbracoContext . MediaCache , ids ) ;
2012-11-21 09:09:37 +05:00
}
2012-10-02 22:10:18 +05:00
public IEnumerable < IPublishedContent > TypedMedia ( params int [ ] ids )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentsbyIds ( _umbracoContext . MediaCache , ids ) ;
2012-10-02 21:58:07 +05:00
}
2012-10-02 22:10:18 +05:00
public IEnumerable < IPublishedContent > TypedMedia ( params string [ ] ids )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentsbyIds ( _umbracoContext . MediaCache , ids ) ;
2012-10-02 21:58:07 +05:00
}
2012-11-21 09:09:37 +05:00
public IEnumerable < IPublishedContent > TypedMedia ( IEnumerable < object > ids )
{
return TypedMedia ( ids . ToArray ( ) ) ;
}
2012-10-02 22:55:36 +05:00
public IEnumerable < IPublishedContent > TypedMedia ( IEnumerable < int > ids )
{
return TypedMedia ( ids . ToArray ( ) ) ;
}
public IEnumerable < IPublishedContent > TypedMedia ( IEnumerable < string > ids )
{
return TypedMedia ( ids . ToArray ( ) ) ;
}
2013-02-02 03:22:30 +06:00
public IEnumerable < IPublishedContent > TypedMediaAtRoot ( )
2013-02-01 06:28:54 -01:00
{
2013-03-19 17:51:55 -01:00
return TypedDocumentsAtRoot ( _umbracoContext . MediaCache ) ;
2013-02-01 06:28:54 -01:00
}
2012-11-21 09:09:37 +05:00
public dynamic Media ( object id )
{
2013-03-19 17:51:55 -01:00
return DocumentById ( id , _umbracoContext . MediaCache , new DynamicNull ( ) ) ;
2012-11-21 09:09:37 +05:00
}
2012-10-02 21:58:07 +05:00
public dynamic Media ( int id )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
return DocumentById ( id , _umbracoContext . MediaCache , new DynamicNull ( ) ) ;
2012-09-14 09:09:23 +07:00
}
2012-10-02 21:58:07 +05:00
public dynamic Media ( string id )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
return DocumentById ( id , _umbracoContext . MediaCache , new DynamicNull ( ) ) ;
2012-09-14 09:09:23 +07:00
}
2012-11-21 09:09:37 +05:00
public dynamic Media ( params object [ ] ids )
{
2013-03-19 17:51:55 -01:00
return DocumentByIds ( _umbracoContext . MediaCache , ids ) ;
2012-11-21 09:09:37 +05:00
}
2012-10-02 21:58:07 +05:00
public dynamic Media ( params int [ ] ids )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
return DocumentByIds ( _umbracoContext . MediaCache , ids ) ;
2012-09-14 09:09:23 +07:00
}
2012-10-02 21:58:07 +05:00
public dynamic Media ( params string [ ] ids )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
return DocumentByIds ( _umbracoContext . MediaCache , ids ) ;
2012-09-14 09:09:23 +07:00
}
2012-11-21 09:09:37 +05:00
public dynamic Media ( IEnumerable < object > ids )
{
return Media ( ids . ToArray ( ) ) ;
}
2012-10-02 22:55:36 +05:00
public dynamic Media ( IEnumerable < int > ids )
{
return Media ( ids . ToArray ( ) ) ;
}
public dynamic Media ( IEnumerable < string > ids )
{
return Media ( ids . ToArray ( ) ) ;
}
2013-02-01 06:28:54 -01:00
public dynamic MediaAtRoot ( )
{
2013-03-19 17:51:55 -01:00
return DocumentsAtRoot ( _umbracoContext . MediaCache ) ;
2013-02-01 06:28:54 -01:00
}
2012-09-14 09:09:23 +07:00
#endregion
#region Used by Content / Media
2012-11-21 09:09:37 +05:00
/// <summary>
/// Overloaded method accepting an 'object' type
/// </summary>
/// <param name="id"></param>
2013-02-05 06:31:13 -01:00
/// <param name="cache"> </param>
2012-11-21 09:09:37 +05:00
/// <returns></returns>
/// <remarks>
/// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass
/// this result in to this method.
/// This method will throw an exception if the value is not of type int or string.
/// </remarks>
2013-03-19 17:51:55 -01:00
private IPublishedContent TypedDocumentById ( object id , ContextualPublishedCache cache )
2012-11-21 09:09:37 +05:00
{
if ( id is string )
2013-02-05 06:31:13 -01:00
return TypedDocumentById ( ( string ) id , cache ) ;
2012-11-21 09:09:37 +05:00
if ( id is int )
2013-02-05 06:31:13 -01:00
return TypedDocumentById ( ( int ) id , cache ) ;
2012-11-21 09:09:37 +05:00
throw new InvalidOperationException ( "The value of parameter 'id' must be either a string or an integer" ) ;
}
2013-03-19 17:51:55 -01:00
private IPublishedContent TypedDocumentById ( int id , ContextualPublishedCache cache )
2012-10-02 21:58:07 +05:00
{
2013-03-19 17:51:55 -01:00
var doc = cache . GetById ( id ) ;
2012-10-02 21:58:07 +05:00
return doc ;
}
2013-03-19 17:51:55 -01:00
private IPublishedContent TypedDocumentById ( string id , ContextualPublishedCache cache )
2012-10-02 21:58:07 +05:00
{
int docId ;
return int . TryParse ( id , out docId )
2013-02-05 06:31:13 -01:00
? DocumentById ( docId , cache , null )
2012-10-02 21:58:07 +05:00
: null ;
}
2013-03-19 17:54:37 -01:00
private IPublishedContent TypedDocumentByXPath ( string xpath , XPathVariable [ ] vars , ContextualPublishedContentCache cache )
{
var doc = cache . GetSingleByXPath ( xpath , vars ) ;
return doc ;
}
2013-04-10 12:49:45 -02:00
private IPublishedContent TypedDocumentByXPath ( XPathExpression xpath , XPathVariable [ ] vars , ContextualPublishedContentCache cache )
{
var doc = cache . GetSingleByXPath ( xpath , vars ) ;
return doc ;
}
/// <summary>
2012-11-21 09:09:37 +05:00
/// Overloaded method accepting an 'object' type
/// </summary>
/// <param name="ids"></param>
2013-02-05 06:31:13 -01:00
/// <param name="cache"> </param>
2012-11-21 09:09:37 +05:00
/// <returns></returns>
/// <remarks>
/// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass
/// this result in to this method.
/// This method will throw an exception if the value is not of type int or string.
/// </remarks>
2013-03-19 17:51:55 -01:00
private IEnumerable < IPublishedContent > TypedDocumentsbyIds ( ContextualPublishedCache cache , params object [ ] ids )
2012-11-21 09:09:37 +05:00
{
2013-02-05 06:31:13 -01:00
return ids . Select ( eachId = > TypedDocumentById ( eachId , cache ) ) ;
2012-11-21 09:09:37 +05:00
}
2013-03-19 17:51:55 -01:00
private IEnumerable < IPublishedContent > TypedDocumentsbyIds ( ContextualPublishedCache cache , params int [ ] ids )
2012-10-02 21:58:07 +05:00
{
2013-02-05 06:31:13 -01:00
return ids . Select ( eachId = > TypedDocumentById ( eachId , cache ) ) ;
2012-10-02 21:58:07 +05:00
}
2013-03-19 17:51:55 -01:00
private IEnumerable < IPublishedContent > TypedDocumentsbyIds ( ContextualPublishedCache cache , params string [ ] ids )
2012-10-02 21:58:07 +05:00
{
2013-02-05 06:31:13 -01:00
return ids . Select ( eachId = > TypedDocumentById ( eachId , cache ) ) ;
2012-10-02 21:58:07 +05:00
}
2012-09-27 08:30:35 +07:00
2013-03-19 17:54:37 -01:00
private IEnumerable < IPublishedContent > TypedDocumentsByXPath ( string xpath , XPathVariable [ ] vars , ContextualPublishedContentCache cache )
{
var doc = cache . GetByXPath ( xpath , vars ) ;
return doc ;
}
2013-04-10 12:49:45 -02:00
private IEnumerable < IPublishedContent > TypedDocumentsByXPath ( XPathExpression xpath , XPathVariable [ ] vars , ContextualPublishedContentCache cache )
{
var doc = cache . GetByXPath ( xpath , vars ) ;
return doc ;
}
2013-03-19 17:51:55 -01:00
private IEnumerable < IPublishedContent > TypedDocumentsAtRoot ( ContextualPublishedCache cache )
2013-02-01 06:28:54 -01:00
{
2013-03-19 17:51:55 -01:00
return cache . GetAtRoot ( ) ;
2013-02-01 06:28:54 -01:00
}
2012-11-21 09:09:37 +05:00
/// <summary>
/// Overloaded method accepting an 'object' type
/// </summary>
/// <param name="id"></param>
2013-02-05 06:31:13 -01:00
/// <param name="cache"> </param>
2012-12-14 09:22:28 +05:00
/// <param name="ifNotFound"> </param>
2012-11-21 09:09:37 +05:00
/// <returns></returns>
/// <remarks>
/// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass
/// this result in to this method.
/// This method will throw an exception if the value is not of type int or string.
/// </remarks>
2013-03-19 17:51:55 -01:00
private dynamic DocumentById ( object id , ContextualPublishedCache cache , object ifNotFound )
2012-11-21 09:09:37 +05:00
{
if ( id is string )
2013-02-05 06:31:13 -01:00
return DocumentById ( ( string ) id , cache , ifNotFound ) ;
2012-11-21 09:09:37 +05:00
if ( id is int )
2013-02-05 06:31:13 -01:00
return DocumentById ( ( int ) id , cache , ifNotFound ) ;
2012-11-21 09:09:37 +05:00
throw new InvalidOperationException ( "The value of parameter 'id' must be either a string or an integer" ) ;
}
2013-03-19 17:51:55 -01:00
private dynamic DocumentById ( int id , ContextualPublishedCache cache , object ifNotFound )
2012-09-14 09:09:23 +07:00
{
2013-03-19 17:51:55 -01:00
var doc = cache . GetById ( id ) ;
2012-09-14 09:09:23 +07:00
return doc = = null
2012-12-14 09:22:28 +05:00
? ifNotFound
2012-10-04 03:26:56 +05:00
: new DynamicPublishedContent ( doc ) . AsDynamic ( ) ;
2012-09-14 09:09:23 +07:00
}
2013-03-19 17:51:55 -01:00
private dynamic DocumentById ( string id , ContextualPublishedCache cache , object ifNotFound )
2012-09-14 09:09:23 +07:00
{
int docId ;
2012-09-27 08:30:35 +07:00
return int . TryParse ( id , out docId )
2013-02-05 06:31:13 -01:00
? DocumentById ( docId , cache , ifNotFound )
2012-12-14 09:22:28 +05:00
: ifNotFound ;
2012-09-14 09:09:23 +07:00
}
2013-03-19 17:54:37 -01:00
private dynamic DocumentByXPath ( string xpath , XPathVariable [ ] vars , ContextualPublishedCache cache , object ifNotFound )
2013-02-01 06:28:54 -01:00
{
2013-03-19 17:54:37 -01:00
var doc = cache . GetSingleByXPath ( xpath , vars ) ;
return doc = = null
? ifNotFound
: new DynamicPublishedContent ( doc ) . AsDynamic ( ) ;
2013-02-01 06:28:54 -01:00
}
2013-04-10 12:49:45 -02:00
private dynamic DocumentByXPath ( XPathExpression xpath , XPathVariable [ ] vars , ContextualPublishedCache cache , object ifNotFound )
{
var doc = cache . GetSingleByXPath ( xpath , vars ) ;
return doc = = null
? ifNotFound
: new DynamicPublishedContent ( doc ) . AsDynamic ( ) ;
}
/// <summary>
2012-11-21 09:09:37 +05:00
/// Overloaded method accepting an 'object' type
/// </summary>
/// <param name="ids"></param>
2013-02-05 06:31:13 -01:00
/// <param name="cache"> </param>
2012-11-21 09:09:37 +05:00
/// <returns></returns>
/// <remarks>
/// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass
/// this result in to this method.
/// This method will throw an exception if the value is not of type int or string.
/// </remarks>
2013-03-19 17:51:55 -01:00
private dynamic DocumentByIds ( ContextualPublishedCache cache , params object [ ] ids )
2012-11-21 09:09:37 +05:00
{
2012-12-14 09:22:28 +05:00
var dNull = new DynamicNull ( ) ;
2013-02-05 06:31:13 -01:00
var nodes = ids . Select ( eachId = > DocumentById ( eachId , cache , dNull ) )
2012-11-21 09:09:37 +05:00
. Where ( x = > ! TypeHelper . IsTypeAssignableFrom < DynamicNull > ( x ) )
. Cast < DynamicPublishedContent > ( ) ;
return new DynamicPublishedContentList ( nodes ) ;
}
2013-03-19 17:51:55 -01:00
private dynamic DocumentByIds ( ContextualPublishedCache cache , params int [ ] ids )
2012-09-14 09:09:23 +07:00
{
2012-12-14 09:22:28 +05:00
var dNull = new DynamicNull ( ) ;
2013-02-05 06:31:13 -01:00
var nodes = ids . Select ( eachId = > DocumentById ( eachId , cache , dNull ) )
2012-09-14 09:09:23 +07:00
. Where ( x = > ! TypeHelper . IsTypeAssignableFrom < DynamicNull > ( x ) )
2012-10-04 03:26:56 +05:00
. Cast < DynamicPublishedContent > ( ) ;
2012-10-02 22:51:53 +05:00
return new DynamicPublishedContentList ( nodes ) ;
2012-09-14 09:09:23 +07:00
}
2013-03-19 17:51:55 -01:00
private dynamic DocumentByIds ( ContextualPublishedCache cache , params string [ ] ids )
2012-09-14 09:09:23 +07:00
{
2012-12-14 09:22:28 +05:00
var dNull = new DynamicNull ( ) ;
2013-02-05 06:31:13 -01:00
var nodes = ids . Select ( eachId = > DocumentById ( eachId , cache , dNull ) )
2012-09-14 09:09:23 +07:00
. Where ( x = > ! TypeHelper . IsTypeAssignableFrom < DynamicNull > ( x ) )
2012-10-04 03:26:56 +05:00
. Cast < DynamicPublishedContent > ( ) ;
2012-10-02 22:51:53 +05:00
return new DynamicPublishedContentList ( nodes ) ;
2012-09-14 09:09:23 +07:00
}
2013-03-19 17:54:37 -01:00
private dynamic DocumentsByXPath ( string xpath , XPathVariable [ ] vars , ContextualPublishedCache cache )
{
return new DynamicPublishedContentList (
cache . GetByXPath ( xpath , vars )
. Select ( publishedContent = > new DynamicPublishedContent ( publishedContent ) )
) ;
}
2013-04-10 12:49:45 -02:00
private dynamic DocumentsByXPath ( XPathExpression xpath , XPathVariable [ ] vars , ContextualPublishedCache cache )
{
return new DynamicPublishedContentList (
cache . GetByXPath ( xpath , vars )
. Select ( publishedContent = > new DynamicPublishedContent ( publishedContent ) )
) ;
}
2013-03-19 17:54:37 -01:00
private dynamic DocumentsAtRoot ( ContextualPublishedCache cache )
{
return new DynamicPublishedContentList (
cache . GetAtRoot ( )
. Select ( publishedContent = > new DynamicPublishedContent ( publishedContent ) )
) ;
}
#endregion
2012-09-14 09:09:23 +07:00
#region Search
/// <summary>
/// Searches content
/// </summary>
/// <param name="term"></param>
/// <param name="useWildCards"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public dynamic Search ( string term , bool useWildCards = true , string searchProvider = null )
2012-10-18 08:00:07 +05:00
{
return new DynamicPublishedContentList (
TypedSearch ( term , useWildCards , searchProvider ) ) ;
}
/// <summary>
/// Searhes content
/// </summary>
/// <param name="criteria"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public dynamic Search ( Examine . SearchCriteria . ISearchCriteria criteria , Examine . Providers . BaseSearchProvider searchProvider = null )
{
return new DynamicPublishedContentList (
TypedSearch ( criteria , searchProvider ) ) ;
}
/// <summary>
/// Searches content
/// </summary>
/// <param name="term"></param>
/// <param name="useWildCards"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public IEnumerable < IPublishedContent > TypedSearch ( string term , bool useWildCards = true , string searchProvider = null )
2012-09-14 09:09:23 +07:00
{
var searcher = Examine . ExamineManager . Instance . DefaultSearchProvider ;
if ( ! string . IsNullOrEmpty ( searchProvider ) )
searcher = Examine . ExamineManager . Instance . SearchProviderCollection [ searchProvider ] ;
var results = searcher . Search ( term , useWildCards ) ;
2013-03-19 17:51:55 -01:00
return results . ConvertSearchResultToPublishedContent ( _umbracoContext . ContentCache ) ;
2012-09-14 09:09:23 +07:00
}
/// <summary>
/// Searhes content
/// </summary>
/// <param name="criteria"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
2012-10-18 08:00:07 +05:00
public IEnumerable < IPublishedContent > TypedSearch ( Examine . SearchCriteria . ISearchCriteria criteria , Examine . Providers . BaseSearchProvider searchProvider = null )
2012-09-14 09:09:23 +07:00
{
var s = Examine . ExamineManager . Instance . DefaultSearchProvider ;
if ( searchProvider ! = null )
s = searchProvider ;
var results = s . Search ( criteria ) ;
2013-03-19 17:51:55 -01:00
return results . ConvertSearchResultToPublishedContent ( _umbracoContext . ContentCache ) ;
2012-09-14 09:09:23 +07:00
}
#endregion
#region Xml
public dynamic ToDynamicXml ( string xml )
{
if ( string . IsNullOrWhiteSpace ( xml ) ) return null ;
var xElement = XElement . Parse ( xml ) ;
return new DynamicXml ( xElement ) ;
}
public dynamic ToDynamicXml ( XElement xElement )
{
return new DynamicXml ( xElement ) ;
}
public dynamic ToDynamicXml ( XPathNodeIterator xpni )
{
return new DynamicXml ( xpni ) ;
}
#endregion
#region Strings
2012-09-27 08:30:35 +07:00
/// <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 ( ) ;
}
2012-09-14 09:09:23 +07:00
public HtmlString StripHtml ( IHtmlString html , params string [ ] tags )
{
return StripHtml ( html . ToHtmlString ( ) , tags ) ;
}
public HtmlString StripHtml ( DynamicNull html , params string [ ] tags )
{
return new HtmlString ( string . Empty ) ;
}
public HtmlString StripHtml ( string html , params string [ ] tags )
{
return StripHtmlTags ( html , tags ) ;
}
private HtmlString StripHtmlTags ( string html , params string [ ] tags )
{
var doc = new HtmlDocument ( ) ;
doc . LoadHtml ( "<p>" + html + "</p>" ) ;
using ( var ms = new MemoryStream ( ) )
{
var targets = new List < HtmlNode > ( ) ;
var nodes = doc . DocumentNode . FirstChild . SelectNodes ( ".//*" ) ;
if ( nodes ! = null )
{
foreach ( var node in nodes )
{
//is element
if ( node . NodeType ! = HtmlNodeType . Element ) continue ;
var filterAllTags = ( tags = = null | | ! tags . Any ( ) ) ;
if ( filterAllTags | | tags . Any ( tag = > string . Equals ( tag , node . Name , StringComparison . CurrentCultureIgnoreCase ) ) )
{
targets . Add ( node ) ;
}
}
foreach ( var target in targets )
{
HtmlNode content = doc . CreateTextNode ( target . InnerText ) ;
target . ParentNode . ReplaceChild ( content , target ) ;
}
}
else
{
return new HtmlString ( html ) ;
}
return new HtmlString ( doc . DocumentNode . FirstChild . InnerHtml ) ;
}
}
public string Coalesce ( params object [ ] args )
{
return Coalesce < DynamicNull > ( args ) ;
}
internal string Coalesce < TIgnore > ( params object [ ] args )
{
foreach ( var sArg in args . Where ( arg = > arg ! = null & & arg . GetType ( ) ! = typeof ( TIgnore ) ) . Select ( arg = > string . Format ( "{0}" , arg ) ) . Where ( sArg = > ! string . IsNullOrWhiteSpace ( sArg ) ) )
{
return sArg ;
}
return string . Empty ;
}
public string Concatenate ( params object [ ] args )
{
return Concatenate < DynamicNull > ( args ) ;
}
internal string Concatenate < TIgnore > ( params object [ ] args )
{
var result = new StringBuilder ( ) ;
foreach ( var sArg in args . Where ( arg = > arg ! = null & & arg . GetType ( ) ! = typeof ( TIgnore ) ) . Select ( arg = > string . Format ( "{0}" , arg ) ) . Where ( sArg = > ! string . IsNullOrWhiteSpace ( sArg ) ) )
{
result . Append ( sArg ) ;
}
return result . ToString ( ) ;
}
public string Join ( string seperator , params object [ ] args )
{
return Join < DynamicNull > ( seperator , args ) ;
}
internal string Join < TIgnore > ( string seperator , params object [ ] args )
{
2012-09-27 08:30:35 +07:00
var results = args . Where ( arg = > arg ! = null & & arg . GetType ( ) ! = typeof ( TIgnore ) ) . Select ( arg = > string . Format ( "{0}" , arg ) ) . Where ( sArg = > ! string . IsNullOrWhiteSpace ( sArg ) ) . ToList ( ) ;
2012-09-14 09:09:23 +07:00
return string . Join ( seperator , results ) ;
}
public IHtmlString Truncate ( IHtmlString html , int length )
{
return Truncate ( html . ToHtmlString ( ) , length , true , false ) ;
}
public IHtmlString Truncate ( IHtmlString html , int length , bool addElipsis )
{
return Truncate ( html . ToHtmlString ( ) , length , addElipsis , false ) ;
}
public IHtmlString Truncate ( IHtmlString html , int length , bool addElipsis , bool treatTagsAsContent )
{
return Truncate ( html . ToHtmlString ( ) , length , addElipsis , treatTagsAsContent ) ;
}
public IHtmlString Truncate ( DynamicNull html , int length )
{
return new HtmlString ( string . Empty ) ;
}
public IHtmlString Truncate ( DynamicNull html , int length , bool addElipsis )
{
return new HtmlString ( string . Empty ) ;
}
public IHtmlString Truncate ( DynamicNull html , int length , bool addElipsis , bool treatTagsAsContent )
{
return new HtmlString ( string . Empty ) ;
}
public IHtmlString Truncate ( string html , int length )
{
return Truncate ( html , length , true , false ) ;
}
public IHtmlString Truncate ( string html , int length , bool addElipsis )
{
return Truncate ( html , length , addElipsis , false ) ;
}
public IHtmlString Truncate ( string html , int length , bool addElipsis , bool treatTagsAsContent )
{
using ( var outputms = new MemoryStream ( ) )
{
using ( var outputtw = new StreamWriter ( outputms ) )
{
using ( var ms = new MemoryStream ( ) )
{
using ( var tw = new StreamWriter ( ms ) )
{
tw . Write ( html ) ;
tw . Flush ( ) ;
ms . Position = 0 ;
var tagStack = new Stack < string > ( ) ;
using ( TextReader tr = new StreamReader ( ms ) )
{
bool IsInsideElement = false ;
bool lengthReached = false ;
int ic = 0 ;
int currentLength = 0 , currentTextLength = 0 ;
string currentTag = string . Empty ;
string tagContents = string . Empty ;
bool insideTagSpaceEncountered = false ;
bool isTagClose = false ;
while ( ( ic = tr . Read ( ) ) ! = - 1 )
{
bool write = true ;
if ( ic = = ( int ) '<' )
{
if ( ! lengthReached )
{
IsInsideElement = true ;
}
insideTagSpaceEncountered = false ;
currentTag = string . Empty ;
tagContents = string . Empty ;
isTagClose = false ;
if ( tr . Peek ( ) = = ( int ) '/' )
{
isTagClose = true ;
}
}
else if ( ic = = ( int ) '>' )
{
//if (IsInsideElement)
//{
IsInsideElement = false ;
//if (write)
//{
// outputtw.Write('>');
//}
currentTextLength + + ;
if ( isTagClose & & tagStack . Count > 0 )
{
string thisTag = tagStack . Pop ( ) ;
outputtw . Write ( "</" + thisTag + ">" ) ;
}
if ( ! isTagClose & & currentTag . Length > 0 )
{
if ( ! lengthReached )
{
tagStack . Push ( currentTag ) ;
outputtw . Write ( "<" + currentTag ) ;
if ( tr . Peek ( ) ! = ( int ) ' ' )
{
if ( ! string . IsNullOrEmpty ( tagContents ) )
{
if ( tagContents . EndsWith ( "/" ) )
{
//short close
tagStack . Pop ( ) ;
}
outputtw . Write ( tagContents ) ;
}
outputtw . Write ( ">" ) ;
}
}
}
//}
continue ;
}
else
{
if ( IsInsideElement )
{
if ( ic = = ( int ) ' ' )
{
if ( ! insideTagSpaceEncountered )
{
insideTagSpaceEncountered = true ;
//if (!isTagClose)
//{
// tagStack.Push(currentTag);
//}
}
}
if ( ! insideTagSpaceEncountered )
{
currentTag + = ( char ) ic ;
}
}
}
if ( IsInsideElement | | insideTagSpaceEncountered )
{
write = false ;
if ( insideTagSpaceEncountered )
{
tagContents + = ( char ) ic ;
}
}
if ( ! IsInsideElement | | treatTagsAsContent )
{
currentTextLength + + ;
}
currentLength + + ;
if ( currentTextLength < = length | | ( lengthReached & & IsInsideElement ) )
{
if ( write )
{
outputtw . Write ( ( char ) ic ) ;
}
}
if ( ! lengthReached & & currentTextLength > = length )
{
//reached truncate point
if ( addElipsis )
{
outputtw . Write ( "…" ) ;
}
lengthReached = true ;
}
}
}
}
}
outputtw . Flush ( ) ;
outputms . Position = 0 ;
using ( TextReader outputtr = new StreamReader ( outputms ) )
{
return new HtmlString ( outputtr . ReadToEnd ( ) . Replace ( " " , " " ) . Trim ( ) ) ;
}
}
}
}
#endregion
#region If
public HtmlString If ( bool test , string valueIfTrue , string valueIfFalse )
{
return test ? new HtmlString ( valueIfTrue ) : new HtmlString ( valueIfFalse ) ;
}
public HtmlString If ( bool test , string valueIfTrue )
{
return test ? new HtmlString ( valueIfTrue ) : new HtmlString ( string . Empty ) ;
}
#endregion
2012-09-20 13:16:38 +07:00
2012-09-03 07:54:09 +07:00
}
}