Showing posts with label w3c. Show all posts
Showing posts with label w3c. Show all posts

Monday, October 13, 2008

JavaScript XMLHttpRequest Wrapper

Here is my version of the XMLHttpRequest Wrapper, Open Source, and available on Google Code. Enjoy.

Here is a simple example of a http request with the lib:

new fiji.xhr('get', 'echo.php?param=value', function(xhr) {
   if (this.readyState == 4 && this.status == 200) {
      alert(this.responseText);
   }
}).send();

The readystate callback handler executes in the scope of the XHR Instance. So you can use the this keyword to reference the XHR object instance. This behavior is the same as the specifications for the callback scope in the W3C XMLHttpRequest Specs. You can also receive a reference to the XHR library instance which is passed as the first parameter to the callback. In the case above it would be xhr. This allows you to attach further references or objects to the XHR library instance that would be persisted for the duration of the XHR call. For example, a request ID.

Sunday, January 20, 2008

Cleaning xHTML markup with PHP Tidy

Everyone makes mistakes. Even the best xHTML coders will sometimes write invalid xHTML. Not to worry, PHP can automatically clean up xHTML before display using the PHP Tidy Extension.

PHP Tidy uses the Tidy Parser. Tidy, is ported to many programming languages, and allows the language to clean up XML documents. It works well for xHTML.

In PHP5, the tidy extension is a default extension, however, in PHP4 you will need to download the Tidy PHP4 extension and compile the PHP executable with Tidy support.

How to use Tidy in PHP is documented here. Here is some examples of what Tidy can do.

Example use of Tidy in PHP

For code portability/distribution its necessary to first check if the tidy extension is available on your PHP version. You can do this by querying the existence of the tidy functions or classes (among other methods). So first you check if Tidy support is availalbe:

if (function_exists('tidy_parse_string')) {
// do your tidy stuff
}
Then comes the tidying. For simplicity, I'll use the single PHP Tidy function, 'tidy_repair_string'.

// Specify configuration
$config = array(
 'indent'         => true,
 'output-xhtml'   => true,
 'wrap'           => 200);
// Specify encoding
$encoding = 'utf8';
// repair HTML
$html = tidy_repair_string($html, $config, $encoding);

This works for both PHP4 and PHP5. PHP5 also supports an OO syntax.

Example Implementation: PHP Tidy Plugin for Joomla

Here is how I implemented the PHP Tidy Plugin into Joomla.

Joomla is a Content Management System, thus you cannot directly control the xHTML that will go into your articles. Some of your users may not be very xHTML savvy. The main reason I implemented Tidy is to clean content inserted automatically from feeds - which you have absolutely no control over.

A Joomla Plugin implements a basic Observer Pattern into Joomla. Functions are registered as observers, which are triggered during certain events. One such event is the preparation of content for display. The tidy plugin thus registers as a handler of content preparation. It then passes all content through the tidy parser, and returns the clean xHTML to Joomla.

The Joomla Tidy Plugin Code


/**
* @copyright Copyright (C) 2007 Fiji Web Design. All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
* @author gabe@fijiwebdesign.com
*/

// no direct access
defined( '_VALID_MOS' ) or die( 'Restricted access' );

// register content event handlers
$_MAMBOTS->registerFunction( 'onPrepareContent', 'bot_tidy' );

/**
*  Tidy up the xHTML of your content
*/
function bot_tidy( $published, &$row, &$params, $page=0 ) {
 
 if ($published) {
  // get the plugin parameters
  //$botParams = bot_tidy_getParams('bot_tidy');

  if (isset($row->text) && $row->text) {
   $row->text = bot_tidy_parse($row->text);
  }

 }
 return true;
}

/**
* Parses a string with tidy taking into consideration the Joomla encoding
* @param String xHTML
*/
function bot_tidy_parse($html) {
 if (function_exists('tidy_parse_string')) {
  
  // Specify configuration
  $config = array(
       'indent'         => true,
       'output-xhtml'   => true,
       'wrap'           => 200);
  // get Joomla content encoding
  $iso = split( '=', _ISO );
  $encoding = '';
  $jos_enc = str_replace('-', '', $iso[1]);
  if (in_array($jos_enc, array('ascii', 'latin0', 'latin1', 'raw', 'utf8', 'iso2022', 'mac', 'win1252', 'ibm858', 'utf16', 'utf16le', 'utf16be', 'big5', 'shiftjis'))) {
   $encoding = $jos_enc;
  }
  
  // Tidy
  $html = tidy_repair_string($html, $config, $encoding);
  
  return $html
  ."\r\n"
  ;
 } else {
  return $html
  ."\r\n"
  ;
 }
}

Here is the tidy plugin for Joomla.

Tidy is great for Content Management Systems where content is contributed by users with differing levels of xHTML knowledge. It is also necessary if you want content from RSS feeds to pass W3C validation (if they contain xHTML like the Google News Feeds). I've noticed however, that PHP Tidy does not always create valid xHTML content. It does however create valid XML every time. This is yet to be explored further as I have just released Joomla Tidy Plugin for Alpha testing.

Use invalid CSS in a W3C standards compliant XHTML Document

This is a technique I've decided to offer in the Joomla Extensions I've developed for the Joomla community, in an effort to allow users of the extension to use invalid CSS on their pages, yet still have the page validate with the W3C CSS Validator.

Why use invalid CSS markup?

Now why would you want to use invalid CSS in the first place? The reason is that not all browsers support the W3C recommended CSS2 and CSS3 properties. (Ahem.. Microsoft.. Ahem...). Now with IE7 our CSS is diverging even more. So the use of invalid CSS is quite inevitable.

An Example Maybe?

Lets say you want to make an image transparent. Something that should be quite simple. So you use the W3C recommended CSS property which is opacity:

img {
   opacity:0.50;
}
Amazingly, this piece of CSS does not validate. Try copy and pasting it to the CSS validator.

Not only does it not validate, it doesn't work for a couple of browsers. So, in order to have image transparency across the largest number of browsers, you need:

img {  
   filter:alpha(opacity=50); 
   -moz-opacity:0.50;  
   opacity:0.50; 
   -khtml-opacity:0.50; 
}
Now this 4 property definitions will create exactly 4 errors in the CSS validator. Hahaha.

How do I use invalid CSS markup that validates?

Now the fun part. In our server logs, around 99% of actual users have JavaScript enabled on their browser. So why not use JavaScript to serve your CSS. If you're familiar with JavaScript Remoting, this is exactly the technique applied to a different problem. In JavaScript remoting, JavaScript files are loaded dynamically after the page has fully loaded. With this technique, CSS is loaded dynamically after the page has loaded.

window.onload = function() {
   if (document && document.getElementsByTagName) {
 var head = document.getElementsByTagName('head')[0];
 var link = document.createElement('link');
 link.type = 'text/css';
 link.rel = 'stylesheet';
 link.href = 'invalid_styles.css';
 head.appendChild(link);
   }
};

What we have is a piece of JavaScript that will load the CSS file, invalid_styles.css, after the HTML Document has loaded. So all you need to do is place your invalid CSS in invalid_styles.css. The W3C validator does not render JavaScript generated Elements on the page, thus the page will pass validation, while 99% of your users will enjoy your funky non-W3C CSS styles.

Fallback to valid CSS

What about the other 1%? They will only view your valid CSS since they do not have JavaScript enabled. So they have everything except your fancy styles. The actual layout of your page should be made with valid CSS.

This is not a new concept, it is used a lot for dynamic switching of CSS styles. However, the proposed application is for loading of non-W3C CSS content for extra formating in non-W3C compliant CSS browsers, while keeping all CSS layout styles in valid CSS for users without JavaScript.