DEV Community

Cover image for Step-by-Step Guide: Adding Mail Merge to Blazor Rich Text Editor
Zahra Sandra Nasaka for Syncfusion, Inc.

Posted on • Originally published at syncfusion.com on

Step-by-Step Guide: Adding Mail Merge to Blazor Rich Text Editor

TL;DR: Learn to add mail merge functionality to the Blazor Rich Text Editor! We’ll set up a Blazor app, configure the editor, and add merge fields using a custom toolbar and Mention component. Finally, we’ll process data with Scriban for seamless personalized content creation.

Syncfusion Blazor Rich Text Editor is a feature-rich WYSIWYG HTML editor and WYSIWYG Markdown editor. It is used to create blogs, forum posts, notes sections, support tickets (incidents), comment sections, messaging apps, and more. The control provides an efficient user interface with mobile support for a better editing experience. It has a variety of tools to edit and format rich content and returns valid HTML markup or Markdown (MD) content. It allows users to insert images, links, tables, and lists with modular architectures.

In this blog, we’ll see how to easily add a mail merge feature to the Blazor Rich Text Editor. This feature is handy for sending personalized messages to many people at once. With a simple setup, users can make their content creation and distribution much smoother, improving their communication process. Keep reading to learn how to make the most of the Blazor Rich Text Editor with mail merge!

Prerequisites

We are going to demonstrate the process using a Blazor server-side app. So, the following prerequisites are needed:

Let’s get started!

Step 1: Create a Blazor server-side app

First, create a Blazor server-side app and configure the Syncfusion Blazor services.

Step 2: Add the Insert Merge Field menu button in the Blazor Rich Text Editor toolbar

Let’s add a custom menu button labeled Insert Merge Field to the toolbar of the Blazor Rich Text Editor. For that, we should configure the Blazor Menu component to include available insert merge field options. This menu button enables users to select and insert merge fields into their text. This can be achieved by binding the ItemSelected event of the Menu component and calling the Rich Text Editor’s ExecuteCommandAsync method with the command name InsertHTML.

Refer to the following code example.

@page "/"
@using Syncfusion.Blazor.RichTextEditor
@using Syncfusion.Blazor.Navigations

<SfRichTextEditor ID="mailMerge" @ref="rteObj" @bind-Value="TextEditorValue">
 <RichTextEditorToolbarSettings Items="@Tools" Type="ToolbarType.MultiRow">
  <RichTextEditorCustomToolbarItems>
   <RichTextEditorCustomToolbarItem Name="InsertMergeField">
    <Template>
     <SfMenu TValue="MenuItem">
      <MenuEvents TValue="MenuItem" ItemSelected="ItemSelected"></MenuEvents>
      <MenuItems>
       <MenuItem Text="Insert Merge Field">
        <MenuItems>
         <MenuItem Text="invoice.company_details">
          <MenuItems>
           <MenuItem Text="invoice.company_details.name"></MenuItem>
           <MenuItem Text="invoice.company_details.address"></MenuItem>
           <MenuItem Text="invoice.company_details.phone"></MenuItem>
          </MenuItems>
         </MenuItem>
         <MenuItem Text="invoice.customer_details">
          <MenuItems>
           <MenuItem Text="invoice.customer_details.name"></MenuItem>
           <MenuItem Text="invoice.customer_details.address"></MenuItem>
           <MenuItem Text="invoice.customer_details.email"></MenuItem>
          </MenuItems>
         </MenuItem>
         <MenuItem Text="invoice.invoice_number"></MenuItem>
        </MenuItems>
       </MenuItem>
      </MenuItems>
     </SfMenu>

    </Template>
   </RichTextEditorCustomToolbarItem>
  </RichTextEditorCustomToolbarItems>
 </RichTextEditorToolbarSettings>
</SfRichTextEditor>

@code {
    SfRichTextEditor? rteObj;
    public string TextEditorValue { get; set; } = @"<p>Dear {{invoice.company_details.name}},</p>

                <p>Thank you for your email and for the exclusive offer! I appreciate the gesture and look forward to using the discount on my next purchase.</p>

                <p>I've been a satisfied customer of {{invoice.company_details.name}} for 5 years, and I must say, your products/services have always exceeded my expectations. Keep up the excellent work!</p>

                <p>If I have any questions or need further assistance, I'll be sure to reach out to your customer service team.</p>

                <p>
                    Thanks again and best regards,<br>
                    {{invoice.customer_details.name}} <br />
                    {{invoice.customer_details.address}} <br />
                    {{invoice.customer_details.email}}
                </p>";

    public class PersonData
    {
        public string? Name { get; set; }

        public string? Status { get; set; }
    }
    List<PersonData> EmailData = new List<PersonData> {
      new PersonData() { Name="invoice.company_details.name", Status = "active", },
      new PersonData() { Name="invoice.company_details.address", Status = "away" },
      new PersonData() { Name="invoice.company_details.phone", Status = "busy" },
      new PersonData() { Name="invoice.customer_details.name", Status = "active"},
      new PersonData() { Name="invoice.customer_details.address", Status = "busy" },
      new PersonData() { Name="invoice.customer_details.email", Status = "active" },
      new PersonData() { Name="invoice.issue_date", Status = "away"},
      new PersonData() { Name="invoice.due_date", Status = "busy" }
    };

    private List<ToolbarItemModel> Tools = new List<ToolbarItemModel>()
    {
        new ToolbarItemModel() { Command = ToolbarCommand.Bold },
        new ToolbarItemModel() { Command = ToolbarCommand.Italic },
        new ToolbarItemModel() { Command = ToolbarCommand.Underline },
        new ToolbarItemModel() { Command = ToolbarCommand.StrikeThrough },
        new ToolbarItemModel() { Command = ToolbarCommand.SuperScript },
        new ToolbarItemModel() { Command = ToolbarCommand.SubScript },
        new ToolbarItemModel() { Command = ToolbarCommand.Separator },
        new ToolbarItemModel() { Command = ToolbarCommand.FontName },
        new ToolbarItemModel() { Command = ToolbarCommand.FontSize },
        new ToolbarItemModel() { Command = ToolbarCommand.FontColor },
        new ToolbarItemModel() { Command = ToolbarCommand.BackgroundColor },
        new ToolbarItemModel() { Command = ToolbarCommand.Separator },
        new ToolbarItemModel() { Command = ToolbarCommand.LowerCase },
        new ToolbarItemModel() { Command = ToolbarCommand.UpperCase },
        new ToolbarItemModel() { Command = ToolbarCommand.Separator },
        new ToolbarItemModel() { Command = ToolbarCommand.Image },
        new ToolbarItemModel() { Command = ToolbarCommand.CreateLink },
        new ToolbarItemModel() { Command = ToolbarCommand.CreateTable },
        new ToolbarItemModel() { Command = ToolbarCommand.Separator },
        new ToolbarItemModel() { Command = ToolbarCommand.Formats },
        new ToolbarItemModel() { Command = ToolbarCommand.Alignments },
        new ToolbarItemModel() { Command = ToolbarCommand.Separator },
        new ToolbarItemModel() { Command = ToolbarCommand.NumberFormatList },
        new ToolbarItemModel() { Command = ToolbarCommand.BulletFormatList },
         new ToolbarItemModel() { Command = ToolbarCommand.SourceCode },
        new ToolbarItemModel() { Name = "InsertMergeField", TooltipText = "Insert Merge Field" },
        new ToolbarItemModel() { Command = ToolbarCommand.Undo },
        new ToolbarItemModel() { Command = ToolbarCommand.Redo }
    };

    public async Task ItemSelected(MenuEventArgs<MenuItem> args)
    {
        if (args.Item.Items == null)
        {
            await this.rteObj.ExecuteCommandAsync(CommandName.InsertHTML, "<span contenteditable='false' class='e-mention-chip'>{{" + args.Item.Text + "}}</span>", new ExecuteCommandOption() { Undo = true });
        }
    }

}
Enter fullscreen mode Exit fullscreen mode

Refer to the following image.

Adding Insert Merge Field menu button in the Blazor Rich Text Editor toolbar


Adding Insert Merge Field menu button in the Blazor Rich Text Editor toolbar

Step 3: Integrate the Blazor Mention component to insert the merge field

First, we need to install the Syncfusion.Blazor.DropDowns package. Now, add the Blazor Mentioncomponent with the required insert merge field data. Then, integrate it with the Rich Text Editor by setting the Target property of the Mention component as the Rich Text Editor’s content editable element id [mailMerge_rte-editable]. Also, configure the MentionChar property as “ { “. When pressing the mention character in the editor, it will appear, allowing users to select and display it in the editor.

Refer to the following code example.

@page "/"
@using Syncfusion.Blazor.RichTextEditor
@using Syncfusion.Blazor.DropDowns
@using Syncfusion.Blazor.Navigations

<SfRichTextEditor ID="mailMerge" @ref="rteObj" @bind-Value="TextEditorValue">
 <RichTextEditorToolbarSettings Items="@Tools" Type="ToolbarType.MultiRow">
  <RichTextEditorCustomToolbarItems>
   <RichTextEditorCustomToolbarItem Name="InsertMergeField">
                …
                …
                …
   </RichTextEditorCustomToolbarItem>
  </RichTextEditorCustomToolbarItems>
 </RichTextEditorToolbarSettings>

</SfRichTextEditor>

<SfMention TItem="PersonData" MentionChar="@mentionChar" Target="#mailMerge .e-rte-content .e-content" DataSource="@EmailData" SuggestionCount=8 AllowSpaces="true" PopupHeight="200px" PopupWidth="250px">

<DisplayTemplate>
   {{@((context as PersonData).Name)}};
</DisplayTemplate>
<ChildContent>
 <MentionFieldSettings Text="Name"></MentionFieldSettings>
</ChildContent>
</SfMention>

@code {
    …
    …
    …

    public char mentionChar = '{';
    public class PersonData
    {
        public string? Name { get; set; }

        public string? Status { get; set; }
    }
    List<PersonData> EmailData = new List<PersonData> {
      new PersonData() { Name="invoice.company_details.name", Status = "active", },
      new PersonData() { Name="invoice.company_details.address", Status = "away" },
      new PersonData() { Name="invoice.company_details.phone", Status = "busy" },
      new PersonData() { Name="invoice.customer_details.name", Status = "active"},
      new PersonData() { Name="invoice.customer_details.address", Status = "busy" },
      new PersonData() { Name="invoice.customer_details.email", Status = "active" },
      new PersonData() { Name="invoice.issue_date", Status = "away"},
      new PersonData() { Name="invoice.due_date", Status = "busy" }
   };
   …
   …
   …

}
Enter fullscreen mode Exit fullscreen mode

Refer to the following image.

Integrating the Blazor Mention component with the Blazor Rich Text Editor


Integrating the Blazor Mention component with the Blazor Rich Text Editor

Step 4: Add the Finish and Merge button to the Rich Text Editor toolbar and merge the placeholder text

Let’s add a custom button labeled Finish & Merge to the Blazor Rich Text Editor’s toolbar. Then, define the JSON data in the InvoiceData.json file for customer and company details to merge the placeholder text.

Using the Scriban, we can render the mail merge placeholder text and assign it to the Rich Text Editor’s Value property.

Refer to the following code example.

@page "/"
@using Syncfusion.Blazor.RichTextEditor
@using Syncfusion.Blazor.DropDowns
@using Syncfusion.Blazor.Navigations
@using RichTextEditorMailMerge.Model
@using Newtonsoft.Json
@using Scriban

<SfRichTextEditor ID="mailMerge" @ref="rteObj" @bind-Value="TextEditorValue">
 <RichTextEditorToolbarSettings Items="@Tools" Type="ToolbarType.MultiRow">
  <RichTextEditorCustomToolbarItems>
   <RichTextEditorCustomToolbarItem Name="InsertMergeField">
                …
                …
                …  
   </RichTextEditorCustomToolbarItem>
   <RichTextEditorCustomToolbarItem Name="FinishMerge">
    <Template>
     <button class="e-btn e-tbar-btn" @onclick="ClickHandler">
      <span style="font-size:14px">Finish & Merge</span>
     </button>
    </Template>
   </RichTextEditorCustomToolbarItem>
  </RichTextEditorCustomToolbarItems>
 </RichTextEditorToolbarSettings>

</SfRichTextEditor>
…
…
…

@code {
    …
    …
    …
    private List<ToolbarItemModel> Tools = new List<ToolbarItemModel>()
    {
        …
        …
        …
        new ToolbarItemModel() { Name = "InsertMergeField", TooltipText = "Insert Merge Field" },
        new ToolbarItemModel() { Name = "FinishMerge", TooltipText = "Finish & Merge" },
        new ToolbarItemModel() { Command = ToolbarCommand.Undo },
        new ToolbarItemModel() { Command = ToolbarCommand.Redo }
    };
    public void ClickHandler()
    {
        Invoice ? invoice = JsonConvert.DeserializeObject<Invoice>(File.ReadAllText(".\\Data\\InvoiceData.json"));
        string invoiceHTML = TextEditorValue;
        Template template = Template.Parse(invoiceHTML);
        var templateData = new { invoice };
        //Fill the template with real invoice data
        TextEditorValue = template.Render(templateData);
    }
    …
    …
    …
}
Enter fullscreen mode Exit fullscreen mode

RichTextEditorMailMerge.Model

using Newtonsoft.Json;

namespace RichTextEditorMailMerge.Model
{
    public class Invoice
    {
        public string? InvoiceNumber { get; set; }
        public string? IssueDate { get; set; }
        public string? DueDate { get; set; }

        public UserDetails? CompanyDetails { get; set; }
        public UserDetails? CustomerDetails { get; set; }

    }
    public class UserDetails
    {
        public string? Name { get; set; }
        public string? Address { get; set; }
        public string? Email { get; set; }
        public string? Phone { get; set; }
    }
}
Enter fullscreen mode Exit fullscreen mode

Refer to the following image.

Adding Finish & Merge button to the Blazor Rich Text Editor toolbar


Adding Finish & Merge button to the Blazor Rich Text Editor toolbar

GitHub reference

For more details, refer to the Mail merge in Blazor Rich Text Editor GitHub demo.

Conclusion

Thanks for reading! In this blog, we have seen how to integrate mail merge functionality into the Blazor Rich Text Editor. Try out the steps in this blog and provide your feedback!

If you are new to Syncfusion, try our control features by downloading a 30-day free trial.

You can also contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!

Related Blogs

Top comments (0)

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay