tracker issue : CF-4080440

select a category, or use search below
(searches all categories and all time range)
Title:

Allow additional attributes to be added to CFPARAM tags

| View in Tracker

Status/Resolution/Reason: To Fix//

Reporter/Name(from Bugbase): Alex Skinner / Alex Skinner (Alex Skinner)

Created: 10/28/2015

Components: Language

Versions: 11.0

Failure Type: Enhancement Request

Found In Build/Fixed In Build: CF11_Final /

Priority/Frequency: Trivial / Unknown

Locale/System: English / Mac 10.9 64 bit

Vote Count: 5

Our CMS PresideCMS www.presidecms.com uses a technique to decorate with additional attributes our  CFPARAM tags in our views in order to auto wire our views to our data layer, the open source engine we are using allows us to put additional attributes on the tags without complaining much in the same way as you can do with cfproperty tags

We have had enquiries from users who would like to run our CMS on the Adobe ColdFusion platform but at present there is no way of suppressing the errors

An example code snippet would be as follows

<cfparam name="args.teaser"                    field="page.teaser"                editable="true"                  />
<cfparam name="args.main_content"         field="page.main_content"   editable="true"                  />
<cfparam name="args.bottom_content"     field="page.bottom_content" editable="true"                  />
<cfparam name="args.datePublished"       field="news.datePublished"  editable="false" renderer="none" />

----------------------------- Additional Watson Details -----------------------------

Watson Bug ID:	4080440

External Customer Info:
External Company:  
External Customer Name: Alex Skinner
External Customer Email:  
External Test Config: My Hardware and Environment details:

Attachments:

Comments:

Heavy Preside CMS user, would like to see this application run on ACF also!
Vote by External U.
5432 | October 28, 2015 07:18:45 AM GMT
two of my clients are considering switching to lucee if this does not get implemented.
Vote by External U.
5433 | October 28, 2015 07:24:42 AM GMT
Like to support Awesome PresideCMS in ACF
Vote by External U.
5434 | October 28, 2015 08:39:54 AM GMT
PresideCMS would be of benefit to the ACF platform if it was able to run on it, lets make this happen!
Vote by External U.
5435 | October 28, 2015 10:26:37 AM GMT
TBH - and I've discussed this with Alex directly - I think PresideCMS's approach is poor here, even considering it happens to work on Railo/Lucee. Properties (and functions, and components) have a prescribed notion of metadata, and it makes sense that they can additional attributes. <cfinvoke> also takes any attribute as one needs to be able to pass function argument names with the invocation. But this doesn't apply to <cfparam>: it has no *legitimate* reason to have extra attributes. So... then one might think... let's allow any tag to have any attribute. But that's a code-checking nightmare in the making. Perhaps CFML tags could take additional unchecked attributes, eg: <cfparam name="args.teaser" meta:field="page.teaser" meta:editable="true" /> I would vote for that. But not because it's actually a good idea, but it's not intrinsically a *bad* idea, which I think this ER is. What Alex ought to do (ought to have done ~) is not co-opt a CFML tag to do something it was never intended for. It muddies his code, for one thing. He could solve his problem reasonable easily with a custom tag, and that would make more semantic sense as well, eg: <cfimport taglib="/com/pixl8/preside/tags prefix="pcms"> <pcms:param anything="atall" cango="here"> <!--- etc ---> Obviously this is a -1 vote for this.
Comment by External U.
5405 | October 28, 2015 10:42:54 AM GMT
"Heavy Preside user", Niall? You work for bloody Pixl8, you shill! ;-)
Comment by External U.
5406 | October 28, 2015 10:43:23 AM GMT
Adam by that rationale we should never have used the technique we did back in the cf6 days of adding additional attributes to the cfproperty tag that weren't supported. It worked though and when adobe did its orm implementation it opted for similar practice. So at best it's not consistent of where you can and can't do this. I personally think parametrising your views is clean and perhaps the issue is not whether it should allow you to put attributes but it should go further and give you a mechanism to find a templates parameters. In the same way as you have getcomponentMetadata() for components being able to programmatically learn a views expected parameter requirements is useful Not the right name but getTemplateParams("foo.cfm")
Comment by External U.
5407 | October 28, 2015 11:09:49 AM GMT
I disagree on this being a 'poor' approach Adam. The use of <cfparam here is very deliberate. If not using the special preside data view technique and wanting to use these views, the cfparam tags can correctly be used to throw errors when the expected data has not been passed in / is not present (readable and declarative). I can't think of a reasonable argument *for* only allowing the prescribed attributes on the tag, the ability to extend the language with meta is a real + for CFML and I think this is a good example of that.
Comment by External U.
5408 | October 28, 2015 11:34:19 AM GMT
Allowing developers to arbitrarily extend the language for their own needs is a really useful thing. Plus having PresideCMS run on ACF would be a plus.
Vote by External U.
5436 | October 28, 2015 11:35:56 AM GMT
Hey Alex, like I mentioned: "Properties (and functions, and components) have a prescribed notion of metadata, and it makes sense that they can additional attributes." (by properties, I meant <cfproperty>, sorry). It's always been documented as *specifically* for providing metadata. This has been in the docs since 6.1 I dunno where it's documented or discussed that <cfcomponent>, <cffunction>, <cfproperty> and <cfargument> work this way, but it *is* widely known. And I'm *pretty sure* it's also widely known that other tags *are not* like that. I feel for your predicament, but I don't think it's CFML's to deal with, sorry. But I am only one voice, and Adobe should listen to everyone's. And then make their own informed decision. Obviously I tend towards being a bit dogmatic when it comes to language rules, and sometimes some pragmatism might be a better option. But CF Mitrah solicited opinions on this... and this is my one ;-) Now... "but it should go further and give you a mechanism to find a templates parameters"... yeah, I def agree that that could be "a thing". Is there a broader solution to this which might be a bit less coupled to Preside's specific/current approach?
Comment by External U.
5409 | October 28, 2015 11:38:56 AM GMT
What on earth do these extra attributes do on cfparam? How does your code access them? This seems like a terrible approach to me and I'm strongly against it on first reading.
Comment by External U.
5410 | October 28, 2015 02:04:12 PM GMT
@Dom you should probably be a bit more forthcoming here; as much to identify the fact you are actually the dev/instigator of this behaviour in PresideCMS? This *is* your code we're discussing working around here, right? But agenda aside, let's look at what you say: "Allowing developers to arbitrarily extend the language for their own needs is a really useful thing". Really? Is it? What's an example of this? I know where languages can be purposely extended... by... like... *actually extending them*, and situations where even sealed classes can be reopened and modified: cool. But arbitrarily just expecting to be able to bolt stuff on without defining what that stuff means? Which language does that (serious question: let's have a look at how they do this)? If you approached this along the lines of being able to "extend" existing tags for one's own ends, by dropping the mods into a certain directory or what-have-you, I'd perhaps agree provided there was a note above the gate saying "Here be Demons" But just arbitrarily adding previously undescribed stuff on at runtime? No. Bad design. Let's bin the bad approach, and look at a good approach.
Comment by External U.
5411 | October 28, 2015 06:22:42 PM GMT
>>> @Dom you should probably be a bit more forthcoming here; as much to identify the fact you are actually the dev/instigator of this behaviour in PresideCMS? This *is* your code we're discussing working around here, right? Why should this matter? This is not a personal matter and we're not discussing working around code - we are discussing an enhancement request (that I didn't make). I appreciate that this ER might not make it, or necessarily be desirable, but we are aware of the alternatives and discussing the quality of my architectural decision making is irrelevant here (I'm not claiming that it was the perfect decision). >>> "Allowing developers to arbitrarily extend the language for their own needs is a really useful thing". Really? Is it? What's an example of this? PresideCMS. This approach has proved useful for the end-developer experience.
Comment by External U.
5412 | October 29, 2015 01:50:15 AM GMT
Reasons I can think to *not* allow this: 1. Introduces a shift of behaviour just for cfparam 2. Means that the compiler is not able to warn against typos in attributes, e.g. 'defalt=""' I think this may warrant a deeper exploration on what is possible and desirable architecturally and not sure that in this current form that it is ready (though allowing it doesn't offend me). In particular, the notion of being able to have cfm templates declare what data they expect to be available to them and for outside code to be able to retrieve that data through system provided inspection would be a useful addition imo.
Comment by External U.
5413 | October 29, 2015 03:17:24 AM GMT
CFCs already have the precedent set for using javadoc style comments for assigning metadata to functions and arguments, eg: /** hint this is the function's hint */ function f(){ // etc } This could be extended to work in CFM files? Although you'd probably want tag-based comment delimiters, I s'pose, eg: <!---- metakey meta value ---> (note there's FOUR dashes on that opening delimiter). Would that work? Is that sensible? I wonder, Dom, if there's a better venue for us to flesh this out? The ColdFusion forums? The Lucee Lang forum? Slack?
Comment by External U.
5414 | October 29, 2015 06:57:37 AM GMT
The key distinction with CFCs and metadata is that you get to compile an instance and pass it around and inspect it. It makes sense for such an entity -- and its constituent parts -- to have metadata. A .cfm template doesn't have that characteristic. Nor do variables inside the runtime. Clojure allows for metadata on certain types of values but that's built into the core of how values are handled and there is a cost associated with that: every value (with a few exceptions) has to be an object and have a pointer to metadata (so supporting metadata in general can be quite expensive from a memory point of view). Changing CFML to support metadata on variables or values would be a huge change and it's not clear how much value it would add -- for developers at large -- compared to the (memory, and potential performance) cost of doing so. Having metadata on values would make CFML a very different language that would need a lot of additional features added in order to make it worthwhile and work properly. So what about the more limited context of allowing .cfm files to have metadata somehow and formalizing this idea that they have "parameters"? Well, we already have things that have metadata and things that have both metadata and parameters (components and functions respectively). Those things are "first class objects" in CFML so it seems that we'd need some thing similar for .cfm files: a way to declare metadata for the template itself, and a way to declare parameters -- and a way to create an instance of a template and inspect and manipulate it, and then run it. So let's consider a new function getTemplateMetadata() that accepts a (possibly mapped) path to a .cfm file. We know the .cfm files are compiled to "page" objects so it's reasonable to be able to load a .cfm file without actually running it. OK. Now, how would we specify the metadata? What about extending cfprocessingdirective for the template metadata and allowing cfproperty inside templates? Currently cfproperty is not allowed inside a .cfm template so this has no backward compatibility concerns. And cfprocessingdirective only supports two attributes so there's plenty of "room" to allow arbitrary attributes to add metadata to the "page" object. Allowing cfproperty inside a .cfm would allow the compiler to attach property metadata to the "page" object too -- at compile time, without any runtime issues. cfproperty has no runtime behavior: it may change the compiler's behavior and therefore cause different code to be generated (e.g., setters/getters, ORM handling code, etc). And all that could be inspectable by getTemplateMetadata(). That doesn't get everything PresideCMS needs, but it gets most of it -- in a way that mimics the existing machinery for CFCs, mostly. You'd still need cfparam for some of your _runtime_ behavior -- so _some_ information about "parameters" would need to be duplicated: partly in cfproperty and partly in cfparam -- but that's true of CFCs today. Mind you, adding cfproperty to .cfm files could be done in such a way that certain aspects cause the compiler to generate the equivalent of cfparam at the top of the .cfm page (or at least inline where the cfproperty tag is encountered). There is precedent, insofar as setters/getters are generated that require arguments, and type check them.
Comment by External U.
5415 | October 29, 2015 11:00:27 AM GMT
@Sean, I like it, kinda. Unless I'm misunderstanding, using the <cfproperty> tag would only be used in this way to allow developers to define arbitrary named metadata properties - that framework developers, etc. would be able to then inspect. I think this is great but for the fact that you would need to duplicate <cfproperty and <cfparam if you also wanted to have a .cfm that declared what variables it expects to exist as well as reporting any additional metadata about those variables through the <cfproperty tag. What is unclear to me, is why <cfparam> could not be used to that effect here. It contains meaninful data for the .cfm file, e.g. "Hey, I need this variable and it needs to be this type". That would be potentially useful meta to be able to read out of the file in a "GetTemplateMetaData()" method. Let's put some examples out there (running with the idea that you'd have 'getTemplateMetaData()' as the name of additional function: <cfparam name="args.somevar" type="boolean" default="false" /> <cfparam name="args.anothervar" type="string" /> <cfparam name="args.athirdvar" /> <cfproperty name="args.somevar" renderer="richcontent" /> Then the output of "GetTemplateMetaData()" might then look like (when serialized to json): { "params" : [ { "name":"args.somevar" , "type":"boolean", "required":false, "default":"false" } { "name":"args.anothervar", "type":"string" , "required":true , "default":"false" }, { "name":"args.athirdvar" , "type":"any" , "required":true , "default":"false" }, ], "properties" : [ { "name":"args.somevar", "renderer":"richcontent" } ] }
Comment by External U.
5416 | October 29, 2015 11:47:24 AM GMT
Because cfproperty is already for metadata and the compiler deals with it (and generates code accordingly). cfparam is a purely runtime construct that checks a variable's contents (and may update the variable) -- when that code actually runs. As for duplication, re-read the last paragraph of my proposal.
Comment by External U.
5417 | October 29, 2015 11:55:52 AM GMT
Scratch my last comment - the example that makes it clear is this: <!--- inside some.cfm template ---> <cfinclude template="somefilethatMightDoAllsorts.cfm" /> <cfparam name="somevariable.i.think.might.exist.after.my.include.has.run" /> i.e. we cannot infer that a <cfparam> tag is declaring expected variable presence *before* the template is included - it could be during the runtime execution of the template (as Sean points out).
Comment by External U.
5418 | October 29, 2015 12:29:00 PM GMT
Copying in some more of my thoughts from the ongoing discussion in #adobe on the CFML Slack: I’m suggesting that `cfproperty` cause the compiler to emit the "equivalent of cfparam" (with appropriate attributes) at the place where the `cfproperty` tag appears — as well as adding metadata to the template. I’m trying to be very precise about the semantics here (because I’m a language designer and have been for decades and sloppy semantics bother me a lot). `cfparam` supports four attributes. I’m not suggesting `cfproperty` assign semantics to all four (but it could). Note that it would also be possible (under my proposal) to say things like: <cfscript> property numeric id = 0; </cfscript> just like you can in a CFC — which is why I’m not saying it should behave like `cfparam` directly since `property` in a CFC does not do validation ?_per se_?. For `property` in a CFC to ?_do_? something — code generation — certain other attributes need to be present in some combination, and I think that explicit intent is important. I’d be comfortable, for example, with requiring `validate=true` on `property` in order for it to affect code generation, rather than be ?_just_? metadata. You need a way to be able to just specify metadata — independent of code generation — so if you want code generation ?_as well_? you should have to explicitly say so.
Comment by External U.
5419 | October 29, 2015 12:42:43 PM GMT
Hi Sean, Perhaps your suggested enhancement to the treatment of .cfm could make way for allowing "var" to be used to create template-local variables (CF-3773095)? Thanks!, -Aaron
Comment by External U.
5420 | October 29, 2015 02:36:50 PM GMT
Hi Sean, Perhaps your suggested enhancement to the treatment of .cfm could pave the way for allowing "var" to be used to create template-local variables (CF-3773095)? Thanks!, -Aaron
Comment by External U.
5421 | October 29, 2015 02:37:24 PM GMT
(the bug tracker threw a CF exception)
Comment by External U.
5422 | October 29, 2015 02:38:02 PM GMT
(I thought my original post didn't make it - so edited and re-posted.. then dupe!)
Comment by External U.
5423 | October 29, 2015 02:39:18 PM GMT
I don't see any connection between this proposal and that one, but template-local var variables is a good enhancement anyway.
Comment by External U.
5424 | October 29, 2015 02:42:29 PM GMT
BTW I already voted for that other ticket ages ago.
Comment by External U.
5425 | October 29, 2015 02:45:09 PM GMT
What have these extra attributes got to do with CFML? No, no. This is a bad idea. CFML shouldn't have to change just because someone else's app uses the language in a bespoke way. If this must be implemented then there are cleaner ways to do it. e.g. CF could ignore attribs that it doesn't understand, just like a browser does for HTML. Have a CF Admin switch to toggle between throwing an error for unsupported attribs or ignoring them. Alternatively introduce X-Attribs, like in email headers. So you can add a header "X-Weather: Sunny" in an email and only systems that are looking out for it will process it. So in CFML tags you could have <cfparam name="args.teaser" x-field="page.teaser" x-editable="true"> So anything with an X can safely be ignored unless the installed CF version recognises it. No more sticky plasters or half baked changes to CF please. Think strategically, long term, and for the cleanest and most consistent syntax please.
Comment by External U.
5426 | October 29, 2015 09:49:47 PM GMT
Gary, did you actually read my proposal to use cfproperty? That already allows arbitrary attributes, which become metadata.
Comment by External U.
5427 | October 29, 2015 09:54:03 PM GMT
Hey, Adobe, I got a notice that you updated this ticket but I don't see any indication of what you changed -- can you add a note please when you change the status of a ticket?
Comment by External U.
5428 | October 29, 2015 10:39:25 PM GMT
Hi Sean, No worries; I was confused. +1 to your proposal. Thanks!, -Aaron
Comment by External U.
5429 | October 30, 2015 12:54:32 AM GMT
@Gary I think you misinterpreted the OP - it was asking for arbitrary attributes not to throw an error as you suggested (not to add specific attributes).
Comment by External U.
5430 | October 30, 2015 03:40:39 AM GMT
I would have to agree with other comments here, we don't need to muddy the language solely for the purpose of supporting an specific application, the change has to make sense for the language as a whole, and as proposed, this would not be a good change. So a downvote from me on this. Sean's suggestion of the use of cfproperty in cfm pages makes infinitely more sense and I would be in favor of that instead.
Comment by External U.
5431 | October 30, 2015 11:26:56 AM GMT