Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving variables inside a Coldfusion string

Tags:

coldfusion

My client has a database table of email bodies that get sent at certain times to customers. The text for the emails contains ColdFusion expressions like Dear #firstName# and so on. These emails are HTML - they also contain all sorts of HTML mark-up. What I'd like to do is read that text from the database into a string and then have ColdFusion Evaluate() that string to resolve the variables. When I do that, Evaluate() throws an exception because it doesn't like the HTML markup in there (I also tried filtering the string through HTMLEditFormat() as an intermediate step for grins but it didn't like the entities in there).

My predecessor solved this problem by writing the email text out to a file and then cfincluding that. It works. It's seems really hacky though. Is there a more elegant way to handle this using something like Evaluate that I'm not seeing?

like image 304
DaveBurns Avatar asked Dec 02 '22 06:12

DaveBurns


1 Answers

What other languages often do that seems to work very well is just have some kind of token within your template that can be easily replaced by a regular expression. So you might have a template like:

Dear {{name}}, Thanks for trying {{product_name}}.  Etc...

And then you can simply:

<cfset str = ReplaceNoCase(str, "{{name}}", name, "ALL") />

And when you want to get fancier you could just write a method to wrap this:

<cffunction name="fillInTemplate" access="public" returntype="string" output="false">
    <cfargument name="map" type="struct" required="true" />
    <cfargument name="template" type="string" required="true" />

    <cfset var str = arguments.template />
    <cfset var k = "" />

    <cfloop list="#StructKeyList(arguments.map)#" index="k">
        <cfset str = ReplaceNoCase(str, "{{#k#}}", arguments.map[k], "ALL") />
    </cfloop>

    <cfreturn str />
</cffunction>

And use it like so:

<cfset map = { name : "John", product : "SpecialWidget" } />
<cfset filledInTemplate = fillInTemplate(map, someTemplate) />
like image 146
Bialecki Avatar answered Jan 05 '23 23:01

Bialecki