Key Points about Macros in Umbraco 8 - FadiZahhar/umbraco8showandtell GitHub Wiki

Key Points about Macros in Umbraco 8

  • Purpose: Macros are designed to enable editors and developers to insert custom code, such as user controls, partial views, or even embedded HTML, into content areas and templates.

  • Where You Use Macros:

    • Rich Text Editor (RTE): Editors can add macros to pages via the content editing interface.
    • Templates/Views: Developers can place macros inside Razor views or master templates for reusable functionality.
  • Types of Macros:

    • Partial View Macro: The most common, using a Razor Partial View (.cshtml file).
    • XSLT Macro: (Legacy, not commonly used in modern Umbraco sites).
    • User Control Macro: (Legacy, for .ascx user controls; rarely used now).
  • Examples of Macro Use Cases:

    • Embedding a contact form in a page.
    • Displaying a list of latest news or events.
    • Embedding a YouTube video or custom scripts.
    • Showing dynamic widgets or functionality (sliders, carousels, etc.).

How Macros Work

  • Creation: Macros are defined in the Umbraco Backoffice under Settings > Macros.
  • Parameters: You can define parameters for a macro (e.g., a "Number of items" field for a news list), allowing editors to customize its output when inserting it.
  • Rendering: When a macro is inserted in content or a template, Umbraco processes it and renders the output of the associated view or control at runtime.

Example (Partial View Macro):

Suppose you create a partial view called LatestNews.cshtml under Views/Partials/. You then create a macro in the Backoffice, link it to LatestNews.cshtml, and editors can insert it anywhere they want—either in a Rich Text Editor or you can call it in a template using:

@Umbraco.RenderMacro("LatestNews")

Or, when editing content, the editor can select Insert Macro in the RTE and pick "LatestNews".


In summary: A macro in Umbraco 8 is a reusable, configurable "drop-in" component—making it easy to add dynamic, custom, or interactive features throughout your website, whether by editors or developers.

1. Prepare Your Content Structure

Assuming you have a "News Article" document type with published news items, perhaps under a "News" parent node in the content tree.


2. Create the Razor Partial View

  • Go to Settings > Partial Views in the Umbraco Backoffice.
  • Click Create and name it, e.g., NewsListMacro.cshtml.

Paste the following Razor code as a starting point:

@inherits Umbraco.Web.Mvc.UmbracoViewPage

@{
    // Optional: Set parameters for parent node ID or max items
    int parentId = 1234; // Replace with your News parent node ID or fetch via parameter
    int maxItems = 5;    // Default number of news to show, can be parameterized

    // Get all news articles under the parent node
    var newsItems = Umbraco.Content(parentId)
        .Children()
        .Where(x => x.IsVisible())
        .OrderByDescending(x => x.CreateDate)
        .Take(maxItems);
}

<div class="news-list">
    <h2>Latest News</h2>
    <ul>
        @foreach(var item in newsItems)
        {
            <li>
                <a href="@item.Url">@item.Name</a>
                <span class="news-date">@item.CreateDate.ToString("yyyy-MM-dd")</span>
                <p>@item.Value("summary")</p> <!-- Replace 'summary' with your summary/intro property alias -->
            </li>
        }
    </ul>
</div>

3. Parameterize Your Macro (Optional but Recommended)

To make it dynamic, you can define macro parameters in Umbraco and access them via Model.MacroParameters in your view.

Example with Parameters:

@inherits Umbraco.Web.Mvc.UmbracoViewPage

@{
    int parentId = Model.MacroParameters["parentId"] != null 
        ? int.Parse(Model.MacroParameters["parentId"].ToString()) 
        : 1234; // Fallback to a default node ID
    int maxItems = Model.MacroParameters["maxItems"] != null 
        ? int.Parse(Model.MacroParameters["maxItems"].ToString()) 
        : 5;
    var newsItems = Umbraco.Content(parentId)
        .Children()
        .Where(x => x.IsVisible())
        .OrderByDescending(x => x.CreateDate)
        .Take(maxItems);
}
<!-- Same rendering as above -->

4. Create the Macro in Umbraco Backoffice

  • Go to Settings > Macros.
  • Click Create.
  • Name it (e.g., "News List Macro").
  • Select "Use in editor" if you want editors to insert it into RTE fields.
  • Under Scripting File, select your partial view (NewsListMacro.cshtml).
  • Add parameters (like parentId and maxItems) if you want editors to configure them.

5. Insert the Macro

  • In a Rich Text Editor: Editors can insert the macro and, if you added parameters, specify values.

  • In a template/view: Use

    @Umbraco.RenderMacro("News List Macro", new { parentId = 1234, maxItems = 5 })

    replacing parameter values as needed.


6. Styling

Add custom CSS as desired to style .news-list in your theme.


Summary Flow

  1. Create partial view (Razor).
  2. Register macro in Backoffice, link to partial.
  3. (Optional) Add parameters for flexibility.
  4. Insert macro where you need dynamic news listings.

1. Create the Partial View

Create a new Partial View in Settings > Partial Views named: NewsListMacro.cshtml

Paste the following code:

@inherits Umbraco.Web.Mvc.UmbracoViewPage

@*
    News List Macro
    Parameters:
        parentId  : (int) The node ID of the parent "News" folder (required)
        maxItems  : (int) The maximum number of news articles to display (default: 5)
*@

@{
    // Read macro parameters with fallback defaults
    int parentId = 0;
    int maxItems = 5;

    if (Model.MacroParameters["parentId"] != null)
    {
        int.TryParse(Model.MacroParameters["parentId"].ToString(), out parentId);
    }

    if (Model.MacroParameters["maxItems"] != null)
    {
        int.TryParse(Model.MacroParameters["maxItems"].ToString(), out maxItems);
    }

    var newsItems = Enumerable.Empty<Umbraco.Web.PublishedModels.NewsArticle>();

    if (parentId > 0)
    {
        var parent = Umbraco.Content(parentId);
        if (parent != null)
        {
            // Replace 'newsArticle' with your Document Type alias if different
            newsItems = parent
                .Children()
                .Where(x => x.IsVisible() && x.ContentType.Alias == "newsArticle")
                .OrderByDescending(x => x.CreateDate)
                .Take(maxItems)
                .Cast<Umbraco.Web.PublishedModels.NewsArticle>();
        }
    }
}

<div class="news-list">
    <h2>Latest News</h2>
    @if (newsItems.Any())
    {
        <ul>
            @foreach (var item in newsItems)
            {
                <li>
                    <a href="@item.Url">@item.Name</a>
                    <span class="news-date">@item.CreateDate.ToString("yyyy-MM-dd")</span>
                    @* Replace "summary" with your property alias if needed *@
                    @if (!string.IsNullOrWhiteSpace(item.Value<string>("summary")))
                    {
                        <p>@item.Value("summary")</p>
                    }
                </li>
            }
        </ul>
    }
    else
    {
        <p>No news found.</p>
    }
</div>

2. Create the Macro in Backoffice

  • Go to Settings > Macros

  • Create a new macro: “News List Macro”

  • Set the Scripting File to NewsListMacro.cshtml

  • Add two parameters:

    • parentId (Type: Number, Description: The node ID of your News parent)
    • maxItems (Type: Number, Description: Number of news articles to display)

3. Usage

  • In RTE: Editors can insert the macro and set the parameters.

  • In Templates/Views:

    @Umbraco.RenderMacro("News List Macro", new { parentId = 1234, maxItems = 5 })

    Replace 1234 with your News section’s node ID.


4. Tips

  • Replace "newsArticle" in x.ContentType.Alias == "newsArticle" with your real news item document type alias if different.
  • Replace "summary" with your summary/intro property alias as used in your document type.
⚠️ **GitHub.com Fallback** ⚠️