How do I process CF code contained in a string (eg. text field in DB)?
Unfortunately CFMX 7 does not have a built-in feature to accomplish this task. You can how ever pull this off with a few manual steps: 1) save the code to a temp file 2) <cfinclude> the temp file 3) Delete the temp file.
Be advised, this is not a recommend best practice! Why add dynamic file read writes if you can avoid it- this is a bad move for performance. Also consider the possible security hole of someone inserting malicious code into your processing engine. In other words, use this recipe at your own risk.
<cfquery
datasource="foo"
name="mQuery">
SELECT code
FROM myCode
WHERE id = 1
</cfquery>
<cfset tempFile = getTempFile("C:\CFusionMX7\wwwroot\test", "code")>
<!--- write file out --->
<cffile action="write"
file= "#tempFile#"
output="#mQuery.code#">
<!--- include file --->
<cfinclude template="#GetFileFromPath(tempFile)#">
<!--- delete file --->
<cffile action="delete"
file="#tempFile#">
<p>This is after</p>
This question was written by Jeremy Petersen.
It was last updated on May 31, 2006 at 2:31:30 PM EDT.
CFML Referenced
Categories
Comments
Comment made by Brian Kotek on May 31, 2006 at 3:17 PM
I would consider it a very bad idea, but you can just wrap the code you pull from the database in evalute().
Comment made by Raymond Camden on May 31, 2006 at 3:20 PM
I agree that it is a bad idea, but many people ask, so I wanted it published. Evaluate will ONLY work for functions. It won't evaluate tags.
Comment made by Patrick McElhaney on May 31, 2006 at 3:36 PM
"Why add dynamic file read writes if you can avoid it - this is a bad move for performance."
But if you must, create a RAM disk.
Comment made by Scott Krebs on May 31, 2006 at 5:44 PM
If there were multiple rows in the myCode table containing differing bits of code, it would seem a good idea to either 1) cflock the code in the server scope so that nearly simultaneous requests for different code ids wouldn't step on each other or (better solution for performance) 2) name the temp file with a unique value (maybe UUID?) so that multiple simultaneous requests have their own space to do their thing. Does that make sense, or am I missing something?
Comment made by Raymond Camden on May 31, 2006 at 5:49 PM
I believe the getTempFile part handles the unique name aspect by itself.
Comment made by Scott Krebs on May 31, 2006 at 5:58 PM
Ahh, yes, I forgot. The second parameter "code" being passed to the getTempFile is only used as a prefix and not the entire file name. Been a while since I used that one and I forgot about the prefix part. Thank you again for leading me down the path to enlightenment, Master :)
Comment made by Raymond Camden on May 31, 2006 at 6:02 PM
I may write a cookbook entry just on that portion.
Comment made by Vince Bonfanti on May 31, 2006 at 7:52 PM
BlueDragon has the Render() method, so you can replace all of the code after the CFQUERY with:
<cfoutput>#Render( mQuery.code )#</cfoutput>
This, of course, solves the performance issue.
I'm not sure what the big issue is with security--simply never dynamically render any user-entered code. The main use for the Render() method that I've seen is to render code snippets from a database in a CMS or CMS-like system.
Comment made by Raymond Camden on May 31, 2006 at 9:11 PM
Vince:
Security - I agree it is obvious, but I think most of the users here may not know it. I wanted to be super careful before recommending something that could be dangerous.
BlueDragon - It is a FAQ for this site that all code assumes "Latest CFMX". This isn't to be anti-BD, but just to make things simpler. I didn't want to have to worry about code for varions versions, platforms, etc. (I hope no offense is taken. :)