Copy link to clipboard
Copied
As a stickler for code semantics, I've noticed that my generated code will use indenting in my .cfm file, but if that .cfm file calls, say, a function from another file, and in the called .cfm file it has indenting to keep that file's output looking good, that when it gets pulled into the caller's output, the indenting becomes increased.
Has anyone come across a method to uniform this?
Copy link to clipboard
Copied
Always specify output=false on your functions. Switch the "control whitepsace" (or whatever it is) setting on in CF Admin. Use CFScript as much as possible as it doesn't generate any output at all (unless, like, with a writeOutput() statement ;-).
--
Adam
Copy link to clipboard
Copied
<cffunction name="generateCode" access="public" output="false" returntype="string">
<!--- Define params. --->
<cfparam name="strOut" default="" type="string" />
<cfsavecontent variable="strOut">
<cfoutput>
<div>this div gets tabbed</div>
</cfoutput>
</cfsavecontent>
<!--- Return. --->
<cfreturn strOut />
</cffunction>
The above function is instantiated into application.comUDF so I call it like:
#application.comUDF.generateCode()#
(I've determined that I cannot call it via CFINVOKE, which would have been nicer. The following won't output the returned code)
<cfinvoke component="#application.comUDF#" method="generateCode" returnvariable="strOut" />
(without having to then dump strOut to the buffer)
In the function, if I add more tabs they are carried over, so I could just tab that code a lot until it lines up in the generated page code, but this seems as a roundabout solution.
Copy link to clipboard
Copied
Are you referring to indentation in the generated html code?
<cfparam name="strOut" default="" type="string" />
I do not know what else your function is doing. But the use of cfparam in an application scoped function jumped out at me. Is strOut supposed to be a function local variable?
Copy link to clipboard
Copied
Yes. Indention for generated code.
As for the param, I guess I should have done something like
<cfset local = {} />
<cfparam name="local.strOut" type="string" default="" />
if I wanted to be strict about it. I like paramming all my functions. Whatever variables they use, even if it's the variable that holds the return value, I param it out.
Copy link to clipboard
Copied
I like paramming all my functions.
Whatever variables they use, even if it's
the variable that holds the return value, I param it out.
Why not just use cfset statements?
cfparam name="local.strOut" type="string" default=""
Yes, given that the function is in a shared scoped, scope leakage is a greater concern than presentation.
-Leigh
Copy link to clipboard
Copied
I got a habit of paramming my vars for use at the begging of where they begin.
For example. in my onSessionStart, I have param'd all possible Session scoped vars.
I do the same thing for App and Request Scope, not to mention when my functions use parameters, I set them to the local scope. What I should have done was:
<cfset var local = {} />
which is the same as
<cfset var local = structNew() />
then:
<cfparam name="local.strOut" type="string" default="" />
Var will ensure that it stays within the function's scope.
I do love some organized code. SO much easier to get back into months down the line.
Copy link to clipboard
Copied
I got a habit of paramming my vars for use at the begging
Yes, but you can do that just as easily with cfset. For the purpose of declaration and initialization, I think cfset is more clear. ie You know the exact state of the variable after the statement. Whereas you might not with cfparam because it is conditional.
Just my $0.02
-Leigh
Copy link to clipboard
Copied
I got a habit of paramming my vars for use at the begging
Yes, but you can do that just as easily with cfset. For the purpose of declaration and initialization, I think cfset is more clear. ie You know the exact state of the variable after the statement. Whereas you might not with cfparam because it is conditional.
Agreed. There's no good reason to have both a <cfset> and a <cfparam> here. In fact given we're already seen an example in your own code of forgetting to VAR the variable in the first place, I reckon this is a pretty poor practice.
Equally, if the intent is that the variable is function-local, <cfparam> is a pointless construct to use because the intent of <cfparam> is one or both of:
a) set a default value if a value does not already exist for the variable;
b) type-check an existing variable.
Because the function-local variable is "new" - ie: it cannot possibly already exist - <cfparam> serves no purpose here. One might as well use a <cfset>. Especially as <cfset> allows one to VAR the variable.
If, on the other hand, the intention was to set a CFC-wide variable (one in the variables scope), then I think paraming it inside a function is the wrong place to do it. It should be done in either the pseudo-constructor or in the init() method. But, again, there's no point in using <cfparam> in this case either, for exactly the same reason as with the function-local example.
Basically... it's the wrong thing to be doing, and I think it makes the code more obscure, not more clear, because someone who knows when to use <cfparam> is going to be going "WTF is going on here?"
--
Adam
Copy link to clipboard
Copied
Basically... it's the wrong thing to be doing, and I think
it makes the code more obscure, not more clear, because
someone who knows when to use <cfparam> is going to be
going "WTF is going on here?"
I think you hit the nail on the head. Looking at that code had me scratching my head, trying to figure out what it was supposed to be doing.
-Leigh
Copy link to clipboard
Copied
There's not much I can do when you're at the mercy of the editor used by these forums. If it's gonna strip indents/code and not provide a
wrap tag to keep those characters, then that's the best I can do.
Copy link to clipboard
Copied
That's not what we mean. I can guess where the indentation is, that's fine. What we mean is your usage of <cfparam> is a bit bung.
We've kinda moved on from your indentation problem a bit.
Although did you see my comment as to why you're getting it?
--
Adam
Copy link to clipboard
Copied
Aegis Kleais wrote:
If it's gonna strip indents/code and not provide a
wrap tag to keep those characters, then that's the best I can do.
Well, the web interface DOES provide a code format feature under the ever so clearly (note sarcasm) >> control above the web input area. At least in the HTML input interface.
Copy link to clipboard
Copied
<cfsavecontent variable="strOut">
<cfoutput>
<div>this div gets tabbed</div>
</cfoutput>
</cfsavecontent>
[...]
In the function, if I add more tabs they are carried over, so I could just tab that code a lot until it lines up in the generated page code, but this seems as a roundabout solution.
I guess your original code had indentation which the forums UI has stripped out?
The reason that the indentation is persisting in this case is because you're making a point of capturing it when you use <cfsavecontent>. <cfsavecontent> captures the string generated within it. It' doesn't "capture the string generated within it except for the indentation". It doesn't know what's indentation and what's not.
What you need to do in this case is to use <cfsetting> to make only <cfoutput> statements generate output, and surround just the stuff you actually want output (so: not the indentation).
Or you could remove the indentation after capturing the string.
--
Adam
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more