Tuesday, January 22, 2008

Extending Native JavaScript Types breaks for in loop

I've read a few posts where JavaScript developers have been weighting different JavaScript libraries such as MooTools, Prototype, JQuery etc. based on their addition of methods to the native Types, such as Object, or Array.

The problem with extending native Types via prototyping is that the custom methods are iterated in the "for in loop".

And example is the best way to show this:

// extends the Native Object
Object.prototype.objMethod = function() {};
Object.prototype.objProperty = function() {};

// an instance of Object
var Obj = {
  myMethod: function() {},
  myProperty: ''
};

// iterate over the properties of Obj
for(var x in Obj) {
  alert(x + ' : ' + Obj[x]);
}

This will give you the result:
myMethod : function() {}
myProperty : 
objMethod : function() {}
objProperty  : 
Try It Notice that you not only iterated over the properties of Obj, but also the (user defined) properties Obj inherits from its constructor, Object.

Now, I've heard/seen a lot of developers complain about this. They have their nice "for in" loops that worked well before, and now they break. Before you start blogging about how bad it is to extend native Types, imagine what JavaScript would be like without it.

Javascript, a land dark and mysterious. Where constructors hide their evil prototype inherited methods from brave instances that must cross the __proto__ in order to see their true properties.
Ok, you get the picture...

A work around

The Object.hasOwnProperty() method differentiates between the properties of an Instance and those inherited from the Constructor.

Lets try our for in loop example again:

// extends the Native Object
Object.prototype.objMethod = function() {};
Object.prototype.objProperty = function() {};

// an instance of Object
var Obj = {
  myMethod: function() {},
  myProperty: ''
};

// iterate over the properties of Obj
for(var x in Obj) {
  if (Obj.hasOwnProperty(x))
    alert(x + ' : ' + Obj[x]);
}

Try It

Notice the new line I've added:

if (Obj.hasOwnProperty(x))
. Now I ask, would you rather be able to choose between inherited and non-inherited methods when iterating via a "for in loop", or not have the choice. I'd rather have that choice.

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.

Thursday, January 17, 2008

Server Side JavaScript with Appjet

Most web developers are familiar with JavaScript on the browser (client side). However, JavaScript can also be used as a platform for your server side development.

While researching the possibility/feasibility of using JS on the sever side, I came across a company called AppJet. They currently offer you the ability to develop a Server Side JavaScript application through their Web Based Editor.

The fun part is that you don't have to install anything on your end. Just start writing some JavaScript code an publish your application and its hosted on their servers ready for viewing.

Now if you're only familiar with working with JavaScript on the client side, you'll have to "bend your mind" a little. This implementation of JavaScript on the server is not an Event based model. It is a simple processing of the request data, and creating a response.

Building a simple application with AppJet

I spent a some time reading the Appject Documentation, and wrote a simple little application. The application is comprised of a single text field that takes a keyword. This keyword is then appended to the url of an RSS feed (Google News) and the URL resource is retrieved from the remote server. We then just display the retrieved RSS feed.

I called the web application GNewsSearch. You can view the Source Code here.

Evaluation of the AppJet Platform

The main problem with the AppJet platform is that you cannot deploy it on your own server.. yet. The application is remotely hosted on their server.

Ease of Development

The server environment is much simpler than the browser environment since you are developing for a single platform (not multiple browsers). JavaScript libraries developed for browser deployment, can be used on AppJet, provided you do not reference browser specific Object, methods or properties.

Persistent Storage

Every web development platform needs some form of persistent storage. Appject has the global object storage for this. This allows the storage of two types of Objects: StorableObject and StorableCollection. StorableObject is used for storing singular values and StorableCollection for a dictionary (associative array) values.

Persistent Storage Retrieval

Though not as robust as a relational database, data stored in StorableCollection can be filtered and sorted.

Session Management

There is no session management built into Appject (as far as I looked into their docs). However, this can be easily built using their response.setCookie() method and their Persistent Storage mechanism.

Overall Appjet is a quick and exciting way to develop small scale web based applications.

Open Source xHTML, CSS and JavaScript Web Development Tools

Your web development is limited just as much by the tools you use, as by your expertize. Imagine trying to build a house with just your bare hands?

It is very possible to do web development with just notepad.exe, and an ftp client. But doing so seriously handicaps you. Here are a few tips to get you going.

Open Source Web Development Tools

Firefox

If are using Internet Explorer as your browser, please switch to Firefox. Firefox has many extensions developed by Web Developers or Web Developers. The most indispensable one to date is Firebug.

Firebug

Firebug is all around the best client side web based development tool. It allows you to view and edit the source of your HTML, JavaScript and CSS directly on the web page, in real time. It has a JavaScript debugger, DOM viewer, HTTP Request/Response viewer and a lot of other nifty features.

You may also want to look at the other web development extensions provided for Firefox.

Aptana

Aptana is an open source IDE (code editor) built upon Eclipse. It supports Ruby on Rails, Adobe Air, IPhone among other development platforms. Up till now, I haven't found a better Open Source IDE for web developers.

Notepad++

Notepad++ is a drop in replacement for the default notepad.exe on Windows OS. It is also a syntax highlighter for many programming languages and has a built in file manager. This tool offers quick editing of your HTML, CSS, XML etc. if you don't want to waste time loading a full IDE.

WAMP Server

Apache, MySQL, PHP on Windows. If you're still doing your web development over FTP, its about time you worked on a local version of your web server. WAMP allows you to easily install an Apache Server, with PHP and MySQL pre-installed.

About On Web Development

This blog will serve a place for me to give my 2 cents on web development. This blog will mainly be on the LAMP architecture for the server side development and xHTML and CSS on the client side. It will also features much on JavaScript (AJAX) and maybe a bit on FLEX. :)