/// <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 (DisposableTimer.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); }); } } }
/// <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; string elementText = GetFieldContents(item); using (DisposableTimer.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); }); } }
/// <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) { // check if a macro (tag) is specified if (!string.IsNullOrEmpty(this.Options.MacroTag)) { // get the node for the current page var node = uQuery.GetCurrentNode(); // if the node is null (either document is unpublished, or rendering from outside the content section) if (node == null) { // then get the first child node from the XML content root var nodes = uQuery.GetNodesByXPath(string.Concat("descendant::*[@parentID = ", uQuery.RootNodeId, "]")).ToList(); if (nodes != null && nodes.Count > 0) { node = nodes[0]; } } if (node != null) { // load the page reference var umbPage = new page(node.Id, node.Version); HttpContext.Current.Items["pageID"] = node.Id; HttpContext.Current.Items["pageElements"] = umbPage.Elements; var attr = XmlHelper.GetAttributesFromElement(this.Options.MacroTag); if (attr.ContainsKey("macroalias")) { var macro = new Macro() { Alias = attr["macroalias"].ToString() }; foreach (var item in attr) { macro.Attributes.Add(item.Key.ToString(), item.Value.ToString()); } this.Controls.Add(macro); } } else { this.Controls.Add(new Literal() { Text = "<em>There are no published content nodes (yet), therefore the macro can not be rendered.</em>" }); } } base.OnInit(e); }
/// <summary> /// Builds the link to the related item /// </summary> /// <param name="relatedCMSNode">The related CMS node.</param> /// <returns></returns> private HtmlGenericControl BuildLinkToRelated(CMSNode relatedCMSNode) { HtmlGenericControl li = new HtmlGenericControl("li"); if (this.options.RepeatDirection == RepeatDirection.Horizontal) { li.Attributes.Add("style", "float:left;margin-right:5px;"); } HtmlAnchor a = new HtmlAnchor(); string img = string.Empty; switch (uQuery.GetUmbracoObjectType(relatedCMSNode.nodeObjectType)) { case uQuery.UmbracoObjectType.Document: a.HRef = "javascript:jumpToEditContent(" + relatedCMSNode.Id + ");"; // WARNING - getting the content icon cia the document api may potentially be slow img = "/umbraco/images/umbraco/" + uQuery.GetDocument(relatedCMSNode.Id).ContentTypeIcon; break; case uQuery.UmbracoObjectType.Media: a.HRef = "javascript:jumpToEditMedia(" + relatedCMSNode.Id + ");"; img = "/umbraco/images/umbraco/" + uQuery.GetMedia(relatedCMSNode.Id).ContentTypeIcon; break; case uQuery.UmbracoObjectType.Member: a.HRef = "javascript:jumpToEditMember(" + relatedCMSNode.Id + ");"; img = "/umbraco/images/umbraco/" + uQuery.GetMember(relatedCMSNode.Id).ContentTypeIcon; break; } // is there a macro ? if (string.IsNullOrWhiteSpace(this.options.MacroAlias)) { // default - no macro set a.Controls.Add(new HtmlImage() { Src = img }); a.Controls.Add(new LiteralControl(relatedCMSNode.Text)); } else { // use macro for markup - to execute a macro, at least one item must be published - as context needed to execute macro ? // get the node for the current page Node contextNode = uQuery.GetCurrentNode(); // if the node is null (either document is unpublished, or rendering from outside the content section) if (contextNode == null) { // then get the first child node from the XML content root contextNode = uQuery.GetNodesByXPath(string.Concat("descendant::*[@parentID = ", uQuery.RootNodeId, "]")).FirstOrDefault(); } if (contextNode != null) { // load the page reference HttpContext.Current.Items["pageID"] = contextNode.Id; //HttpContext.Current.Items["pageElements"] = new page(contextNode.Id, contextNode.Version).Elements; } else { // nothing published ! so can't run a macro } Macro macro = new Macro() { Alias = this.options.MacroAlias }; macro.MacroAttributes.Add("id", relatedCMSNode.Id); a.Controls.Add(new LiteralControl(macro.RenderToString())); } li.Controls.Add(a); return li; }
/// <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; } string elementText = GetFieldContents(item); StringBuilder output = new StringBuilder(); StringBuilder fieldResult = new StringBuilder(elementText); bool stop = false; while (!stop) { int tagIndex = fieldResult.ToString().ToLower().IndexOf("<?umbraco"); if (tagIndex < 0) { tagIndex = fieldResult.ToString().ToLower().IndexOf("<umbraco:macro"); } if (tagIndex > -1) { String tempElementContent = ""; item.Controls.Add(new LiteralControl(fieldResult.ToString().Substring(0, tagIndex))); fieldResult.Remove(0, tagIndex); String tag = fieldResult.ToString().Substring(0, fieldResult.ToString().IndexOf(">") + 1); Hashtable attributes = helper.ReturnAttributes(tag); // Check whether it's a single tag (<?.../>) or a tag with children (<?..>...</?...>) if (tag.Substring(tag.Length - 2, 1) != "/" && tag.IndexOf(" ") > -1) { String closingTag = "</" + (tag.Substring(1, tag.IndexOf(" ") - 1)) + ">"; // Tag with children are only used when a macro is inserted by the umbraco-editor, in the // following format: "<?UMBRACO_MACRO ...><IMG SRC="..."..></?UMBRACO_MACRO>", so we // need to delete extra information inserted which is the image-tag and the closing // umbraco_macro tag if (fieldResult.ToString().IndexOf(closingTag) > -1) { fieldResult.Remove(0, fieldResult.ToString().IndexOf(closingTag)); } } Macro macroControl = new Macro(); macroControl.Alias = helper.FindAttribute(attributes, "macroalias"); if (macroControl.Alias.Length == 0) { macroControl.Alias = helper.FindAttribute(attributes, "alias"); } IDictionaryEnumerator ide = attributes.GetEnumerator(); while (ide.MoveNext()) { if (macroControl.Attributes[ide.Key.ToString()] == null) { macroControl.Attributes.Add(ide.Key.ToString(), ide.Value.ToString()); } } item.Controls.Add(macroControl); fieldResult.Remove(0, fieldResult.ToString().IndexOf(">") + 1); fieldResult.Insert(0, tempElementContent); } else { item.Controls.Add(new LiteralControl(fieldResult.ToString())); break; } } }
/// <summary> /// /// </summary> /// <param name="key">passed by parameter into the macro</param> /// <param name="label">value to return if macro fails</param> /// <param name="keys">csv of all keys</param> /// <param name="counter">current postion</param> /// <param name="total">total number of keys</param> /// <returns>the output of the macro as a string</returns> private string ProcessMacro(string key, string label, string keys, int counter, int total) { if (!string.IsNullOrWhiteSpace(this.MacroAlias) && this.HasMacroContext) { Macro macro = new Macro() { Alias = this.MacroAlias }; macro.MacroAttributes.Add("contextId".ToLower(), this.ContextId); macro.MacroAttributes.Add("propertyAlias".ToLower(), this.PropertyAlias); macro.MacroAttributes.Add("key", key); macro.MacroAttributes.Add("label", label); macro.MacroAttributes.Add("keys", keys); macro.MacroAttributes.Add("counter", counter); macro.MacroAttributes.Add("total", total); label = this.RenderToString(macro); } return label; }
/// <summary> /// Method added here to remove the need for the more generic ControlExtensions (as unlikely to need this functionality elsewhere) /// </summary> /// <param name="macro"></param> private string RenderToString(Macro macro) { StringBuilder stringBuilder = new StringBuilder(); using (StringWriter stringWriter = new StringWriter(stringBuilder)) using (HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter)) { macro.RenderControl(htmlTextWriter); } return stringBuilder.ToString(); }