I ran into a problem recently where a completely valid XHTML 1.0 transitional site was rendered incompliant by the addition of <cfmenu>. It seems that <cfmenu> causes compliance to fail in two ways:
First, it adds JavaScript to the “OnMouseOver” and “OnMouseOut” attributes of its menu items. To be compliant, it should be adding them to the “onmouseover” and “onmouseout” attributes. There’s an easy fix to this. Inspired by Ben Nadel’s post on altering the output of the writeToBrowser feature of <cfimage> I just used <cfsavecontent> to capture the menu, and then alter it, as listed below:
<cfsavecontent
variable=“menuContent”>
<cfmenu
name=“menu”
type=“vertical”>
<cfmenuitem
name=“home”
href=“index.cfm”
display=“Home”/>
</cfmenu>
</cfsavecontent>
<!— These calls help bring page to XHTML compliance. —>
<cfset menuContent = Replace(menuContent, “OnMouseOver”, “onmouseover”, “ALL”) />
<cfset menuContent = Replace(menuContent, “OnMouseOut”, “onmouseout”, “ALL”) />
<cfoutput>#menuContent#</cfoutput>
But that doesn’t hit the other problem, which is that any of the Ajax capable tags seem to add the following bit of code to the top of a page:
_cf_loadingtexthtml=”<div align=’center’><img src=’/CFIDE/scripts/ajax/resources/cf/images/loading.gif’/>”
This screws up compliance on two fronts:
- The div created in that code isn’t closed.
- The img created in that code doesn’t have a alt tag.
Now the interesting thing here is that isn’t actually a div that’s created, it’s only JavaScript that will at some point create those elements. I think technically the compliance test is falsely marking this as a violation. But try explaining that to a client who demands compliance without understanding the theory behind it.
Anyway, I can’t find a single way around this. Using the OnRequest method of application.cfc was my best bet. I figured I would use to call <cfsavecontent> and replace the offending code like I did above. Unfortunately, this spot of code is directly written to the buffer when <cfmenu> gets called.
I also tried a few getPageContext() functions, but to no avail. I’ll be stuck trying to explain this to the client. In the meantime, I filed a bug report with Adobe.
Adobe has got to get more xhtml-conscience peeps into the CF Beta/Alpha. I think this is one of the issues. We’re all so focused on new features and such, we forget about the standards.
LikeLike
I agree – all these ‘features’ aren’t going to do me a bit of good if they don’t generate valid, compliant code.
LikeLike
In regards to passing validation, Adobe also need to keep in mind HTML 4.01 and, in the future, HTML5. I haven’t played with validating any of the generated code yet, but if Adobe went down the path of only generating valid XHTML it could be a bad thing (even though the parsing of HTML is a lot more forgiving).
LikeLike
I’ve been arguing about this for years, going all the way back to the fact that paragraphFormat() still adds a single closing <P> tag. The auto server-side form validation adds an unclosed input tag. Now, cfimage provides no way to add alt text. And so on and so on. It’s always seemed to me that these shouldn’t require major rewriting of things, but when I have raised these issues with folks at Adobe, the response has always been “do you want us fixing things like this, or adding new features?” We need to get the message out that yes, we want these fixed!
And Justin – I would argue that adding XHTML support would not in any way mess up HTML 4.01 pages, since technically, XHTML is valid HTML (but not the other way around), and potentially having to support a theoretical future version of HTML isn’t a valid reason to not support a current version of XHTML. However, if that is a real issue, then maybe we need to have something like a cfdoctype element that lets us control these types of things.
LikeLike
@Rob: That’s what I was throwing out there; we might want to have better control over the output in the future, especially if HTML5 and XHTML2 are butting heads 😛 XHTML1 should be covered since HTML5 will be backwards compatible.
For now though I hope Adobe can fix validation issues fairly quickly, since the last thing we’d want is for some tags to become unusable in certain situations. Good post Terrence 🙂
LikeLike
@Rob,
We are working on the issue to add alt text with cfimage. We maybe posting a patch for this, but no promises.
@Terrence
I saw your wishlist posting and have logged a bug for the same. We will try to resolve it for the next release.
Please let us know any feedback/specific issues using
http://www.adobe.com/cfusion/mmform/index.cfm?name=wishform
so that we can review and track the issues.
Thanks,
Hemant
LikeLike
@Terrence,
I am curious as to what went wrong with the OnRequest and the CFSaveContent. Other than not being able to flush any of the content to the browser until the whole page has rendered, it should have worked. What CFMenu actually writing to the primary content buffer from within the CFSaveContent tag?
LikeLike
@Hemant Thanks, the only issue I have with the wish form is that lack of feedback from it. I don’t know if my replies go to the either or are being seen by someone.
LikeLike
@Ben, somehow cfmenu is writing the javascript includes to the buffer independent of the way the rest of the content is created. If you wrap the call in a cfsavecontent, but don’t output it, it still adds that stuff to the html head. (Dumping the source of the ensuing blank page will reveal that. )
LikeLike
This is one of the main reasons I refuse to use Spry.
LikeLike
I’m glad to see that there are other CF developers out there as concerned as I am with the lack of XHTML validation in code generated by ColdFusion. I recently posted a similar rant on my web site at http://www.richarddavies.us/archives/2007/08/coldfusion_is_the_next_frontpage.php
If enough of us start complaining about this, hopefully Adobe will do something about it!
BTW, I really liked the suggestion of using savecontent to fix some of the invalid code.
And regarding the “invalid” HTML in the JavaScript string. You are correct that it should not be flagged as invalid because technically it’s just a string. But you’re wrong in assuming that the validator is flawed. JavaScript code blocks should be nested inside CDATA tags (i.e. “// “) to tell the validator not to parse the contents of the script tags.
LikeLike
Terrence,
I posted a comment yesterday, but it appears your spam filter flagged it as junk (possibly because I included a link).
LikeLike
@Richard, I’ve restored your comment, and I’m glad I did. That’s some good information. I can’t take credit for the cfsavecontent idea though, I stole that from Ben Nadel.
LikeLike
I am curious as to what went wrong with the OnRequest and the CFSaveContent. Other than not being able to flush any of the content to the browser until the whole page has rendered, it should have worked. What CFMenu actually writing to the primary content buffer from within the CFSaveContent tag?
LikeLike
Thanks for posting this. Has anyone figured out how to make it compliant?
LikeLike
A worthy topic. I see that CF 8,0,1 adds the alt attribute. So there’s one problem fixed.
The other issue still stands. And I am so disappointed in Adobe for not fixing such a simple and important issue. One year on, it still exists!
Good post, Terrence.
LikeLike
Where can i have more info on this ?
Regards
LikeLike