I am attempting to use umbraco.library.RenderMacroContent via the API and it is not passing the macro parameters to the macro. In fact, if I debug, the Page_Load of my macro (usercontrol) is never hit. If I call the method through the Immediate Window when debugging I see an exception: "pageElements" cannot be null.
The HTML from my usercontrol does render, but it doesn't get the parameters it needs to render correctly.
Am I doing anything wrong? My code looks like this:
Thanks, Sebastiaan. I took a look at the blog post but it's not entirely applicable to what I'm trying to do. I'm using C# rather than XSLT and I'm using the C# API to get the value of a rich text field, which contains a paragraph of HTML followed by a macro insertion. If I look at the value of that field I see the complete <?UMBRACO_MACRO value with all of its correct parameters. If I try to do the C# umbraco.library.RenderMacroContent(item.getProperty("description").Value, item.Id) method, I get the HTML of the macro but it didn't process anything from my parameters. If I call this manually, using just a valid macro tag and not all of the HTML from above it, it has the same result. I've tried all of the suggestions for HTML Encoding the tag, etc., but to no avail. Any other ideas?
Hmm, I see, sorry I don't know how to send paramss to RenderMacroContent.
So, how about if you instantiate a macro from code and insert it into a placeholder maybe?
Two options: just insert <umbraco:Macro ... /> etc in your usercontrol, or add it more dynamically like this:
var formId = 1234;
var macro = new Macro { Alias = "Poll" };
macro.MacroAttributes.Add("pollnodeid", formId.ToString());
macro.MacroAttributes.Add("displayonly", "0");
var formContainer = new HtmlForm();
pollContainer.Controls.Add(formContainer);
Unfortunately this won't work because I can't guarantee that the user will or won't have a macro in the rich text editor, and if they do, how many and which ones they've selected. So it would need to be dynamic, like reading the value of that field and rendering any macros contained within. The macro tags do have all of the correct attribute values, they just aren't getting processed.
I see, didn't realize you were getting the macros from the Rte. What might work in that case is if you manually parse the HTML for the Rte, and capture all of the macro calls but I'm not sure that's the best way to go.
Do the editor really need to mix macros and content? Maybe it's easy to set some rules for that, like: here's three eye's and three macro pickers, you can have three macros in between the three text fields..
I'am not an umbraco wizard as you asked on twitter.
I didn't know the renderMacroContent, so i looked it up in the source code. These are the xml comments:
///<summary> /// Renders the content of a macro. Uses the normal template umbraco macro markup as input. /// This only works properly with xslt macros. /// Python and .ascx based macros will not render properly, as viewstate is not included. ///</summary> ///<param name="Text">The macro markup to be rendered.</param> ///<param name="PageId">The page id.</param> ///<returns>The rendered macro as a string</returns>
I guess the solution is in there. if you are not using xslt is function might not be the correct one because the viewstate is not rendered.
Am i completely missing out what you are trying to do? What do you think?
Thanks, Damiaan - I hadn't seen that. I guess what I'm trying to do (essentially process the value of a rich text field, macros included, and get the result as a string) is not possible.
It depends a bit what you want to do. I regulary embed ascx controls in my macro's so users can embed them in the Rich Text Editor.
Can't you use the umbraco.library.RenderTemplate function (or some similar function). Just pass the page id and a (custom) template and you might get what you want.
Without getting into too much detail, this particular case is a macro contained within a macro. There's a page onto which an event detail macro is placed. This macro retrieves a calendar event from the CMS and renders it. First, though, I map a domain object for the calendar event from the values entered into the CMS. One of the fields on the calendar event document type is the event description, which is a rich text field. The content author is attempting to insert another macro into that description field.
The original event detail macro is setting the Text property of a literal = to the value of the description property on the calendar event domain object. Since that description field contains a nested macro, I'm simply trying to RenderMacroContent() on that field prior to passing the string back to the original macro to set its Literal.
This works fine if the nested macro is an XSLT macro. Unfortunately it's an ASCX macro, which, as you point out above, isn't supported. For the nested macro in question I can get around it by rewriting it in XSLT. However, all of my macros are ASCX so hopefully the content author doesn't need to nest another macro. For now, though, rewriting the one in question into XSLT will solve the problem.
Got this exact same problem. Ended up using c# classes with [XsltExtension] and extending them with ApplicationBase. Thus creating a layer of methods which I can call from xslt. Works just fine but it's quite annoying.
I was working on a method which I called instead of the RenderMacroContent. The idea was that it should create the macro, render it and add the result to the output string. But I ran out of time, maybe someone want to continue the development, or explain how this should work
private string RenderMacro(string input, int nodeId)
{
if (string.IsNullOrEmpty(input))
return string.Empty;
var regex = new Regex("]*/>", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
return regex.Replace(input, p =>
{
try
{
// Using the HtmlAgilityPack to control the string
var doc = new HtmlDocument();
doc.LoadHtml(p.Value);
var macroAlias = doc.DocumentNode.SelectSingleNode("//*").Attributes["macroAlias"].Value;
// Create a new instance of my macro
var newMacro = new Macro
{
Alias = macroAlias
};
// Only for debugging, not working very well...
Controls.Add(newMacro);
// Todo! Should return a rendered version of the macro
return umbraco.library.RenderMacroContent(p.Value, nodeId);
}
catch
{
return input;
}
});
}
RenderMacroContent problem
Hello,
I am attempting to use umbraco.library.RenderMacroContent via the API and it is not passing the macro parameters to the macro. In fact, if I debug, the Page_Load of my macro (usercontrol) is never hit. If I call the method through the Immediate Window when debugging I see an exception: "pageElements" cannot be null.
The HTML from my usercontrol does render, but it doesn't get the parameters it needs to render correctly.
Am I doing anything wrong? My code looks like this:
Thanks in advance,
Matt
This blog post
might help.
Thanks, Sebastiaan. I took a look at the blog post but it's not entirely applicable to what I'm trying to do. I'm using C# rather than XSLT and I'm using the C# API to get the value of a rich text field, which contains a paragraph of HTML followed by a macro insertion. If I look at the value of that field I see the complete <?UMBRACO_MACRO value with all of its correct parameters. If I try to do the C# umbraco.library.RenderMacroContent(item.getProperty("description").Value, item.Id) method, I get the HTML of the macro but it didn't process anything from my parameters. If I call this manually, using just a valid macro tag and not all of the HTML from above it, it has the same result. I've tried all of the suggestions for HTML Encoding the tag, etc., but to no avail. Any other ideas?
Thanks,
matt
Hmm, I see, sorry I don't know how to send paramss to RenderMacroContent.
So, how about if you instantiate a macro from code and insert it into a placeholder maybe?
Two options: just insert <umbraco:Macro ... /> etc in your usercontrol, or add it more dynamically like this:
Unfortunately this won't work because I can't guarantee that the user will or won't have a macro in the rich text editor, and if they do, how many and which ones they've selected. So it would need to be dynamic, like reading the value of that field and rendering any macros contained within. The macro tags do have all of the correct attribute values, they just aren't getting processed.
Thanks for your help!
I see, didn't realize you were getting the macros from the Rte. What might work in that case is if you manually parse the HTML for the Rte, and capture all of the macro calls but I'm not sure that's the best way to go.
Do the editor really need to mix macros and content? Maybe it's easy to set some rules for that, like: here's three eye's and three macro pickers, you can have three macros in between the three text fields..
Hi,
I'am not an umbraco wizard as you asked on twitter.
I didn't know the renderMacroContent, so i looked it up in the source code. These are the xml comments:
I guess the solution is in there. if you are not using xslt is function might not be the correct one because the viewstate is not rendered.
Am i completely missing out what you are trying to do? What do you think?
Thanks, Damiaan - I hadn't seen that. I guess what I'm trying to do (essentially process the value of a rich text field, macros included, and get the result as a string) is not possible.
It depends a bit what you want to do. I regulary embed ascx controls in my macro's so users can embed them in the Rich Text Editor.
Can't you use the umbraco.library.RenderTemplate function (or some similar function). Just pass the page id and a (custom) template and you might get what you want.
Without getting into too much detail, this particular case is a macro contained within a macro. There's a page onto which an event detail macro is placed. This macro retrieves a calendar event from the CMS and renders it. First, though, I map a domain object for the calendar event from the values entered into the CMS. One of the fields on the calendar event document type is the event description, which is a rich text field. The content author is attempting to insert another macro into that description field.
The original event detail macro is setting the Text property of a literal = to the value of the description property on the calendar event domain object. Since that description field contains a nested macro, I'm simply trying to RenderMacroContent() on that field prior to passing the string back to the original macro to set its Literal.
This works fine if the nested macro is an XSLT macro. Unfortunately it's an ASCX macro, which, as you point out above, isn't supported. For the nested macro in question I can get around it by rewriting it in XSLT. However, all of my macros are ASCX so hopefully the content author doesn't need to nest another macro. For now, though, rewriting the one in question into XSLT will solve the problem.
Thanks again for your help,
Matt
Got this exact same problem. Ended up using c# classes with [XsltExtension] and extending them with ApplicationBase. Thus creating a layer of methods which I can call from xslt. Works just fine but it's quite annoying.
I was working on a method which I called instead of the RenderMacroContent. The idea was that it should create the macro, render it and add the result to the output string. But I ran out of time, maybe someone want to continue the development, or explain how this should work
Cheers.
is working on a reply...