Page 1 of 1

Possible to add custom class to nVelocity processing?

Posted: Mon Jul 27, 2009 6:11 pm
by AbleMods
Let's say I've built a custom class in the code-behind of a page

Code: Select all

Public Class MyFormFields
   Public FirstName as String
   Public LastName as String
   Public EmailAddress as String
End Class
So now I populate an instance of the class

Code: Select all

Dim _MyFields as New MyFormFields
_MyFields.FirstName = "Joe"
_MyFields.LastName = "Payne"
_MyFields.EmailAddress = "foo @ foo.com"
Now let's say I am manually pulling in a email template and want to add some variables to the template like this...

Code: Select all

            Dim _Template As EmailTemplate = EmailTemplateDataSource.Load(AlwaysConvert.ToInt(TemplateId))

            ' Now with the email template validated, we can proceed with template construction
            _Template.Parameters.Add("store", Token.Instance.Store)
            _Template.Parameters.Add("user", Token.Instance.User)
            _Template.Parameters.Add("product", _Product)
The question is...can I add my custom class defined in the code-behind as a parameter to the template like this...

Code: Select all

            _Template.Parameters.Add("formfields", _MyFields)
My thinking is I would be able to access the nVelocity equivalents using $formfields.LastName, $formfields.FirstName etc. That way I can integrate my custom form data straight into the standard email templates engine for AC7.

Can it be done? My initial testing isn't working.....

Re: Possible to add custom class to nVelocity processing?

Posted: Tue Jul 28, 2009 4:51 am
by mazhar
Yes, it should work. For example if you look at following thread
viewtopic.php?f=42&t=11740
Here I passed C# exception object as parameter to Email template.

Re: Possible to add custom class to nVelocity processing?

Posted: Tue Jul 28, 2009 12:50 pm
by AbleMods
Hmmm - must be doing something wrong then :?

Re: Possible to add custom class to nVelocity processing?

Posted: Tue Jul 28, 2009 7:07 pm
by AbleMods
In your example(s), you're passing data types that are globally available.

My class is only visible in the code-behind. I wonder if that's why my example doesn't work......

Re: Possible to add custom class to nVelocity processing?

Posted: Wed Jul 29, 2009 1:52 am
by mazhar
It could be, better place that class in App_Code and then try again.

Re: Possible to add custom class to nVelocity processing?

Posted: Wed Jul 29, 2009 6:36 am
by AbleMods
Last night I did some playing around. It doesn't seem to support custom classes but I don't understand why.

I tried defining the class in the code-behind - no workie. Understandable since the visibility scope of that class would be limited to the code-behind page itself.

I tried defining it in an existing public class I had written in ~/App_Code - no workie. I verified the class visibility was global by specifically removing the "Imports AbleModsClass;" at the top of the code-behind file.

I expected the global class to work since it's visibility was now application-wide. It surprised me that it didn't work.

So I ended up using a fake product class instance to pass the data and it worked flawlessly. There must be something in the template class that's blocking the inheritence of custom classes into the nVelocity script processing engine.

/shrug

Re: Possible to add custom class to nVelocity processing?

Posted: Wed Jul 29, 2009 8:53 am
by nickc
I replaced the trigger for notification emails by adding some code in OPC:

Code: Select all

            Hashtable ht = new Hashtable();
            ht.Add("customer", order.User);
            ht.Add("order", order);
            ht.Add("payments", payments);
            ht.Add("store", store);
            ht.Add("site", SiteInformation.Current);

            // we always notify customer
            CommerceHelper.SendSiteMail("Customer Order Notification", ht);
and a custom class in App_Code:

Code: Select all

        public static void SendSiteMail(string templateName, Hashtable parameters)
        {
        ...
                // hashtable contains objects for template replacements:
                // store, customer(user), basket, order, shipments, vendor, etc.
                // see template source for details (velocity references for "objectname" are ${objectname})
                NVelocityEngine nVengine = new NVelocityEngine();

                // load up the template
                EmailTemplate template = Token.Instance.Store.EmailTemplates.Find(delegate(EmailTemplate t) { return t.Name == templateName; });
                if (template != null)
                {
                ...
                    nVengine.Init();
                    template.ToAddress = nVengine.Process(parameters, template.ToAddress);
                    template.FromAddress = nVengine.Process(parameters, template.FromAddress);
                    template.CCList = nVengine.Process(parameters, template.CCList);
                    template.BCCList = nVengine.Process(parameters, template.BCCList);
                    template.Subject = nVengine.Process(parameters, template.Subject);
                    template.Body = nVengine.Process(parameters, template.Body);
                    template.Send();
                    ...
This more manual approach allows the use object references in the address lines, custom placeholders (e.g. customer,vendor,manufacturer,administrator, ...) etc. Doubt that this is the "right" way but has been working fine for me.