cffile creating blank lines when storing a table - coldfusion

I've got a cfsavecontent tag that saves a table. Later I use cffile to write the saved content to a file. When I look at that file, I see that there many blank lines inserted after <td> tags in the table; and few blank lines inserted after </tr> tags. (Although it doesn't do that where the code says <tr><td> </td></tr> all on one line.)
Presently I have a file which contains two of those tables. The tables are generated in a loop, and the output file is created with cffile append. This file has 915 lines in it of which maybe 30 are non-blank. All my subsequent code works correctly, but this is just test data. In the real world I could have 1000 or more tables, and I am concerned about the file size.
The code:
<cfset head1 = 'from = "moxware" '>
<cfset head2 = 'to = "#hrep.PersonEmail#" '>
<cfset head3 = 'replyto = "#replyto#" '>
<cfset head4 = 'subject = "#subject#" '>
<cfset head5 = 'type = "html" '>
<cfsavecontent variable = "abc">
<cfoutput>
#head1#
#head2#
#head3#
#head4#
#head5# >
#xyz#
</cfoutput>
</cfsavecontent>
<cffile action = "append"
file = "/var/www/reports/moxrep/#reportout#.cfm"
output = "<cfmail"
mode = "777" >
<cffile action = "append"
file = "/var/www/reports/moxrep/#reportout#.cfm"
output = "#abc#"
mode = "777">
<cffile action = "append"
file = "/var/www/reports/moxrep/#reportout#.cfm"
output = "</cfmail>"
mode = "777" >
Re the xyz, I am reading it in from a file:
<cffile action = "read"
file = "/var/www/reports/moxrep/#reportname#.cfm"
variable = "xyz">
and the file looks like this:
<link rel="stylesheet" href="sample.css">
<link rel="stylesheet" type = "text/css" href ="betty.css"/>
<p style="margin-left:40px"><span style="font-size:14px"><span style="font- family:georgia,serif">Dear Customer,</span></span></p>
We were so pleased that you have signed up for one of our programs. Apparently you live in the city of {{1. Additionally we observe that your were referred to us by {{2. Below please find a listing of what you signed up for.</span></span></p>
<p style="margin-left:40px"><span style="font-size:14px"><span style="font- family:georgia,serif">{{r</span></span></p>
<p style="margin-left:40px"><span style="font-size:14px"><span style="font-family:georgia,serif">Sincerely Yours,</span></span></p>
<p style="margin-left:40px"><span style="font-size:14px"><span style="font-family:georgia,serif">John Jones<br />
President<br />
XYZ Corporation</span></span></p>
The file was created by a code generator, not me, so it's a bit cumbersome. Later in the code I replace everything starting with {{ ; in particular {{r gets replaced with a table, and that is where the additional space is coming from.
The append itself is not inserting any extra lines.
Does anyone know what is causing these extra blank lines in the file; and how to get rid of them?

Betty, typically you need to do this carefully if you want to avoid whitespace. In particular the use of cfoutput with a query will generate lines. So this code:
<table>
<cfoutput query="myquery">
<tr><td>#col1#</td><td>#col2#</td></tr>
</cfoutput>
</table>
will produce extra lines... but if you do this:
<cfsetting enablecfoutputonly="yes">
<cfoutput><table></cfoutput>
<cfloop query="myquery"><cfoutput><tr><td>#col1#</td><td>#col2#</td></tr></cfoutput></cfloop>
<cfoutput></table></cfoutput>
You would carefully control exactly what is allowed to be appended to the buffer. enableoutputonly does exactly what it says... it does not allow anything to "go to the buffer" unless it is enclosed in cfoutputs.
Hope this helps. As cameron says you should paste code for questions like this. That's where the answer will typically reside.
(you might also need to experiment with the "addnewline" attribute of cffile - depending on whether your problem is a line at the END of your file).
To answer your question regarding adding cfsetting... in your case you are writing CF code to a file that is then executed later (which by the way is not a great idea usually :). So in your first Append statement:
<cffile action = "append"
file = "/var/www/reports/moxrep/#reportout#.cfm"
output = "<cfmail"
mode = "777" >
Change the "output" to be:
<cffile action = "append"
file = "/var/www/reports/moxrep/#reportout#.cfm"
output = "<cfsetting enablecfoutputonly=""yes""/> <cfmail"
mode = "777" >
But Betty - you will still need to remove the line breaks from your cfsavecontent (if that's where your whitespace is coming from) because they actually ARE inside of a cfoutput. Also, your code that creates the table you are inserting might be at fault - and it is not listed here.
Finally, since this is cfmail take a look at this post regarding line breaks that may or may not have some bearing - but at least gives you one more piece of information :)
http://www.coldfusionmuse.com/index.cfm/2006/4/12/cfmail.linebreak

You may consider using cfprocessingdirective around your cfsavecontent. There is a setting in CF administrator that universally either compresses or retains unnecessary whitespace, "Enable Whitespace Management" - http://help.adobe.com/en_US/ColdFusion/9.0/Admin/WSc3ff6d0ea77859461172e0811cbf3638e6-7ffc.html . Using the suppressWhiteSpace attribute of cfprocessingdirective, you can override this setting for a particular page or part of a page. So in your case:
<cfprocessingdirective suppressWhiteSpace="true">
<cfsavecontent variable="myvar">....
...
...
</cfsavecontent>
</cfprocessingdirective>
may help. Likewise, to ensure the retention of whitespace when building text emails, you'd use suppressWhiteSpace="false".
Cheers,

Related

Creating XLS file Using ColdFusion

I am trying to create a spreadsheet (.XLS file) using Adobe ColdFusion - 8.
The code that creates a spreadsheet is:
<cfsetting enablecfoutputonly="Yes">
<cfset date_from = "#URL.date_from#">
<cfset date_to = "#URL.date_to#">
<cfset query_id="#URL.queryID#">
<cfquery name="GetEmps" datasource="cfdocexamples">
<!--- My SQL Queries Goes Here--->
</cfquery>
<cfcontent type="application/msexcel">
<cfheader name="Content-Disposition" value="filename=Employees.xls">
<cfoutput>
<table cols="4">
<cfloop query="getData">
<tr>
<td>#uid#</td>
<td>#week#</td>
<td>#book_count#</td>
</tr>
</cfloop>
</table>
</cfoutput>
Whenever I run the page, an XLS sheet is created, but I cannot find any data. The size of the created XLS file is 0.
Please Note: The Query is correct(Since when I print the output as html, I can see the table without any error/warning).
** After reading comments: UPD**:
I had updated my code and only included important code snippet now.
UPD 2:
Whenever I commented the line <cfsetting enablecfoutputonly="Yes"> , xls file is created with expected data. However, when I opened the generated file, a dialogue appears:
Please note the spreadsheet generated is perfect. Only thing that is bothering me is the above warning.
Also Note: whenever I tried to open the spreadsheet in google-docs as a preview, it says, the file could not be opened due to corrupted format.
However, I am able to open it perfectly in an MS-Excel.
Even changing content type to : <cfcontent type="application/vnd.msexcel"> , I got the same warning.
While I cannot speak exactly how to implement this, I know the developers within my organization worked around it with the Apache POI. It seemed to do the trick for them. It does have to be completed with Java through Coldfusion. Here is an example of it.

cf10 unable to add text to HTML Head

I am getting the following error on a page we are loading:
coldfusion.runtime.CfErrorWrapper
Unable to add text to HTML HEAD tag.
[empty string]
caused by
Template
Unable to add text to HTML HEAD tag.
ColdFusion was unable to add the text you specified to the output stream. This is probably because you have already used a CFFLUSH tag in your template or buffered output is turned off.
I've done a sweep of all the files that are included in our application and cannot find anything that uses CFFlush.
output is set to 'no' on all cfcs and components. I also tried adding cfsetting showdebugoutput = no in a file. That didn't help.
I turned request debugging on in cfadmin and that didn't help.
The HTML Head works fine in other parts of our app, it just seems to be on this one page.
The only thing really different about this page is that it is a particularly long page.
If it's a particularly long page, then CF may be flushing the buffer on its own. If you check in the CFAdmin, on the settings page, there is a setting for Maximum Output Buffer size. I believe the default is 1024 KB. If your page is over 1 meg of content, then CF may flush the buffer before your <cfhtmlhead /> tag runs. Try increasing the buffer size, or changing the placement of the <cfhtmlhead /> tag to see if that corrects the issue.
I've run into the same problem recently but the behavior wasn't predictable. I believe that Dan Short's answer is correct. I created some test pages to see if I could reproduce the problem. Each time TestTemplate.cfm is included, CFHTMLHEAD writes a simple JavaScript alert to the head tag. Once the buffer is reached, and the page is automatically flushed, any subsequent CFHTMLHEAD tag use will result in an error, specifically, the error in the original post. As Dan indicates, you can work your way around this issue by changing the maximum output buffer size.
file: index.cfm
<html>
<head><title>Test Page</title></head>
<body>
<cfset SampleScript = "<script src='sample.js'></script>">
cfset Count = 0>
<cfinclude template="TestTemplate.cfm">
<cfinclude template="TestTemplate.cfm">
<cfinclude template="TestTemplate.cfm">
</body>
</html>
file TestTemplate.cfm
<cfhtmlhead text="#SampleScript#">
<cfset Count++>
<cfoutput>
<h1>Count #Count#</h1>
</cfoutput>
<cfoutput>
<cfloop from="1" to="100000" index="i">
<cfscript>
j = randRange(i, 1000000);
k = randRange(i, 1000000);
l = j * k;
writeOutput(l);
</cfscript>
</cfloop>
</cfoutput>
file sample.js
alert('Boo!');
server.log showed another error that I was submitting too many fields with a POST request. I had to increase this limit on the Settings page.
To fix this, login to Coldfusion Admin, go to Memory Variables, and uncheck 'Disable updating Coldfusion internal cookies using Coldfusion tags/functions.' Save your settings and restart your website.

css not working in cffile write

I have a report which is enclosed in a cfsavecontent tag.
<cfsavecontent variable = "testcust">
When I use
<cfoutput> #testcust# </cfoutput>
the report renders correctly. When I use cffile to save it to disk I lose the css formatting:
<cffile action = "write"
file = "/var/www/reports/testcust.cfm"
output = "#testcust#">
I can run testcust.cfm and it produces the report. All in-line styling is preserved. But formatting from the style sheet is not there. Does anyone know how to fix this?
You need to escape the html special characters. e.g < for < and > for >
So replace them before writing to file.

is there a way to add some spacing to cfmail type=text emails in Coldfusion when using variables only?

I'm a little in awe on how my first Cfmails are looking.
Problem is, I'm using variables for both text and content and I would still like to have some sort of spacing.
For example, if I have:
<cfprocessingdirective suppresswhitespace="No">
<cfmail
TO="#Local.User.email#"
FROM="..."
SERVER="..."
USERNAME="..."
PASSWORD="..."
WRAPTEXT="80"
SUBJECT="#tx_automailer_register_subject# - #Local.User.Comp#">
#tx_automailer_default_hello#
#tx_automailer_register_info#
#tx_automailer_register_iln#: #Local.User.iln#
#tx_firma#: #Local.User.firma#
#tx_ansprechpartner#: #Local.User.ansprechpartner#
#tx_adresse#: #Local.User.adresse#
#tx_plz#: #Local.User.plz#
#tx_ort#: #Local.User.ort#
...
The only place this looks nice is my cfc :-) In the mail itself everything is going bazooka.
Question:
Is there a way to space this? I have also tried to space according to length of variables, but this also does not really do any good and I'm not really keen on doing math for this...
Thanks for help!
The only option may be to post process the content. Build up the pretty content in a cfsavecontent, then run through cleanup function.
<cfprocessingdirective suppresswhitespace="No">
<cfsavecontent variable="message">
#tx_automailer_default_hello#
#tx_automailer_register_info#
#tx_automailer_register_iln#: #Local.User.iln#
#tx_firma#: #Local.User.firma#
#tx_ansprechpartner#: #Local.User.ansprechpartner#
#tx_adresse#: #Local.User.adresse#
#tx_plz#: #Local.User.plz#
#tx_ort#: #Local.User.ort#
</cfsavecontent>
<cfmail
TO="#Local.User.email#"
FROM="..."
SERVER="..."
USERNAME="..."
PASSWORD="..."
WRAPTEXT="80"
SUBJECT="#tx_automailer_register_subject# - #Local.User.Comp#"
>#cleanupTextMessage(message)#</cfmail>
<cffunction name="cleanupTextMessage" output="false">
<cfargument name="content" />
<!--- remove whitespace at beginning of each line --->
<cfset arguments.content = reReplace(arguments.content, "^\s+", "", "all") />
<!--- replace any multiple whitespace characters with one space --->
<cfset arguments.content = reReplace(arguments.content, "\s+", " ", "all") />
<cfreturn arguments.content />
</cffunction>
You might actually be able to nest the cfsavecontent inside cfmail, or create a custom tag that does savecontent and function actions.
Note: I was answering under the assumption the question was "how to make code look good without affecting the resulting text message". If you were trying to do something different with the resulting text output let me know.
You can use HTML To do it by adding the TYPE="html" to your cfmail attributes. Then put in a "pre" tag if you want that sysprint type look. as in
<pre>
#tx_automailer_default_hello#
#tx_automailer_register_info#
....
</pre>
Or you could add a table as in:
<table
<tr>
<td>#tx_automailer_default_hello#</td>
</tr>
<tr><td>
#tx_automailer_register_info#
</td>
If you want to stick with plain text you need to make sure you have tabs/spaces counted correctly and that none of your lines is longer than 80 chars (or they will wrap..without a beat too).
If you're set on plaintext email and are confident that the recipient will be using a fixed-width font, you can use lJustify() to align your text and pad with spaces.
Left justifies characters in a string of a specified length.
#lJustify(tx_automailer_register_iln & ":",32)# #lJustify(Local.User.iln,25)#
#lJustify(tx_firma & ":",32)# #lJustify(Local.User.firma,25)#
#lJustify(tx_ansprechpartner & ":",32)# #lJustify(Local.User.ansprechpartner,25)#
#lJustify(tx_adresse & ":",32)# #lJustify(Local.User.adresse,25)#
#lJustify(tx_plz & ":",32)# #lJustify(Local.User.plz,25)#
#lJustify(tx_ort & ":",32)# #lJustify(Local.User.ort,25)#

How to determine if a full name has a space in it?

I have a field that a user can input first and last name to fill out my form. Sometimes, users put on their first name and that results in empty fields in my database. PLEASE keep in mind that I cannot change this method completely because this form is part of a bigger project and it is being used by other websites of my company.
This is the part of the code that i need the validation around it. I already have a validation that ensures that the filed is not empty but I need on more to ensure that the field has two items in it separated by space.
<input name="fullname" class="fullname" type="text" value="#fullname#" maxlength="150"/>
<cfif fullname eq '' and check2 eq 'check2'>
<br /><span style="color:red">*you must enter your full name</span></cfif>
The check2 eq 'check2' is checking if the form was submitted already to ensure a user submitting their data twice.
I thought of using regular expressions to do that but unfortunately I am not very familiar with how to use regx in CF9 and the documentation online through me off a bit.
I was also thinking to use "Find" or "FindOneOF", any thoughts on that?
Also, I am trying to avoid using JQ,JS etc, so please try to keep your suggestions based on CF code IF possible.
Any help or different suggestions on how to tackle this issue will be very appreciated.
No regex is needed for this. A slightly simpler solution:
<cfset form.fullname = "Dave " />
<cfif listLen(form.fullname," ") GT 1> <!--- space-delimited list, no need for trimming or anything --->
<!--- name has more than one 'piece' -- is good --->
<cfelse>
<!--- name has only one 'piece' -- bad --->
</cfif>
You could do something like this for server side validation:
<cfscript>
TheString = "ronger ddd";
TheString = trim(TheString); // get rid of beginning and ending spaces
SpaceAt = reFind(" ", TheString); // find the index of a space
// no space found -- one word
if (SpaceAt == 0) {
FullNameHasSpace = false;
// at least one space was found -- more than one word
} else {
FullNameHasSpace = true;
}
</cfscript>
<cfoutput>
<input type="input" value="#TheString#">
<cfif FullNameHasSpace eq true>
<p>found space at position #SpaceAt#</p>
<p>Your data is good.</p>
<cfelse>
<p>Did not find a space.</p>
<p>Your data is bad.</p>
</cfif>
</cfoutput>