On a page, I have a field of bodyText with a line of text and a contour form inserted.
When the above macro is rendered, the contour form part is not rendered correctly, the output is:
<p>A form will be here (text added by me in RTE)</p> <?UMBRACO_MACRO formguid="fae40097-a511-4366-94b9-d724a005284d" macroAlias="umbracoContour.RazorRenderForm" />
I guess I need todo something different in my razor macro for rendering the contents of bodyText but what?
If I just output @Model.bodyText it works fine but I need my macro to use a parameter.
The problem is that the Umbraco internal classes / methods required to render a macro are not called when just getting a field value. I personally created my own FieldRenderer for this but perhaps there is a built-in way to avoid such a workaround?
Well it is just a simple copy of the umbraco internals that are not public. You have to be careful regarding future version. No one knows what will change ;-)
/// <summary> /// Helper class to render the content of an umbraco HTML field. /// </summary> public class FieldRenderer { /// <summary> /// Renders the content of an umbraco docment type property and returns the result /// as a HTML string. /// </summary> /// <param name="alias">The alias of the property to render.</param> /// <param name="contentId">The ID of the content element containing the property.</param> /// <returns>The content of an umbraco document type property as HTML string.</returns> public HtmlString GetContent(string alias, int contentId) { if (string.IsNullOrEmpty(alias)) { throw new ArgumentNullException("alias"); }
var item = new Item { Field = alias, TextIfEmpty = string.Empty, LegacyAttributes = GetAttributeCollectionAdapter(alias), NodeId = contentId.ToString(CultureInfo.CurrentCulture) };
var containerPage = new FormlessPage(); containerPage.Controls.Add(item);
using (var output = new StringWriter(CultureInfo.CurrentCulture)) using (var htmlWriter = new HtmlTextWriter(output)) { ItemRenderer.Instance.Init(item); ItemRenderer.Instance.Load(item); ItemRenderer.Instance.Render(item, htmlWriter); return new HtmlString(output.ToString()); } }
/// <summary> /// Creates a new <see cref="AttributeCollectionAdapter"/> with the required /// attributes to render a field. /// </summary> /// <param name="field">The alias of the field to create the adapter for.</param> /// <returns>The created <see cref="AttributeCollectionAdapter"/> object.</returns> private static AttributeCollectionAdapter GetAttributeCollectionAdapter(string field) { var attributes = new Dictionary<string, string> { { "field", field }, { "recursive", "false" }, { "useifempty", string.Empty }, { "textifempty", string.Empty }, { "stripparagraph", "false" }, { "case", string.Empty }, { "inserttextbefore", string.Empty }, { "inserttextafter", string.Empty }, { "convertlinebreaks", "false" }, { "formatasdate", "false" }, { "formatasdatewithtime", "false" }, { "formatasdatewithtimeseparator", string.Empty } };
var attributesForItem = new AttributeCollectionAdapter( new AttributeCollection( new StateBag()));
foreach (var i in attributes) { attributesForItem.Add(i.Key, i.Value); }
return attributesForItem; } }
/// <summary> /// Represents a formless .aspx file to be able to render a control outside the current page context /// without verification of the server form. /// </summary> internal class FormlessPage : Page { /// <summary> /// Handles the server form verification. Stays empty to avoid the /// verification. /// </summary> /// <param name="control">The <see cref="Control"/> object to verify.</param> public override void VerifyRenderingInServerForm(Control control) { // Empty to avoid the verification } }
I tried to render macro content from the child page RTE using foreach and its not working. It works fine if I tried to load from the same page itself...
Please help me to figure out, why the macro is not loading from the child page RTE when using foreach loop in Umbraco MVC
I am listing all the child nodes RTE bodyText Content from the current page, and some of the child nodes RTE has macro in it. So I want to render those macros from the child nodes to my current page listing.
here is the structure of my contents
- Services - Service 1 - Service 2 (RTE with Macro placed) - Service 3
Rendering macro contents with razor
I have a macro which takes a parameter of a field to be displayed in razor:
On a page, I have a field of bodyText with a line of text and a contour form inserted.
When the above macro is rendered, the contour form part is not rendered correctly, the output is:
I guess I need todo something different in my razor macro for rendering the contents of bodyText but what?
If I just output @Model.bodyText it works fine but I need my macro to use a parameter.
Thanks,
Adam
The problem is that the Umbraco internal classes / methods required to render a macro are not called when just getting a field value. I personally created my own FieldRenderer for this but perhaps there is a built-in way to avoid such a workaround?
Thanks Andreas,
My feeling is there must be a built in way todo it as thats what DynamicNode is doing when I call @Model.bodyText.
How difficult was it to build your own FieldRenderer? are you able to share it?
Well it is just a simple copy of the umbraco internals that are not public. You have to be careful regarding future version. No one knows what will change ;-)
Awesome! thanks Andreas.
As you said, im a little nervous around changes to future versions so not sure im going to use this yet but thanks for your help :)
Hi Andreas,
I tried to render macro content from the child page RTE using foreach and its not working. It works fine if I tried to load from the same page itself...
Please help me to figure out, why the macro is not loading from the child page RTE when using foreach loop in Umbraco MVC
Hi, what exactly are you doing and which version of umbraco do you use?
Umbraco Version v6.1.2
I am listing all the child nodes RTE bodyText Content from the current page, and some of the child nodes RTE has macro in it. So I want to render those macros from the child nodes to my current page listing.
here is the structure of my contents
- Services
- Service 1
- Service 2 (RTE with Macro placed)
- Service 3
Sorry I'm not able to reproduce it, but I haven't upgrade to v6.1.2 yet.
is working on a reply...