9 Replies Latest reply on May 28, 2008 7:37 AM by Newsgroup_User

    How to execute arbitrary CFML stored in a string variable?

    jgolub Level 1
      All-

      I have some arbitrary CFML stored in a string. (In practice, it is stored in a database and retrieved into a string variable.) Is there any way to execute it other than writing it to a file and using <cfmodule> to execute that file?

      Note that I found a "render" function in the BlueDragon product, which does what I am looking for, but I need it in CF itself.

      Thanks in advance for any help you can offer.

      -Josh
        • 1. Re: How to execute arbitrary CFML stored in a string variable?
          Dan Bracuk Level 5
          slightly different, write it to a file and use cfinclude to execute it.
          • 2. Re: How to execute arbitrary CFML stored in a string variable?
            jgolub Level 1
            quote:

            Originally posted by: Dan Bracuk
            slightly different, write it to a file and use cfinclude to execute it.


            True. Let me rephrase -- is there any way to execute it that doesn't involve writing it to disk first?

            -Josh
            • 3. Re: How to execute arbitrary CFML stored in a string   variable?
              Level 7
              One note of caution: 9 out of 10 times I have solved this problem, I
              have found it was a problem that did not need to be solved. There with
              a bit of rethinking of my system, I removed the need to execute
              arbitrary code.

              With that said; as well as writing to a file, you should be able to use
              a mix of evaluate() and de() [delay evaluate] to execute code in a string.
              • 4. Re: How to execute arbitrary CFML stored in a string   variable?
                jgolub Level 1
                quote:

                Originally posted by: Newsgroup User
                you should be able to use
                a mix of evaluate() and de() [delay evaluate] to execute code in a string.



                Let's assume that I really do need dynamic evaluation of CFML in this particular situation.

                That said, say that the dynamic CFML has been configured to be this:

                <cfloop index="i" from="1" to="10"><cfoutput>#i# </cfoutput></cfloop>

                I put it into a string and evaluate the string like this:

                <cfset s = '<cfloop index="i" from="1" to="10"><cfoutput>#de("i")# </cfoutput></cfloop>'>
                <cfoutput>#Evaluate( s )#</cfoutput>

                using the de() function to delay evaluation of the variable i. This produces the following error:

                quote:

                Invalid CFML construct found on line 1 at column 1.
                ColdFusion was looking at the following text:
                <
                The CFML compiler was processing:
                < marks the beginning of a ColdFusion tag.Did you mean LT or LTE?


                I am pretty sure that Evaluate() takes a Coldfusion expression and not CFML.

                Other ideas?

                -Josh
                • 5. Re: How to execute arbitrary CFML stored in a string variable?
                  Grizzly9279 Level 1
                  You are correct that Evaluate() will handle ColdFusion expressions, and not CFML.

                  However, keep in mind that you can invoke function calls (UDFs, CFC methods, etc) in a ColdFusion expression. So in-directly, you can dynamically invoke any CFML code you want within the context of an Evaluate() call, so long as the CFML you want to invoke is encapsulated in a UDF or CFC somewhere.

                  If you really do want to store CFML tags/code in a database and parse it on the fly, you're not going to have much luck I'm afraid. Your only option really will be to write it to a file and <cfinclude> it. Not pretty. If this really is your requirement, consider taking a step back and re-thinking this. There's probably a better way to approach this.
                  • 6. Re: How to execute arbitrary CFML stored in a string variable?
                    Level 7
                    I can understand the reluctance to jump through all the hoops of getting a
                    string, writing it to file, including it, removing the file; but that's
                    about the only option available as far as doing what you want to do.

                    Can I recommend you write a custom tag (UDF) which wraps all this up for
                    you, so you can just write it once and then slap it in your code as needs
                    must. This'll save some of the horror of having to be undertaking the task
                    in the first place ;-)

                    I'd perhaps write the file with a name that is the hash of the code, that
                    way I could check whether a file with that hash already exists, and simply
                    include it if it does. This saves the file-write, file-read, re-compile,
                    execute process that creating the files on the fly will have.


                    I'd like to add a "me too" to the positions put forward that I'd really
                    consider thinking twice about pulling code out of the DB. Can you not just
                    write it to file in the first place, and store a reference to the file in
                    the DB instead?

                    --
                    Adam
                    • 7. Re: How to execute arbitrary CFML stored in a string variable?
                      Dan Bracuk Level 5
                      quote:

                      Originally posted by: jgolub
                      quote:

                      Originally posted by: Dan Bracuk
                      slightly different, write it to a file and use cfinclude to execute it.


                      True. Let me rephrase -- is there any way to execute it that doesn't involve writing it to disk first?

                      -Josh

                      None that are as simple as writing it to a disk first. As Adam mentioned, you also delete the file right after you use it.

                      Just out of curiousity, what is your objection to this approach?
                      • 8. Re: How to execute arbitrary CFML stored in a string variable?
                        jgolub Level 1
                        quote:


                        None that are as simple as writing it to a disk first. As Adam mentioned, you also delete the file right after you use it.
                        Just out of curiousity, what is your objection to this approach?



                        I do not object to this approach, per se, especially as it seems to be my only option :). I was just surprised that a function like BlueDragon's "Render" had not made it into CF by now. In an ideal world, the execution of CFML would be agnostic regarding the persistence format (e.g. disk or database) of the code in question. Right now, it's biased toward disk-based persistence.

                        But, we all know about ideal worlds...

                        Thanks for all of your help.

                        -Josh
                        • 9. Re: How to execute arbitrary CFML stored in a string variable?
                          Level 7
                          > I was just surprised that a function like BlueDragon's "Render" had
                          > not made it into CF by now.

                          Well it only went into BD late last year, which was after the most recent
                          release of CF.

                          I don't think it's that much of a boon, functionality-wise. You can
                          emulate what it does in about 10min with a bit of a code.

                          1) create a unique file name;
                          2) write the string to file;
                          3) include the file;
                          4) remove the file if it makes sense not to keep it.

                          I imagine that's all render() is doing.

                          I don't see it as value-added functionality, to be honest.

                          --
                          Adam