Elastic Email from a Bean using a template

ColdBox, ColdFusion

This is just like my query post except it's from a bean. For those that aren't familiar with a bean, I use Coldbox as my MVC framework of choice which can then populate the bean. I have a toStruct function in my base Bean that I use. I posted it here also. So the concept is from to Bean to struct and then loop over it to dynamically populate a template. So this combined with my previous function I've turned my entire email model into two dynamic functions sending pretty emails on the fly.

    public string function sendElasticEmailFromBean(myBean)
        {
            LOCAL.httpService = new http();
            LOCAL.httpService.setMethod("post");
            LOCAL.httpService.setCharset("utf-8");
            LOCAL.httpService.setUrl(THIS.SENDURL);
            LOCAL.httpService.addParam(type="formfield",name="username",value=THIS.USERNAME);
            LOCAL.httpService.addParam(type="formfield",name="api_key",value=THIS.API_KEY);
            LOCAL.httpService.addParam(type="formfield",name="from",value=THIS.FROM);
            LOCAL.httpService.addParam(type="formfield",name="from_name",value=THIS.FROM_NAME);
            LOCAL.httpService.addParam(type="formfield",name="to",value=ARGUMENTS.myBean.getTo());
            LOCAL.httpService.addParam(type="formfield",name="subject",value=ARGUMENTS.myBean.getSubject());
            if (ARGUMENTS.myBean.getTemplate() neq '')
            {
                LOCAL.httpService.addParam(type="formfield",name="template",value=ARGUMENTS.myBean.getTemplate());
                LOCAL.httpService.addParam(type="formfield",name="merge_body",value=ARGUMENTS.myBean.getBody());
            }    
            else
                LOCAL.httpService.addParam(type="formfield",name="body_html",value=ARGUMENTS.myBean.getBody());    
            if (ARGUMENTS.myBean.getMergeName() neq '')
                LOCAL.httpService.addParam(type="formfield",name="data_source",value=ARGUMENTS.myBean.getMergeName());
            
            LOCAL.columns=StructKeyArray(ARGUMENTS.myBean.toStruct());
            for (local.i=1; LOCAL.i LTE arraylen(LOCAL.columns); LOCAL.i=LOCAL.i+1)
            {
                LOCAL.temp=evaluate("ARGUMENTS.myBean.get"& LOCAL.columns[i]&"()");
                if( isDefined('LOCAL.temp'))
                    LOCAL.httpService.addParam(type="formfield",name="merge_#LOCAL.columns[i]#",value="#LOCAL.temp#");
            }
            LOCAL.result = LOCAL.httpService.send().getPrefix();
            return LOCAL.result.filecontent;
        }

    public struct function toStruct()
    {
        LOCAL.rtn = structNew();
        for(LOCAL.x=1; LOCAL.x lte ArrayLen(getMetaData(THIS).properties); LOCAL.x = LOCAL.x + 1)
        {
            if(isDefined(getMetaData(THIS).properties[LOCAL.x].name)) value = evaluate(getMetaData(THIS).properties[x].name);
            else LOCAL.value = "";
            
            structInsert(LOCAL.rtn, getMetaData(THIS).properties[LOCAL.x].name, value);
        }
        return LOCAL.rtn;
    }


Elastic Email from Query using a template

ColdFusion

Here is a function I wrote to send an email via Elastic Email. It accepts a query and a template. It matches any fields from the query and populates the template. You will need to user all uppercase when placing variables in your template because in ColdFusion query column names are all uppercase, for example {FIRSTNAME} works in your template and {firstname} wouldn't work. You can also over ride the template subject if needed.

    public any function sendElasticEmailFromQuery(myQuery,template,subject="")
        {
            LOCAL.httpService = new http();
            LOCAL.httpService.setMethod("post");
            LOCAL.httpService.setCharset("utf-8");
            LOCAL.httpService.setUrl(THIS.SENDURL);
            LOCAL.httpService.addParam(type="formfield",name="username",value=THIS.FROM);
                LOCAL.httpService.addParam(type="formfield",name="api_key",value=THIS.API_KEY);
            LOCAL.httpService.addParam(type="formfield",name="from",value=THIS.FROM);
            LOCAL.httpService.addParam(type="formfield",name="from_name",value=THIS.FROM_NAME);
            if(arguments.subject neq "")
                LOCAL.httpService.addParam(type="formfield",name="subject",value=ARGUMENTS.subject);
            LOCAL.httpService.addParam(type="formfield",name="to",value=ARGUMENTS.myquery.email);
            LOCAL.httpService.addParam(type="formfield",name="template",value=ARGUMENTS.template);
            LOCAL.httpService.addParam(type="formfield",name="merge_YEAR",value=datepart('YYYY',now()));
            LOCAL.columns=ARGUMENTS.myQuery.GetColumnNames();
            for (local.i=1; LOCAL.i LTE arraylen(LOCAL.columns); LOCAL.i=LOCAL.i+1)
            {
                LOCAL.temp=evaluate("ARGUMENTS.myQuery."& LOCAL.columns[i]);
                LOCAL.httpService.addParam(type="formfield",name="merge_#LOCAL.columns[i]#",value="#LOCAL.temp#");
            }
            LOCAL.result = LOCAL.httpService.send().getPrefix();
        }    

 


trying to use the page in an non-page page

ContentBox
I have the following in my layout:
#cb.quickView(view='_pagesidebar')#

In the _pagesidebar view I have

cb.widget("SearchForm")


When I try to search, I'm getting:
"This probably means you are trying to use the page in an non-page page! Redundant huh?"

Why can't I do this? This is included the in the default layout that comes with contentbox? If I can't do this shouldn't it be removed?

Making pretty URLs when using widgets and ContentBox

ContentBox
If I do /tournaments/tournament-page/tournamentid/9000
without a route it's telling me that the page doesn't exist. I assume this is because it's like you said looking for a slug named 9000 rather than populating the RC. I've added a route in the contentbox-ui module config
pattern="/:pageSlug/:pageSlug/tournamentid/:tournamentid-numeric"

the route is matched and the tournamentid is populated in the rc but I'm still getting

The page you requested: tournaments/tournament-page/tournamentid/9000
 
the currently routed url is tournaments/tournament-page/tournamentid/9000/

not tournaments/tournament-page/, I'm wondering if this is causing the issue because
prc.page = pageService.findBySlug( incomingURL, showUnpublished ); in page.index is never populating the page my best guess is because it's not matching.


ContentBox Recent Pages Widget

ContentBox

The recent pages widget uses the pageService.findPublishedPages function. This function accepts a showInMenu arguement. This will come in handy if you have pages in your contentbox that you don't want to show in your recent pages widget. For example pages that contain other widgets that need to have variables passed to them. If you leave these in your recentpages output users can click on them and of course the widget will return an error like:

Error executing viewlet: widgets.tournament(). The variable: tournamentid is undefined in the request collection (private=false)

Unless of course you test for this in your widget and handle it. I find it easier to only show recent pages for stuff that in the menu. Since I usually use this widget in my sidebar view of my layout I've just modified the widget to make this the default.

I'm writing this post so I can remember what I've done since I'm going to have to fix it after each upgrade.

Happy new year.