I use a Wordpress plugin called the Developer Formatter to display code blocks. In general, it works well for me, but I recently went to check the W3C HTML Validator and was getting a large number of errors. Working through them, there were four things that the validator did not like about the plugin output:
- The Javascript script tags used language=”Javascript” and did not include type=”text/javascript”.
- The flash (for the clipboard) used embed, which is a Netscape proprietary extension.
- Wordpress automatically adds paragraph tags and either the code block was in a paragraph with other content or it was in its own paragraph. Unfortunately,
<pre> is not a valid child of <p>, so the validator barfs.
- Even if I strip the paragraph tags, the <pre> contains a <table>. Again, table is not a valid child of pre.
The first problem was easy enough to fix. I just added the necessary type=”text/javascript” until the problem went away. The second was more complicated, but with the help of the Flash Satay technique, I was able to make a standards compliant version. I did not bother with creating the container flash, as the necessary flash is small enough to load completely. Streaming is not needed. The fourth was an easy fix. I just changed the pre to a div. This works fine in both IE and Firefox, so I’m happy. As you may have guessed, the third was not as simple a fix. I actually got it working pretty quickly by editing a WordPress function. However, I wanted to get it working by modifying the Developer Formatter plugin, as the solution has code specific to the plugin. That took longer, as the plugin does some wizardry that hides the code block while it is letting the WordPress content filters run. I originally tried to modify the wrong section of code and got no result, so I switched to adding a new filter that would run after the working WordPress filter. That failed. I finally worked out the proper place to change the Developer Formatter plugin and did so. The full set of code changes, starting with devinterface.php:
| 473 | function devfmt_commonHeader(){ |
| 474 | GLOBAL $DevFmt_Config; |
| 475 | echo "<script language=\"JavaScript\" type=\"text/javascript\"><!--\n var DevFmtUrl='".DEVFMT_URL."'; //-->\n</script>\n"; |
| 476 | echo "<script type='text/javascript' src='".DEVFMT_URL."devfmt_common.js?ver=".devfmt_Version()."'></script>\n"; |
| 477 | } |
The type=”text/javascript” was added. This code would also validate under XHTML strict if the language=”JavaScript” was removed. However, for my purposes, XHTML Transitional is sufficient. Next, in the devfmt_ParseStructure function in devformatter.php:
| 174 | 'background-position:50% 50%;width:16px;height:16px;vertical-align:middle;">' . "\n" . '<object id="ZeroClipboard'.$DevFmt_CodeIndex.'" |
| 175 | type="application/x-shockwave-flash" data="'. |
| 176 | DEVFMT_URL.'_zclipboard.swf" width="16" height="16" style="vertical-align:middle">'. |
| 177 | '<param name="movie" value="'. |
| 178 | DEVFMT_URL.'_zclipboard.swf" />'. |
| 179 | '<param name="FlashVars" value="id='.$DevFmt_CodeIndex.'&width=16&height=16" />'. |
| 180 | '<param name="wmode" value="transparent" />'. |
| 181 | '<param name="loop" value="false" />'. |
| 182 | '<param name="menu" value="false" />'. |
| 183 | '<param name="quality" value="best" />'. |
| 184 | '<param name="allowFullScreen" value="false" />'. |
| 185 | '<param name="allowScriptAccess" value="always" />'. |
| 186 | '</object>' . "\n" . '</td>'. |
replaced
| 174 | 'background-position:50% 50%;width:16px;height:16px;"/><embed id="ZeroClipboard'.$DevFmt_CodeIndex.'" src="'. |
| 175 | DEVFMT_URL.'_zclipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16px" height="16px"'. |
| 176 | ' align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash"'. |
| 177 | ' pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id='.$DevFmt_CodeIndex.'&width=16&height=16"'. |
| 178 | ' wmode="transparent" /></td>'. |
and to finish that function, change pre to div:
| 196 | return $regionflag[0].'<div class="devcodeblock" title="'.devfmt_getLangTitle($ALang).'">'. |
| 197 | $Toolbar.'<div class="devcodeoverflow"'.$AStyle.'>'.$ACode.'</div></div>'.$regionflag[1]; |
Later in the same file, in the devfmt_ContentFormat function, added
| 351 | $AContent = str_replace('<!--DEVFMTCODE-->', '</p><!--DEVFMTCODE-->', $AContent); |
| 352 | $AContent = str_replace('<!--END_DEVFMTCODE-->', '<!--END_DEVFMTCODE--><p>', $AContent); |
| 353 | $AContent = str_replace('<p></p><!--DEVFMTCODE-->', '<!--DEVFMTCODE-->', $AContent); |
| 354 | $AContent = str_replace('<!--END_DEVFMTCODE--><p></p>', '<!--END_DEVFMTCODE-->', $AContent); |
These became the last three lines before the else and then the return. I.e. the effect was to make these the last statements that ran before the string was returned. Finally, to make the javascript work with the object replacing the embed for the flash, in devfmt_common.js, I changed
| 56 | ZeroClipboard = { |
| 57 | dispatch: function(id, eventName, args){ |
| 58 | EmbedObj = jQuery("embed#ZeroClipboard" + id)[0]; |
| 59 | switch(eventName){ |
to
| 56 | ZeroClipboard = { |
| 57 | dispatch: function(id, eventName, args){ |
| 58 | EmbedObj = jQuery("object#ZeroClipboard" + id)[0]; |
| 59 | switch(eventName){ |
Now, with these changes, my site validates in XHTML Transitional. It almost validates in XHTML Strict, but the aforementioned language=”JavaScript” and the use of target=”_blank” keep it from passing. I’m not willing to give up the open in a new window functionality, so I’ll stick with Transitional.
I’m going to see if I can talk the author into including these or equivalent changes into the next version of the Developer Formatter. It looks like the clipboard actually is a third party library called Zero Clipboard by Joseph Huckaby. I’ll try to touch base with him as well.
Update: report posted on WordPress forums.
Update: issue reported at the Zero Clipboard project page.
Great job.
Soon as possible I’ll add these modifications.
Thanks.
(keep your eyes on the wp support page to see the news)
Comment by Gilberto Saraiva — 2009/09/14 @ 10:56