🙈 WOW this was super old Umbraco V3 days of <umbraco:item runat="server" /> WebForms days
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.ComponentModel;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
namespace umbraco.presentation.templateControls
|
||||
{
|
||||
[DefaultProperty("MimeType")]
|
||||
[ToolboxData("<{0}:ContentType runat=server></{0}:ContentType>")]
|
||||
public class ContentType : WebControl
|
||||
{
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue("")]
|
||||
public string MimeType { get; set; }
|
||||
|
||||
protected override void OnPreRender(EventArgs e)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(MimeType))
|
||||
{
|
||||
Page.Response.ContentType = MimeType;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Render(HtmlTextWriter writer)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace umbraco.presentation.templateControls
|
||||
{
|
||||
/// <summary>
|
||||
/// This control disables request validation (equalevant of setting validateRequest to false in page directive)
|
||||
/// </summary>
|
||||
[ToolboxData("<{0}:DisableRequestValidation runat=\"server\"></{0}:Item>")]
|
||||
[Designer("umbraco.presentation.templateControls.ItemDesigner, Umbraco.Web")]
|
||||
public class DisableRequestValidation : System.Web.UI.WebControls.WebControl
|
||||
{
|
||||
protected override void OnInit(EventArgs e)
|
||||
{
|
||||
base.OnInit(e);
|
||||
((UmbracoDefault)base.Page).ValidateRequest = false;
|
||||
}
|
||||
|
||||
protected override void Render(System.Web.UI.HtmlTextWriter writer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,314 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Web;
|
||||
using System.Linq;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Macros;
|
||||
|
||||
|
||||
namespace umbraco.presentation.templateControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Control that renders an Umbraco item on a page.
|
||||
/// </summary>
|
||||
[DefaultProperty("Field")]
|
||||
[ToolboxData("<{0}:Item runat=\"server\"></{0}:Item>")]
|
||||
[Designer("umbraco.presentation.templateControls.ItemDesigner, Umbraco.Web")]
|
||||
public class Item : CompositeControl
|
||||
{
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>The item's unique ID on the page.</summary>
|
||||
private readonly int m_ItemId;
|
||||
public AttributeCollectionAdapter LegacyAttributes;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Used by the UmbracoHelper to assign an IPublishedContent to the Item which allows us to pass this in
|
||||
/// to the 'item' ctor so that it renders with the new API instead of the old one.
|
||||
/// </summary>
|
||||
internal IPublishedContent ContentItem { get; private set; }
|
||||
|
||||
#region Public Control Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the field name.
|
||||
/// </summary>
|
||||
/// <value>The field name.</value>
|
||||
[Bindable(true)]
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue("")]
|
||||
[Localizable(true)]
|
||||
public string Field
|
||||
{
|
||||
get { return (string)ViewState["Field"] ?? String.Empty; }
|
||||
set { ViewState["Field"] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the node id expression.
|
||||
/// </summary>
|
||||
/// <value>The node id expression.</value>
|
||||
[Bindable(true)]
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue("")]
|
||||
[Localizable(true)]
|
||||
public string NodeId
|
||||
{
|
||||
get { return (string)ViewState["NodeId"] ?? String.Empty; }
|
||||
set { ViewState["NodeId"] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text to display if the control is empty.
|
||||
/// </summary>
|
||||
/// <value>The text to display if the control is empty.</value>
|
||||
[Bindable(true)]
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue("")]
|
||||
[Localizable(true)]
|
||||
public string TextIfEmpty
|
||||
{
|
||||
get { return (string)ViewState["TextIfEmpty"] ?? String.Empty; }
|
||||
set { ViewState["TextIfEmpty"] = value; }
|
||||
}
|
||||
|
||||
[Bindable(true)]
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue("")]
|
||||
[Localizable(true)]
|
||||
public bool DebugMode
|
||||
{
|
||||
get { return ((ViewState["DebugMode"] == null) ? false : (bool)ViewState["DebugMode"]); }
|
||||
set { ViewState["DebugMode"] = value; }
|
||||
}
|
||||
|
||||
public ItemRenderer Renderer { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Readonly Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item's unique ID on the page.
|
||||
/// </summary>
|
||||
/// <value>The item id.</value>
|
||||
public int ItemId
|
||||
{
|
||||
get { return m_ItemId; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Umbraco page elements.
|
||||
/// </summary>
|
||||
/// <value>The Umbraco page elements.</value>
|
||||
public Hashtable PageElements
|
||||
{
|
||||
get
|
||||
{
|
||||
return Context.Items["pageElements"] as Hashtable;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Item"/> class.
|
||||
/// </summary>
|
||||
public Item()
|
||||
{
|
||||
Renderer = ItemRenderer.Instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal ctor used to assign an IPublishedContent object.
|
||||
/// </summary>
|
||||
/// <param name="contentItem"></param>
|
||||
internal Item(IPublishedContent contentItem)
|
||||
:this()
|
||||
{
|
||||
ContentItem = contentItem;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overriden Control Methods
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
|
||||
protected override void OnInit(EventArgs e)
|
||||
{
|
||||
Attributes.Add("field", Field);
|
||||
LegacyAttributes = new AttributeCollectionAdapter(Attributes);
|
||||
Renderer.Init(this);
|
||||
|
||||
base.OnInit(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="E:System.Web.UI.Control.Load"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
Renderer.Load(this);
|
||||
|
||||
base.OnLoad(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the <see cref="T:System.Web.UI.WebControls.CompositeControl"/> content
|
||||
/// to the specified <see cref="T:System.Web.UI.HtmlTextWriter"/> object, for display on the client.
|
||||
/// </summary>
|
||||
/// <param name="writer">
|
||||
/// An <see cref="T:System.Web.UI.HtmlTextWriter"/> that represents
|
||||
/// the output stream to render HTML content on the client.
|
||||
/// </param>
|
||||
protected override void Render(HtmlTextWriter writer)
|
||||
{
|
||||
Renderer.Render(this, writer);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Functions
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parsed node id. As a nodeid on a item element can be null, an integer or even a squarebracket syntax, this helper method
|
||||
/// is handy for getting the exact parsed nodeid back.
|
||||
/// </summary>
|
||||
/// <returns>The parsed nodeid, the id of the current page OR null if it's not specified</returns>
|
||||
public int? GetParsedNodeId()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(NodeId))
|
||||
{
|
||||
string tempNodeId = MacroRenderer.ParseAttribute(PageElements, NodeId);
|
||||
int nodeIdInt = 0;
|
||||
if (int.TryParse(tempNodeId, out nodeIdInt))
|
||||
{
|
||||
return nodeIdInt;
|
||||
}
|
||||
}
|
||||
else if (UmbracoContext.Current.PageId != null)
|
||||
{
|
||||
return UmbracoContext.Current.PageId.Value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this control is inside the form tag.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if this control is inside the form tag; otherwise, <c>false</c>.</returns>
|
||||
protected virtual bool IsInsideFormTag()
|
||||
{
|
||||
// check if this control has an ancestor that is the page form
|
||||
for (Control parent = this.Parent; parent != null; parent = parent.Parent)
|
||||
if (parent == Page.Form)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("Item {0} (NodeId '{1}' : {2})", ItemId, NodeId, Field);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Field Information Functions
|
||||
|
||||
static string FindAttribute(IDictionary attributes, string key)
|
||||
{
|
||||
key = key.ToLowerInvariant();
|
||||
var attributeValue = attributes.Contains(key) ? attributes[key].ToString() : string.Empty;
|
||||
return MacroRenderer.ParseAttribute(null, attributeValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the field is a dictionary item.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the field is a dictionary item; otherwise, <c>false</c>.</returns>
|
||||
protected virtual bool FieldIsDictionaryItem()
|
||||
{
|
||||
return FindAttribute(new AttributeCollectionAdapter(Attributes), "field").StartsWith("#");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the field is recursive.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the field is recursive; otherwise, <c>false</c>.</returns>
|
||||
protected virtual bool FieldIsRercursive()
|
||||
{
|
||||
return FindAttribute(new AttributeCollectionAdapter(Attributes), "recursive") == "true";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current item is editable by the current user.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if the current item is editable by the current user; otherwise, <c>false</c>.</value>
|
||||
protected virtual bool FieldEditableWithUserPermissions()
|
||||
{
|
||||
var u = UmbracoContext.Current.Security.CurrentUser;
|
||||
if (u == null) return false;
|
||||
var permission = Current.Services.UserService.GetPermissions(u, PageElements["path"].ToString());
|
||||
|
||||
return permission.AssignedPermissions.Contains(ActionUpdate.ActionLetter.ToString(CultureInfo.InvariantCulture), StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class ItemDesigner : System.Web.UI.Design.ControlDesigner {
|
||||
|
||||
private Item m_control;
|
||||
|
||||
public override string GetDesignTimeHtml()
|
||||
{
|
||||
m_control = this.Component as Item;
|
||||
return returnMarkup(String.Format("Getting '{0}'", m_control.Field));
|
||||
}
|
||||
|
||||
private string returnMarkup(string message)
|
||||
{
|
||||
return "<span style=\"background-color: #DDD; padding: 2px;\">" + message + "</span>";
|
||||
}
|
||||
|
||||
protected override string GetErrorDesignTimeHtml(Exception e)
|
||||
{
|
||||
if (this.Component != null) {
|
||||
m_control = this.Component as Item;
|
||||
}
|
||||
|
||||
if (m_control != null && !String.IsNullOrEmpty(m_control.Field))
|
||||
{
|
||||
return returnMarkup(String.Format("Getting '{0}'", m_control.Field));
|
||||
}
|
||||
else { return returnMarkup("<em>Please add a Field property</em>"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,226 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Xml;
|
||||
using Umbraco.Core.Macros;
|
||||
using Umbraco.Web.Templates;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Macros;
|
||||
|
||||
namespace umbraco.presentation.templateControls
|
||||
{
|
||||
public class ItemRenderer
|
||||
{
|
||||
public readonly static ItemRenderer Instance = new ItemRenderer();
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ItemRenderer"/> class.
|
||||
/// </summary>
|
||||
protected ItemRenderer()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Renders the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Render(Item item, HtmlTextWriter writer)
|
||||
{
|
||||
if (item.DebugMode)
|
||||
{
|
||||
writer.AddAttribute(HtmlTextWriterAttribute.Title, string.Format("Field Tag: '{0}'", item.Field));
|
||||
writer.AddAttribute("style", "border: 1px solid #fc6;");
|
||||
writer.RenderBeginTag(HtmlTextWriterTag.Div);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
StringWriter renderOutputWriter = new StringWriter();
|
||||
HtmlTextWriter htmlWriter = new HtmlTextWriter(renderOutputWriter);
|
||||
foreach (Control control in item.Controls)
|
||||
{
|
||||
try
|
||||
{
|
||||
control.RenderControl(htmlWriter);
|
||||
}
|
||||
catch (Exception renderException)
|
||||
{
|
||||
// TODO: Validate that the current control is within the scope of a form control
|
||||
// Even controls that are inside this scope, can produce this error in async postback.
|
||||
HttpContext.Current.Trace.Warn("ItemRenderer",
|
||||
String.Format("Error rendering control {0} of {1}.", control.ClientID, item), renderException);
|
||||
}
|
||||
}
|
||||
|
||||
// parse macros and execute the XSLT transformation on the result if not empty
|
||||
string renderOutput = renderOutputWriter.ToString();
|
||||
renderOutput = renderOutput.Trim().Length == 0 ? string.Empty : renderOutput;
|
||||
// handle text before/after
|
||||
renderOutput = AddBeforeAfterText(renderOutput, FindAttribute(item.LegacyAttributes, "insertTextBefore"), FindAttribute(item.LegacyAttributes, "insertTextAfter"));
|
||||
string finalResult = renderOutput.Trim().Length > 0 ? renderOutput : GetEmptyText(item);
|
||||
|
||||
//Don't parse urls if a content item is assigned since that is taken care
|
||||
// of with the value converters
|
||||
if (item.ContentItem == null)
|
||||
{
|
||||
writer.Write(TemplateUtilities.ResolveUrlsFromTextString(finalResult));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(finalResult);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception renderException)
|
||||
{
|
||||
HttpContext.Current.Trace.Warn("ItemRenderer", String.Format("Error rendering {0}.", item), renderException);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (item.DebugMode)
|
||||
{
|
||||
writer.RenderEndTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string FindAttribute(IDictionary attributes, string key)
|
||||
{
|
||||
key = key.ToLowerInvariant();
|
||||
var attributeValue = attributes.Contains(key) ? attributes[key].ToString() : string.Empty;
|
||||
return MacroRenderer.ParseAttribute(null, attributeValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the field contents.
|
||||
/// Checks via the NodeId attribute whether to fetch data from another page than the current one.
|
||||
/// </summary>
|
||||
/// <returns>A string of field contents (macros not parsed)</returns>
|
||||
protected virtual string GetFieldContents(Item item)
|
||||
{
|
||||
var tempElementContent = string.Empty;
|
||||
|
||||
// if a nodeId is specified we should get the data from another page than the current one
|
||||
if (string.IsNullOrEmpty(item.NodeId) == false)
|
||||
{
|
||||
var tempNodeId = item.GetParsedNodeId();
|
||||
if (tempNodeId != null && tempNodeId.Value != 0)
|
||||
{
|
||||
//moved the following from the catch block up as this will allow fallback options alt text etc to work
|
||||
// stop using GetXml
|
||||
//var cache = Umbraco.Web.UmbracoContext.Current.ContentCache.InnerCache as PublishedContentCache;
|
||||
//if (cache == null) throw new InvalidOperationException("Unsupported IPublishedContentCache, only the Xml one is supported.");
|
||||
//var xml = cache.GetXml(Umbraco.Web.UmbracoContext.Current, Umbraco.Web.UmbracoContext.Current.InPreviewMode);
|
||||
//var itemPage = new page(xml.GetElementById(tempNodeId.ToString()));
|
||||
var c = Umbraco.Web.UmbracoContext.Current.ContentCache.GetById(tempNodeId.Value);
|
||||
var itemPage = new page(c);
|
||||
|
||||
tempElementContent =
|
||||
new item(item.ContentItem, itemPage.Elements, item.LegacyAttributes).FieldContent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// gets the field content from the current page (via the PageElements collection)
|
||||
tempElementContent =
|
||||
new item(item.ContentItem, item.PageElements, item.LegacyAttributes).FieldContent;
|
||||
}
|
||||
|
||||
return tempElementContent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inits the specified item. To be called from the OnInit method of Item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
public virtual void Init(Item item)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Loads the specified item. To be called from the OnLoad method of Item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
public virtual void Load(Item item)
|
||||
{
|
||||
using (Current.ProfilingLogger.DebugDuration<ItemRenderer>(string.Format("Item: {0}", item.Field)))
|
||||
{
|
||||
ParseMacros(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the macros inside the text, by creating child elements for each item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
protected virtual void ParseMacros(Item item)
|
||||
{
|
||||
// do nothing if the macros have already been rendered
|
||||
if (item.Controls.Count > 0)
|
||||
return;
|
||||
|
||||
var elementText = GetFieldContents(item);
|
||||
|
||||
//Don't parse macros if there's a content item assigned since the content value
|
||||
// converters take care of that, just add the already parsed text
|
||||
if (item.ContentItem != null)
|
||||
{
|
||||
item.Controls.Add(new LiteralControl(elementText));
|
||||
}
|
||||
else
|
||||
{
|
||||
using (Current.ProfilingLogger.DebugDuration<ItemRenderer>("Parsing Macros"))
|
||||
{
|
||||
|
||||
MacroTagParser.ParseMacros(
|
||||
elementText,
|
||||
|
||||
//callback for when a text block is parsed
|
||||
textBlock => item.Controls.Add(new LiteralControl(textBlock)),
|
||||
|
||||
//callback for when a macro is parsed:
|
||||
(macroAlias, attributes) =>
|
||||
{
|
||||
var macroControl = new Macro
|
||||
{
|
||||
Alias = macroAlias
|
||||
};
|
||||
foreach (var i in attributes.Where(i => macroControl.Attributes[i.Key] == null))
|
||||
{
|
||||
macroControl.Attributes.Add(i.Key, i.Value);
|
||||
}
|
||||
item.Controls.Add(macroControl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected string AddBeforeAfterText(string text, string before, string after)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(text))
|
||||
{
|
||||
if (!String.IsNullOrEmpty(before))
|
||||
text = String.Format("{0}{1}", HttpContext.Current.Server.HtmlDecode(before), text);
|
||||
if (!String.IsNullOrEmpty(after))
|
||||
text = String.Format("{0}{1}", text, HttpContext.Current.Server.HtmlDecode(after));
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the text to display if the field contents are empty.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>The text to display.</returns>
|
||||
protected virtual string GetEmptyText(Item item)
|
||||
{
|
||||
return item.TextIfEmpty;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Collections;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Macros;
|
||||
|
||||
namespace umbraco.presentation.templateControls
|
||||
{
|
||||
|
||||
[DefaultProperty("Alias")]
|
||||
[ToolboxData("<{0}:Macro runat=server></{0}:Macro>")]
|
||||
[PersistChildren(false)]
|
||||
[ParseChildren(true, "Text")]
|
||||
public class Macro : WebControl, ITextControl
|
||||
{
|
||||
public Hashtable MacroAttributes { get; set; } = new Hashtable();
|
||||
|
||||
[Bindable(true)]
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue("")]
|
||||
[Localizable(true)]
|
||||
public string Alias
|
||||
{
|
||||
get
|
||||
{
|
||||
var s = (string)ViewState["Alias"];
|
||||
return s ?? string.Empty;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
ViewState["Alias"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Bindable(true)]
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue("")]
|
||||
[Localizable(true)]
|
||||
public string Language {
|
||||
get {
|
||||
var s = (string)ViewState["Language"];
|
||||
return s ?? string.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["Language"] = value.ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
[Bindable(true)]
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue("")]
|
||||
[Localizable(true)]
|
||||
public string FileLocation {
|
||||
get {
|
||||
var s = (string)ViewState["FileLocation"];
|
||||
return s ?? string.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["FileLocation"] = value.ToLower();
|
||||
}
|
||||
}
|
||||
[Bindable(true)]
|
||||
[Category("Umbraco")]
|
||||
[DefaultValue(RenderEvents.Init)]
|
||||
[Localizable(true)]
|
||||
public RenderEvents RenderEvent
|
||||
{
|
||||
get
|
||||
{
|
||||
var renderEvent = RenderEvents.Init;
|
||||
if (ViewState["RenderEvent"] != null)
|
||||
renderEvent = (RenderEvents)ViewState["RenderEvent"];
|
||||
return renderEvent;
|
||||
}
|
||||
set
|
||||
{
|
||||
ViewState["RenderEvent"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Indicates where to run EnsureChildControls and effectively render the macro
|
||||
public enum RenderEvents
|
||||
{
|
||||
Init,
|
||||
PreRender,
|
||||
Render
|
||||
}
|
||||
|
||||
public IList<Exception> Exceptions = new List<Exception>();
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
|
||||
protected override void OnInit(EventArgs e) {
|
||||
base.OnInit(e);
|
||||
|
||||
// Create child controls when told to - this is the default
|
||||
if (RenderEvent == RenderEvents.Init)
|
||||
EnsureChildControls();
|
||||
}
|
||||
|
||||
// Create child controls when told to - new option to render at PreRender
|
||||
protected override void OnPreRender(EventArgs e)
|
||||
{
|
||||
base.OnPreRender(e);
|
||||
|
||||
if (RenderEvent == RenderEvents.PreRender)
|
||||
EnsureChildControls();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
|
||||
/// </summary>
|
||||
protected override void CreateChildControls() {
|
||||
// collect all attributes set on the control
|
||||
var keys = Attributes.Keys;
|
||||
foreach (string key in keys)
|
||||
MacroAttributes.Add(key.ToLower(), HttpUtility.HtmlDecode(Attributes[key]));
|
||||
|
||||
if (MacroAttributes.ContainsKey("macroalias") == false && MacroAttributes.ContainsKey("macroAlias") == false)
|
||||
MacroAttributes.Add("macroalias", Alias);
|
||||
|
||||
// set pageId to int.MinValue if no pageID was found,
|
||||
// e.g. if the macro was rendered on a custom (non-Umbraco) page
|
||||
var pageId = UmbracoContext.Current.PageId == null ? int.MinValue : UmbracoContext.Current.PageId.Value;
|
||||
|
||||
if ((string.IsNullOrEmpty(Language) == false && Text != "") || string.IsNullOrEmpty(FileLocation) == false) {
|
||||
var tempMacro = new MacroModel();
|
||||
MacroRenderer.GenerateMacroModelPropertiesFromAttributes(tempMacro, MacroAttributes);
|
||||
|
||||
// executing an inline macro?
|
||||
// ie the code of the macro is in the control's text body
|
||||
// ok, this is not supported in v8 anymore
|
||||
if (string.IsNullOrEmpty(FileLocation))
|
||||
throw new NotSupportedException("Inline macros are not supported anymore.");
|
||||
|
||||
// executing an on-disk macro
|
||||
// it has to be a partial (cshtml or vbhtml) macro in v8
|
||||
var extension = System.IO.Path.GetExtension(FileLocation);
|
||||
if (extension.InvariantEndsWith(".cshtml") == false && extension.InvariantEndsWith(".vbhtml") == false)
|
||||
throw new NotSupportedException("");
|
||||
|
||||
tempMacro.MacroSource = FileLocation;
|
||||
tempMacro.MacroType = MacroTypes.PartialView;
|
||||
|
||||
if (string.IsNullOrEmpty(Attributes["Cache"]) == false)
|
||||
{
|
||||
int cacheDuration;
|
||||
if (int.TryParse(Attributes["Cache"], out cacheDuration))
|
||||
tempMacro.CacheDuration = cacheDuration;
|
||||
else
|
||||
Context.Trace.Warn("Template", "Cache attribute is in incorect format (should be an integer).");
|
||||
}
|
||||
|
||||
var renderer = new MacroRenderer(Current.ProfilingLogger);
|
||||
var c = renderer.Render(tempMacro, (Hashtable) Context.Items["pageElements"], pageId).GetAsControl();
|
||||
if (c != null)
|
||||
{
|
||||
Exceptions = renderer.Exceptions;
|
||||
Controls.Add(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.Trace.Warn("Template", "Result of inline macro scripting is null");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = Current.Services.MacroService.GetByAlias(Alias);
|
||||
if (m == null) return;
|
||||
|
||||
var tempMacro = new MacroModel(m);
|
||||
try
|
||||
{
|
||||
var renderer = new MacroRenderer(Current.ProfilingLogger);
|
||||
var c = renderer.Render(tempMacro, (Hashtable)Context.Items["pageElements"], pageId, MacroAttributes).GetAsControl();
|
||||
if (c != null)
|
||||
Controls.Add(c);
|
||||
else
|
||||
Context.Trace.Warn("Template", "Result of macro " + tempMacro.Name + " is null");
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
Context.Trace.Warn("Template", "Error adding macro " + tempMacro.Name, ee);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the control to the specified HTML writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.</param>
|
||||
protected override void Render(HtmlTextWriter writer)
|
||||
{
|
||||
// Create child controls when told to - do it here anyway as it has to be done
|
||||
EnsureChildControls();
|
||||
|
||||
var isDebug = GlobalSettings.DebugMode && (Context.Request.GetItemAsString("umbdebugshowtrace") != "" || Context.Request.GetItemAsString("umbdebug") != "");
|
||||
if (isDebug)
|
||||
{
|
||||
writer.Write("<div title=\"Macro Tag: '{0}'\" style=\"border: 1px solid #009;\">", Alias);
|
||||
}
|
||||
RenderChildren(writer);
|
||||
if (isDebug)
|
||||
{
|
||||
writer.Write("</div>");
|
||||
}
|
||||
}
|
||||
|
||||
public string Text { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user