Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Adam Jenkin 71 posts 226 karma points
    Mar 18, 2013 @ 11:02
    Adam Jenkin
    0

    Rendering macro contents with razor

    I have a macro which takes a parameter of a field to be displayed in razor:

    @inherits umbraco.MacroEngines.DynamicNodeContext
    @using umbraco.MacroEngines
    @if (
        Model.HasProperty(Parameter.fieldAlias)
        && Model.HasValue(Parameter.fieldAlias))
    {
        @Model.GetPropertyValue(Parameter.fieldAlias)
    }

    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.

    Thanks,

    Adam

  • Andreas Iseli 150 posts 427 karma points
    Mar 18, 2013 @ 11:30
    Andreas Iseli
    0

    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?

  • Adam Jenkin 71 posts 226 karma points
    Mar 18, 2013 @ 12:12
    Adam Jenkin
    0

    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?

  • Andreas Iseli 150 posts 427 karma points
    Mar 18, 2013 @ 16:47
    Andreas Iseli
    100

    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
    }
    }

     

  • Adam Jenkin 71 posts 226 karma points
    Mar 18, 2013 @ 17:44
    Adam Jenkin
    0

    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 :)

  • SM 19 posts 41 karma points
    Jul 21, 2013 @ 08:11
    SM
    0

    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

  • Andreas I. 12 posts 34 karma points
    Jul 21, 2013 @ 09:46
    Andreas I.
    0

    Hi, what exactly are you doing and which version of umbraco do you use?

  • SM 19 posts 41 karma points
    Jul 21, 2013 @ 10:23
    SM
    0

    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

     

  • Andreas Iseli 150 posts 427 karma points
    Jul 22, 2013 @ 20:46
    Andreas Iseli
    0

    Sorry I'm not able to reproduce it, but I haven't upgrade to v6.1.2 yet.

Please Sign in or register to post replies

Write your reply to:

Draft