In many systems, it is nice to be able to have pre-written messages that can be injected with customized content at runtime.

This tutorial will explain how to write a basic content injection system.

We'll just build a query to hold some sample system messages that we need to customize at runtime. We'll add some extra fields as placeholders for the values we want to inject into the message.

qMessage = querynew("messageid,messagetitle,message","integer,varchar,varchar");
//first sample row queryaddrow(qMessage);
querysetcell(qMessage,"messagetitle","Registration Complete");
querysetcell(qMessage,"message","Thankyou [customername], registration is complete");
//second sample row queryaddrow(qMessage);
querysetcell(qMessage,"messagetitle","New Ticket");
querysetcell(qMessage,"message","Dear [customername], Ticket number [ticketnbr] has been created.");

You'll notice that there are several key words in brackets in the message. (i.e. [customername], [ticketnbr]) - These are the placeholders that will be populated at runtime.

The code below will query the messages we just created and display a select box to allow you to choose a message:

<cfquery name="getMessages" dbtype="query">
   select messageid, messagetitle,message
   from qMessage
   order by messagetitle

<form method="get">
<select name="messageid">
   <cfoutput query="getMessages">
   <option value="#getMessages.messageID#">#getMessages.messagetitle#</option>
<input type="submit" value="go" />

In order to prefill the message, we create a struct with keys that match the ones that are expected in the message.

These values would typically be set from a query result or some other logic - in this case we just create it with some dummy data.

<cfset stInject = structnew()>
<cfset stInject.customername = "Nathan Miller">
<cfset stInject.ticketnbr = createuuid()>

Once the form is submitted, we get the selected message using query:

<cfquery name="getSelectedMessage" dbtype="query">
select message
from qMessage
where messageid = #url.messageid#
order by messagetitle

The original message: <cfoutput>#getSelectedMessage.message#</cfoutput>
The guts of the system is the following UDF. This function takes a struct of data in the first argument, and tries to match the struct keys to the placeholders in the second argument. It returns the fully injected text as a string.

<cffunction name="injectContent" returntype="string" output="false">
   <cfargument name="stContent" type="struct" hint="container of data that will inject into the raw text">
   <cfargument name="rawtext" type="string" hint="text with placeholders that will be injected">   
   <cfset var lstFields = structkeylist(arguments.stContent)>
   <cfset var placeholder = "">
   <cfset var i = 0>
   <cfset var rtn = arguments.rawtext>
   <!--- there must be a matching struct key in arguments.stContent that matches a placeholder name -
   the place holder will be filled with the stContent key value --->
   <cfloop list="#lstFields#" index="placeholder">
      <cfset rtn = replacenocase(rtn,"[#placeholder#]",arguments.stContent[placeholder],"all")>
   <cfreturn rtn />

To inject the values into the message, just call the injectContent function:

<cfset newMessage = injectContent(stInject,getSelectedMessage.message)>
The new message: <cfoutput>#newMessage#</cfoutput>

Any unused keys will simply be ignored. For example, if you select the 'Reg Complete' message, you can still create a new ticket number and pass it to the function, but since there is no [ticketnbr] place holder in the message, stInject.ticketnbr will be ignored.

You can download a fully functional demo here

About This Tutorial
Author: Nathan Miller
Skill Level: Intermediate 
Platforms Tested: CFMX7
Total Views: 90,453
Submission Date: March 28, 2007
Last Update Date: June 05, 2009
All Tutorials By This Autor: 11
Discuss This Tutorial
  • I was doing something similar to content injection, but a different way. After reviewing this tutorial and looking at some other options, I think this will be the most efficient. Thanks for sharing this!


Website Designed and Developed by Pablo Varando.