2

If I write

<section id="banner" class="#getBannerClass()#">

I end up with

<section id="banner" class=" classname">

But if I write

<cfset test = getBannerClass() />
<section id="banner" class="#test#">

I end up with

<section id="banner" class="classname">

Do anyone know why or how to prevent it from happening? To me both of those codes should run the exact same.

I ran this code in cflive and it produced the result the same so I don't think it's anything with "my code" messing with stuff. It seems just how CF works, but it seems incorrect.

<cffunction name="testfun">
    <cfreturn 'myClass' />
</cffunction>
<cfoutput>
    <div class="#testFun()#">#testFun()#</div>
    <cfset classOutput = testFun() />
    <div class="#classOutput#">#classOutput#</div>
</cfoutput>
Leeish
  • 5,203
  • 2
  • 17
  • 45

2 Answers2

4
<cffunction name="testfun" output="false">
    <cfreturn 'myClass' />
</cffunction>
Henry
  • 32,689
  • 19
  • 120
  • 221
  • Ok. I am gracious for your response. Is there a reason why or is it a "bug" because either way I don't think there should be a space. Especially wrapping it with a trim. Is it outputting the whitespace that is actually "inside" the function but if so, why doesn't trim remove it. – Leeish May 27 '16 at 21:58
  • @Leeish something similar was asked on SO before; I couldn't find a real explanation. http://stackoverflow.com/questions/2791813/why-is-coldfusion-adding-whitespace-when-i-call-a-function-in-cfoutput – TRose May 27 '16 at 22:00
  • Thanks I guess I didn't search using the right terms to find that one. – Leeish May 27 '16 at 22:02
  • 2
    @Leeish `` can be used to output html, and white spaces in HTML usually does not matter. Therefore if you don't have `output=false` CF will output whatever in your function that are not cf tags, and output to the output buffer / caller. You're lucky if you're only getting 1 whitespace. :) If your function is a method in a cfc, make sure you set `output=false` in the `` as well. – Henry May 27 '16 at 22:12
  • 1
    Old school CF style, you would output HTML from within a function. I can only assume that someone thought it would be expected to add a space after you output HTML, therefore we need an attribute to say we're not rendering HTML. (Not _returning_ HTML, _rendering_ HTML.) – Adrian J. Moreno May 27 '16 at 22:15
  • Any thoughts on why `trim(function())` doesn't trim it? Is it because white space that is an issue is not a string "per say" and trim is supposed to act on a string that would be the returned value from the function. – Leeish May 27 '16 at 22:37
  • @Leeish It is not a bug - it is how ColdFusion is meant to work. The whitespace is put directly into the output buffer when it is processed within the function scope - it is not being appended to the return value of the function and then passed back to the calling scope and processed there. So calling `trim()` on the return value will not do anything as the whitespace is not part of the return value. See my answer for a more detailed example. – MT0 May 27 '16 at 23:47
  • @MT0 - Yes, but there is still something a little hinky about CF's implementation. I would have expected "output" to be all or nothing. When enabled, output everything "as is". Instead, CF collapses the leading white space, *unless* it is followed by one or more characters. *Then* it outputs the whole shebang, white space characters and all. Something not quite right about that... – Leigh May 28 '16 at 02:53
  • @Leigh Go to the ColdFusion administration panel and turn off the "Enable Whitespace Management" setting - it should then output all the whitespace. – MT0 May 28 '16 at 08:59
  • @MT0 - Duh, forgot about Whitespace Management! – Leigh May 29 '16 at 16:11
  • I get it, is there a way at the application level to set functions to `output=false` by default or do I have to do them all? – Leeish May 31 '16 at 14:51
  • @Leeish you'll have to do them all, or start using cfscript where possible. :) – Henry May 31 '16 at 23:09
3

You can turn output off in the function:

<cffunction name="testfun" output="false">
   <cfreturn 'myClass'/>
</cffunction>

or turn the output off with cfsilent:

<cfsilent>
<cffunction name="testfun">
   <cfreturn 'myClass'/>
</cffunction>
</cfsilent>

or by eliminating the whitespace from the function:

<cffunction name="testfun"
  ><cfreturn 'myClass'
/></cffunction>

or converting the function to cfscript:

<cfscript>
  function testfun(){
    return 'myclass';
  }
</cfscript>

As for what is happening:

The HTML you are generating is being output to a buffer - when ColdFusion processes anything that is not in a cf tag then it will be output directly to this buffer unless you tell ColdFusion to suppress this output.

So if you do:

<cffunction name="testfun">Append to Buffer<cfreturn 'Return Value' /></cffunction>

Then each call to testfun() will append Append to Buffer to the output buffer (while you are in the function's scope) and then the cfreturn will be processed and the function will return and any remaining code in the function scope (after the return statement) will be ignored. The scope will then return to the calling scope which can then do something with the returned value (note: the text output to the buffer is not part of the return value from the function).

The output would be:

<div class="Append to BufferReturn Value">Append to BufferReturn Value</div>
Append to Buffer
<div class="Return Value">Return Value</div>

So the call to the function in cfset does output the text not in a cf tag within the function but it will output it where the function is called and not where the return value is being output.

MT0
  • 143,790
  • 11
  • 59
  • 117