protected void Page_Load(object sender, System.EventArgs e) { int macroID = cms.businesslogic.macro.Macro.GetByAlias(helper.Request("umb_macroAlias")).Id; int pageID = int.Parse(helper.Request("umbPageId")); Guid pageVersion = new Guid(helper.Request("umbVersionId")); System.Web.HttpContext.Current.Items["macrosAdded"] = 0; System.Web.HttpContext.Current.Items["pageID"] = pageID.ToString(); // Collect attributes Hashtable attributes = new Hashtable(); foreach (string key in Request.QueryString.AllKeys) { if (key.IndexOf("umb_") > -1) { attributes.Add(key.Substring(4, key.Length - 4), Request.QueryString[key]); } } page p = new page(pageID, pageVersion); macro m = new macro(macroID); Control c = m.renderMacro(attributes, p.Elements, p.PageID); PlaceHolder1.Controls.Add(c); }
/// <summary> /// Renders the macro with the specified alias, passing in the specified parameters. /// </summary> /// <param name="m">The macro.</param> /// <param name="parameters">The parameters.</param> /// <param name="umbracoPage">The legacy umbraco page object that is required for some macros</param> /// <returns></returns> internal IHtmlString RenderMacro(macro m, IDictionary <string, object> parameters, page umbracoPage) { if (umbracoPage == null) { throw new ArgumentNullException("umbracoPage"); } if (m == null) { throw new ArgumentNullException("m"); } if (_umbracoContext.PageId == null) { throw new InvalidOperationException("Cannot render a macro when UmbracoContext.PageId is null."); } var macroProps = new Hashtable(); foreach (var i in parameters) { //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. //NOTE: the value could have html encoded values, so we need to deal with that macroProps.Add(i.Key.ToLowerInvariant(), (i.Value is string) ? HttpUtility.HtmlDecode(i.Value.ToString()) : i.Value); } var macroControl = m.renderMacro(macroProps, umbracoPage.Elements, _umbracoContext.PageId.Value); string html; if (macroControl is LiteralControl) { // no need to execute, we already have text html = (macroControl as LiteralControl).Text; } else { var containerPage = new FormlessPage(); containerPage.Controls.Add(macroControl); 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). // // 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; var traceIsEnabled = containerPage.Trace.IsEnabled; containerPage.Trace.IsEnabled = false; _umbracoContext.HttpContext.Server.Execute(containerPage, output, true); containerPage.Trace.IsEnabled = traceIsEnabled; //reset the content type _umbracoContext.HttpContext.Response.ContentType = contentType; //Now, we need to ensure that local links are parsed html = TemplateUtilities.ParseInternalLinks(output.ToString()); } } return(new HtmlString(html)); }
/// <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(), Attributes[key]); } if (!MacroAttributes.ContainsKey("macroalias") && !MacroAttributes.ContainsKey("macroAlias")) { 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 int pageId = Context.Items["pageID"] == null ? int.MinValue : int.Parse(Context.Items["pageID"].ToString()); if ((!String.IsNullOrEmpty(Language) && Text != "") || !string.IsNullOrEmpty(FileLocation)) { var tempMacro = new macro(); tempMacro.GenerateMacroModelPropertiesFromAttributes(MacroAttributes); if (string.IsNullOrEmpty(FileLocation)) { tempMacro.Model.ScriptCode = Text; tempMacro.Model.ScriptLanguage = Language; } else { tempMacro.Model.ScriptName = FileLocation; } tempMacro.Model.MacroType = MacroTypes.Script; if (!String.IsNullOrEmpty(Attributes["Cache"])) { var cacheDuration = 0; if (int.TryParse(Attributes["Cache"], out cacheDuration)) { tempMacro.Model.CacheDuration = cacheDuration; } else { System.Web.HttpContext.Current.Trace.Warn("Template", "Cache attribute is in incorect format (should be an integer)."); } } var c = tempMacro.renderMacro((Hashtable)Context.Items["pageElements"], pageId); if (c != null) { Exceptions = tempMacro.Exceptions; Controls.Add(c); } else { System.Web.HttpContext.Current.Trace.Warn("Template", "Result of inline macro scripting is null"); } } else { var tempMacro = macro.GetMacro(Alias); if (tempMacro != null) { try { var c = tempMacro.renderMacro(MacroAttributes, (Hashtable)Context.Items["pageElements"], pageId); if (c != null) { Controls.Add(c); } else { System.Web.HttpContext.Current.Trace.Warn("Template", "Result of macro " + tempMacro.Name + " is null"); } } catch (Exception ee) { System.Web.HttpContext.Current.Trace.Warn("Template", "Error adding macro " + tempMacro.Name, ee); } } } }
/// <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") && !MacroAttributes.ContainsKey("macroAlias")) 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 int pageId = Context.Items["pageID"] == null ? int.MinValue : int.Parse(Context.Items["pageID"].ToString()); if ((!String.IsNullOrEmpty(Language) && Text != "") || !string.IsNullOrEmpty(FileLocation)) { var tempMacro = new macro(); tempMacro.GenerateMacroModelPropertiesFromAttributes(MacroAttributes); if (string.IsNullOrEmpty(FileLocation)) { tempMacro.Model.ScriptCode = Text; tempMacro.Model.ScriptLanguage = Language; } else { tempMacro.Model.ScriptName = FileLocation; } tempMacro.Model.MacroType = MacroTypes.Script; if (!String.IsNullOrEmpty(Attributes["Cache"])) { var cacheDuration = 0; if (int.TryParse(Attributes["Cache"], out cacheDuration)) tempMacro.Model.CacheDuration = cacheDuration; else System.Web.HttpContext.Current.Trace.Warn("Template", "Cache attribute is in incorect format (should be an integer)."); } var c = tempMacro.renderMacro((Hashtable)Context.Items["pageElements"], pageId); if (c != null) { Exceptions = tempMacro.Exceptions; Controls.Add(c); } else System.Web.HttpContext.Current.Trace.Warn("Template", "Result of inline macro scripting is null"); } else { var tempMacro = macro.GetMacro(Alias); if (tempMacro != null) { try { var c = tempMacro.renderMacro(MacroAttributes, (Hashtable)Context.Items["pageElements"], pageId); if (c != null) Controls.Add(c); else System.Web.HttpContext.Current.Trace.Warn("Template", "Result of macro " + tempMacro.Name + " is null"); } catch (Exception ee) { System.Web.HttpContext.Current.Trace.Warn("Template", "Error adding macro " + tempMacro.Name, ee); throw; } } } }