Loading

Briefly about custom macro fields

In this post I want to provide a bit more details regarding how to add custom macro fields to existing object types.

In Kentico documentation we have good explanation how to create and use custom macro field for the existing object type. But documentation examples often use hardcoded username value to retrieve, for example, user information. In real life things can be more complicated.

Let's consider the scenario. We have Kentico Order object type. And we created custom module and classes to manage customer's credit cards information (for example it can be last four digits for credit card number, credit card expiration date, etc.). Custom object type to store credit card information is called CreditCard. Also additional column was added to the object type Order to store credit card ID just to know which credit card customer used to pay for order. Now we need to display credit card information in order invoice or sent emails to customer with order details and credit card information used for payment. So what is the best way to insert this information into invoice? I think the answer is to use custom macros.

As credit card object is tied to order by ID so credit card object information can be field of order object. The main issue was to identify context of specific order object and get credit card ID stored within the currently used order object (for example, when we edit order information and view order invoice). The code sample below demonstrate how to register custom field for credit card.

[assembly: RegisterExtension(typeof(CustomMacroFields), typeof(OrderInfo))]

public class CustomMacroFields : MacroFieldContainer
{
    protected override void RegisterFields()
    {
        base.RegisterFields();
        
        RegisterField(new MacroField("CreditCard", (context) =>
        {
            //context.Resolver.SourceObject is used to retrieve data of currently used object
            ShoppingCartInfo si = context.Resolver.SourceObject as ShoppingCartInfo;
            if (si != null && si.Order != null)
            {
                return CreditCardDataInfoProvider.GetCreditCardDataInfo(si.Order.GetIntegerValue("OrderCreditCardID", 0));
            }

            return context.DefaultValue;
        }));
    }
}
 

So as you can see the example is quite simple, but the main focus is how to get appropriate object data from context parameter of type EvaluationContext. Now all properties of Credit card object can be easily retrieved as macro fields.