This is a blog entry that will/may have a few parts. A user just sent this in, and it seems like a mystery, so I'll try to keep my readers updated as things progress. Jennifer asks:
I am trying to suppress whitespace in a script that I inherited that generates a .ps report from database info. I have tried everything (I do not have access to CF Administrator, but I've tried all the in code solutions) and it still won't go away! I have put cfsilent everywhere I possibly can, enabled cfoutput only, reset my content, cfprocessingdirective... the whole shebang. However, whitespace is still everywhere and is turning a 1497k file into a 1696k file AFTER everything I have implemented! Is there anyway you can help or wisdom that you can impart?
Well, first off, let's go over the list of places you may have forgotten to trim whitespace. I think you got them all, and the cfcontent with a reset should have done it anyway, but it won't hurt to review.
If your site uses an Application.cfm file, you want to ensure no whitespace is generated. You can do this with a cfsilent around the whole file, which I find to be a bit icky, or use the cfsetting tag, both on the very top (above comments!) and on the very bottom.
If you use Application.cfc, you have a few more places to check. First add output="false" to your top cfcomponent tag. Then look into all your onXStart methods (onApplicationStart, onSessionStart, onRequestStart), and ensure output is false there as well.
Lastly, look at the template that generates the PS report. Does it call any custom tags? Call any CFCs? If so, any of those calls can generate whitespace. You can check each of those files, or surround them with cfsilent.
Now - you mentioned that you were serving your file up and you had preceded with a cfcontent/reset. You should know that that will clear any whitespace before your final output. It won't remove whitespace inside your output.
So look at your output. Do you have a lot of whitespace between elements?
If any of my readers have other ideas, chime in, and hopefully Jennifer will post an update.
Archived Comments
I'm half-kidding, but have you tried wrapping the entirety fo the content with a <cfsavecontent /> and then using a regular expression to replace all whitespace streaks with a single space? And then using the resulting variable to generate your file?
David's solution is simply the best one. I use that for years!
Make a custom tag with this:
<cfif not thisTag.hasEndTag>
<cfabort showError="You must close the tag">
</cfif>
<cfif thisTag.executionMode is "End">
<cfset thisTag.generatedContent = REReplace(thisTag.generatedContent, "[[:cntrl:]]{2,}",chr(0), "ALL")>
</cfif>
Then, just insert the code you want between the start and end tags for the custom tag:
if the file is named "whitespace.cfm" then:
<cf_whitespace>
...content...
</cf_whitespace>
All of your content will have whitespace removed, including line breaks.
I use this for my CFM, CSS and JS output.
It's fast and efective and, as I stated before, I've been using it for years in production servers.
Rewrite to use java's StringBuffer and build the string up that way then output. Will give more control of the whitespace.
Don't forget to wrap cfparams with cfsilent if you have a long list of them as they can also generate whitespace.
This is something I found a couple years ago that uses the pageContext buffer. It doesn't remove all whitespace but reduces the extra whitespace leaving the code still readable by viewing source.
<cfscript>
pageContent = getPageContext().getOut().getString().trim();
getPageContext().getOut().clearBuffer();
pageContent = REreplace(pageContent, ">\s+<", ">" & chr(13) & chr(10) & "<", "all");//strip whitespace between tags
pageContent = REreplace(pageContent, "[\n\r\f]+", chr(13) & chr(10), "all");//condense excessive new lines into one new line
pageContent = REreplace(pageContent, "\t+", " ", "all");//condense excessive tabs into a single space
writeoutput(pageContent.trim());
getPageContext().getOut().flush();
</cfscript>
Fernanado you nailed my problem - many thanks, this will come in useful all over the place.
Thanks for this. Very helpful. One more thing, though. I created the whitespace.cfm file but made it all one line. It was creating its own whitespaces; once I pulled it all together, worked like a charm.