Skip to main content
November 18, 2009
Answered

Complicated variables/RegEx question

  • November 18, 2009
  • 2 replies
  • 615 views

Hello~

I have a form that allows users to submit a block of text, with any variables they want to use surrounded by ~, like ~firstName~. The entire block of text, including the variables, is being outputted to the page. I have a RegEx function that replaces all of the ~ with #, but I still can't get the variables to show up as their values, rather than #firstName# on the page.

Here is my RegEx expression:

<cfset content = reReplace(content,'[~]','##','ALL') />

This gets me this when I output the whole variable to the page:

<p>Dear #firstName# #lastName#:</p>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras nec accumsan ante. Mauris placerat ullamcorper lorem mollis fringilla. Morbi non urna ipsum, et tempus urna. Aliquam pellentesque sapien ut orci lacinia vitae faucibus enim ullamcorper.</p>

<p>Sincerely,<br />#clientName#</p>

<p><a href="#webSite#">Click here</a> to return to our Web site.</p>

I have been playing around with reReplace to add single quotes around non-variable text, and ampersands, etc., to make it all work, but I haven't had much luck! Any suggestions would be really helpful. Thanks!

KC

    This topic has been closed for replies.
    Correct answer JR__Bob__Dobbs-qSBHQ2

    You might try something like this.

    <cfset myData=StructNew() />
    <cfset myData.firstName="Bob" />
    <cfset myData.lastName="Dobbs" />

    <cfset content="Hello ~firstName~ ~lastName~" />

    <!--- loop through myData struct and do find and replace --->
    <cfloop collection="#myData#" item="key">
       
        <!--- does ~key~ exist in content?  If so, replace it with value --->
        <cfset content=ReplaceNoCase(content, "~#key#~", myData["#key#"]) />

    </cfloop>

    <cfoutput>#HtmlEditFormat(content)#</cfoutput>


    Whatever method you use for you project I recommend that you cheek the input against a whitelist of the variables that your end users have access to.  This will avoid given users access to variables that might contain sensitive information, such as data source names.

    2 replies

    JR__Bob__Dobbs-qSBHQ2Correct answer
    Inspiring
    November 19, 2009

    You might try something like this.

    <cfset myData=StructNew() />
    <cfset myData.firstName="Bob" />
    <cfset myData.lastName="Dobbs" />

    <cfset content="Hello ~firstName~ ~lastName~" />

    <!--- loop through myData struct and do find and replace --->
    <cfloop collection="#myData#" item="key">
       
        <!--- does ~key~ exist in content?  If so, replace it with value --->
        <cfset content=ReplaceNoCase(content, "~#key#~", myData["#key#"]) />

    </cfloop>

    <cfoutput>#HtmlEditFormat(content)#</cfoutput>


    Whatever method you use for you project I recommend that you cheek the input against a whitelist of the variables that your end users have access to.  This will avoid given users access to variables that might contain sensitive information, such as data source names.

    November 19, 2009

    This works perfectly, thanks! And, I will definitely be checking values against a master list


    ilssac
    Inspiring
    November 18, 2009

    Because, unless you really twist it's arm painfully behind it's back, ColdFusion will only process a line of code once. As will most other languages.

    But you want to process this line of code twice, first to make the variables in the text then to render the variable into their values.

    The two most common solutions developers employs to solve this double rendering issue is:

    1) Write the line of code with the variables to a temporary file and then <cfinclude ...> that file back into the original.

    2) Use the evaluate() function and|or de() 'delay evaluate' functions.

    I can never remember which combonation of evaluate()|de() would allow this because once most developers actually figure this out, they usually quickly figure out how problemetic the whole concept is and move on to something less dangerious then allowing users write their on code on the system.

    Ok, here is something that may do what you want:

    <cfset test = "The Red ##something## Fox">
    <cfset something = "New Stuff">
       
    <cfoutput>#evaluate(de(test))#</cfoutput>