2009/09/12

Validating devformatter content

Filed under: eCartz — Tags: , , , , — eCartz @ 06:11  Share/Bookmark  Delicious  StumbleUpon  WordPress  Twitter  LinkedIn

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: 

  1. The Javascript script tags used language=”Javascript” and did not include type=”text/javascript”. 
  2. The flash (for the clipboard) used embed, which is a Netscape proprietary extension. 
  3. 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. 
  4. 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:

 PHP |   copy code |? 
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: 

 PHP |   copy code |? 
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.'&amp;width=16&amp;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

 PHP |   copy code |? 
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.'&amp;width=16&amp;height=16"'.
178
        ' wmode="transparent" /></td>'.

and to finish that function, change pre to div: 

 PHP |   copy code |? 
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

 PHP |   copy code |? 
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

 PHP |   copy code |? 
56
ZeroClipboard = {
57
 dispatch: function(id, eventName, args){
58
    EmbedObj = jQuery("embed#ZeroClipboard" + id)[0];
59
    switch(eventName){

to

 PHP |   copy code |? 
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.

  1. 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

RSS feed for comments on this post. TrackBack URL

Leave a comment

You can log in to post a comment, or just fill out your name and email.

Powered by WordPress