Replace the placeholders in a text with the values of an object
Tags: dotnet
Published: 2022-09-08 13:59:17

Platforms: .NET

When working on multi-language websites or apps, or we have to send personalized confirmation emails, we often store the text as a resource in resource files or a database.

This way of working is great to let translators translate the text and the developer build the website/app.

The text can hold different placeholders and the following Nuget Package (CodeHelper.Core.PlaceHolder) makes it easy to replace the placeholders with the value of the given object.

##PreRequisites

- [CodeHelper.Core.PlaceHolder](https://www.nuget.org/packages/CodeHelper.Core.PlaceHolder)


##Example Text
Let's use an order confirmation email

```
Hi {CUSTOMERNAME},
<br />
Your order #{ORDERID} is confirmed and will be shipped out of our warehouse on {SHIPMENTDATE}
<br />
<b>Total Details</b><br />
Number of items: {NBOFITEMS}<br />
Total amount: {TOTALAMOUNT}
<br /><br />
Items:
{LISTOFITEMS}
```


##The OrderInfo Class
Let's start with the class, containing the order info
The only thing we need to do is

- Add using CodHelper.Core.PlaceHolder
- Add a Placeholder Attribute to the class properly

A Placeholder Attribute requires the **placeholder value (string)** used in the text and optional the **format (string)**     

```
using CodeHelper.Core.PlaceHolder;

public class OrderInfo 
     {        
        [Placeholder("{ORDERID}")] 
        public Int64 ID { get; set; }

        public Int64 CustomerID { get; set; }

        [Placeholder("{CUSTOMERNAME}")] 
        public string CustomerName { get; set; } ="";

        [Placeholder("{SHIPMENTDATE}", "MMM dd, yyyy")]
        public DateTime DateShipmentDate { get; set; }

        public DateTime DateOrder{ get; set; }

        [Placeholder("{NBOFITEMS}", "#,##0")]
        public int NbShippedItems { get { return ShippedItemDescriptions.Count; } }

        [Placeholder("{TOTALAMOUNT}", "#,###,##0.00")]
        public double TotalAmount { get; set; }

        [Placeholder("{LISTOFITEMS}")]
        public List<string> ShippedItemDescriptions { get; set; } = new();
               
        public OrderInfo() { }         
    }
```


##The Code
The replace string extension has the following parameters
- _order : object with the values
- false: Indicates if the text is an URL, if true, the empty parameters will be omitted, in our example it is not an URL, so false.
- FormatTypes.HTML: Text, HTML or Markdown (default: FormatTypes.TEXT)

```
using CodeHelper.Core.PlaceHolder;

//-- get the order info
OrderInfo _order = new() { ID = 99876, DateShipmentDate = DateTime.Today.AddDays(1) 
                                , TotalAmount = 1234.50
                                , CustomerID=333
                                , CustomerName ="CodeHelper"
                                , DateOrder= DateTime.Today };
    _order.ShippedItemDescriptions.Add("Product Description #1");
    _order.ShippedItemDescriptions.Add("Product Description # 2");
    _order.ShippedItemDescriptions.Add("Product Description # 3");

//-- Get The Confirmation Email Text
string emailBody = Resources.Translations.EmailConfirmOrder

//-- Replace the placeholder inside the text with the values of 
//-- the _order object
emailBody = emailBody.Replace(_order, false, FormatTypes.HTML);
```


##Result
The email is ready to send...
```
Hi CodeHelper,<br />
Your order #99876 is confirmed and will be shipped out of our warehouse on Sept 09, 2022
<br />
<b>Total Details</b><br />
Number of items: 3<br />
Total amount: 1,234.50
<br /><br />
Items:
<ul>
    <li>Product Description #1</li>
    <li>Product Description # 2</li>
    <li>Product Description # 3</li>
</ul>
```


##Advantages
When the marketing team wants to change the confirmation email, or add fields or translate to more languages, the code keep working.

In case of adding placeholder, simply add the attribute to the field