Archive for November, 2006

The Great MIME-Type Swindle

Sunday, November 19th, 2006

It’s a really old subject, but I haven’t said my piece on the XHTML 1.0 versus HTML 4.01 debate. While commenting on Roger Johansson’s blog, 456 Berea Street, I said a little bit about what I think. I figured I ought to go ahead and say my fill.

XHTML was supposed to be the death of HTML. HTML 4.01, until recently, was supposed to be the last iteration of HTML. I think XHTML is great. It allows the designer to implement bits of XML, should he want to. It also is very strict, requiring proper syntax where HTML didn’t. If there is something wrong with the code, the page should not render at all. This makes good syntax coding a requirement rather than a suggestion. However, the current implementation of most of the XHTML pages I know of is ideologically broken. The rest don’t work on Internet Explorer.

The comments I made assumed a little foreknowledge but basically say what I want to say here. However, I’ll go ahead and lay out my full argument here.

In 2000 when XHTML 1.0 was introduced, there was a need for backward compatibility since most browsers could not render real XHTML. That is, browsers were built to render HTML served as text/html. Sending XHTML as XML resulted in, I assume, an interpreted XML tree. So that adoption of XHTML would occur, it needed to work in browsers. So, the XHTML recommendation had guidelines in place of how to make XHTML work on HTML browsers. This wasn’t backward compatibility so much as a hack. It didn’t allow for any of the benefits of XHTML, though it succeeded in making pages written with XHTML syntax render on old browsers. So, the mime-type is the modern equivalent of DOCTYPE triggering quirksmode (which the Web Hypertext Application Technology Work Group embrace).

As far as hacks go, it worked. Like all transitional solutions, it was supposed to be dropped as browser support for XHTML grew. The problem is that Internet Explorer never supported it (even in version 7) and people opted to continue to send HTML-XHTML. Further, it seems, many people don’t realize that real XHTML requires the correct application/xhtml+xml mime-type being sent. This is something that must be set up on the server, as text/html is the default mime-type for sending .html documents on every web server I know of.

When XHTML is sent as text/html, it behaves differently than if it is sent correctly. XHTML sent as HTML is treated as tag soup, which means any optimized, light weight XML parsers aren’t used. Tag Soup XHTML doesn’t require strict use of CDATA elements and improper syntax doesn’t stop rendering of the page. The null closing tags are treated as broken attributes. While it still works, XHTML is ideologically broken if it is sent as text/html. People who suggest we ought to use XHTML to guarantee that fledgling designers pick up XHTML (which would require strict syntax) are suggesting that we use a broken implementation to uphold an ideal that is at odds with broken implementations (ignoring that an unforgiving markup language would cause most designers to give up out of irritation). It is hypocritical.

So, I see two choices that are ideologically sound. The first is to use XHTML and send it as application/xhtml+xml, Internet Explorer be damned. However, this is really not a good choice for most. Some would suggest content negotiation, but this is still a hack that requires a lot of extra thinking and planning (albeit a better one than sending XHTML as HTML). The second is to only use XHTML in specific instances where compatibility can be guaranteed.

Let me elaborate on the second choice. HTML 4.01 is a web standard. Anyone in the web standards group that always advocates XHTML over HTML on grounds that XHTML is better suited for use than HTML doesn’t understand what tools are for. HTML with a strict DOCTYPE can be validated, written semantically, and obsessed over as much as XHTML. HTML just allows the web designer to make the choice (and good designers will obsess over their markup no matter what).

HTML and XHTML are tools to solve a problem. Just like a screwdriver won’t help when a hammer is needed, XHTML is no good when HTML is needed. I’ll be specific. On pages where free-form user input is allowed, the potential for non-designers (and designers, too, for that matter) to enter bad markup is huge. In a real XHTML page, the user could easily break a page, preventing rendering. When using HTML, the page may no longer validate, but it will still render. In instances such as these HTML is a better tool than XHTML.

Web applications, however, are a different story. System requirements can be specified as they are on traditional applications (e.g. a browser that supports XHTML can be required). This means that no hacks need to be used. Since web applications generally use form elements to display and edit data, concerns over user input are drastically reduced. Most of the time, discreet data is required rather than free-flow data that one might find on, say, a comments page. So, data can be more accurately validated. When that data is inserted into an XHTML page, it’s far less likely to break the page. On a syntactical level, XHTML meshes well with programming languages. That is, the code must live up to certain standards. XHTML would help tie the front end to the back end. XHTML is a perfect tool for web applications.

So, ignoring all the common arguments about the dangers of using XHTML, the ideology of XHTML is broken if the page works in Internet Explorer 7 or below. Advocating the use of a broken technology is hypocritical when well written HTML 4.01 with a strict DOCTYPE is better suited for normal web usage. However, XHTML has a defined and useful place on the World Wide Web.

If you want another opinion, Maciej Stachowiak of Apple’s WebKit / Safari project weighs in with pretty much the same opinions I have.

Update: The Lachlan Hunt pointed out that I screwed up the XHTML MIME-type. I fixed the error.

Wikka Wiki Bread Crumbs

Friday, November 10th, 2006

Dan decided he wanted to set up a wiki to build content. I wasn’t involved in the process, but I got the job of making a bread crumbs script for the site.

Dan decided to use Wikka Wiki. When I asked why he didn’t use Media Wiki (the software that Wikipedia uses, which seems to be the de-facto standard), he said it required PHP 5, which our server doesn’t have. I guess that was a good-enough reason.

For all my niggles with Wikka Wiki, it is actually pretty standards compliant and has a cute name. The main issue with Wikka Wiki, which might be an issue with all wikis (I wouldn’t know since this is the first one I’ve ever coded on), is how it stores links from one page to another. It has a links table with a from_tag and to_tag. This is logical and works quite well until you try to do bread crumbs.

When you send a query to get every link that should go on a page, recursive links aren’t a problem. When you are trying to make a recursive function to get a bread crumb trail, it is quite annoying. Since Dan was in a hurry, he just did 10 left joins on the same table with a limit of one. That got the job done but didn’t always show a logical or short-route path to the current page. Dan decided that I was better at recursive functions and told me to work on it when I had time (except he calls them cookie crumbs instead of bread crumbs, which you’ll see in the code). After about 10 tries, I came up with the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function BuildCookieCrumbs2($page, $depth=0, $menu=array("CareerOpportunities","DefaultMenu","CurrentFrontPage")){
	if($depth > 10)
		return;
	if(in_array($page,$menu)){
		return $page;
	}
	$sql = "SELECT to_tag, from_tag FROM career_opportunities_links WHERE from_tag IN ('".implode("','",$menu)."')";
	$r = $this->Query("SET NAMES UTF8");
	$r = $this->Query($sql);
	$o = array();
	$f = array();
	while($row = mysql_fetch_assoc($r)){
		$o[] = $row["to_tag"];
		$f[] = $row["from_tag"];
	}
	if($ret = array_search($page,$o)){
		return $f[$ret].">".$o[$ret];
	}
	else{
		$ret = "";
		$bcc = $this->BuildCookieCrumbs2($page,$depth+1,$o);
		$ret .= $bcc;
		$tmp = explode(">",$ret);
		$sql = "SELECT FIND_IN_SET(from_tag,'".implode(",",$menu)."') as fis FROM career_opportunities_links WHERE from_tag IN ('".implode("','",$menu)."') AND to_tag = '".$tmp[0]."'";
		$r = $this->Query("SET NAMES UTF8");
		$r = $this->Query($sql);
		$row = mysql_fetch_assoc($r);
		$ret = $menu[$row["fis"]-1].">".$ret;
		if(in_array($page,$tmp)){
			return $ret;
		}
	}
	return $ret;
}
function BuildCookieCrumbs($page) {
	$ret = $this->BuildCookieCrumbs2($page);
	$ret = explode(">",$ret);
	unset($ret[0]);
	return array_values($ret);
}

These two functions can be dropped into the Wakka.class.php file. I have no idea how to call it and put it into the template, as that part was already done when I started working on it. Sending the current page will return an array of tags to use in the bread crumb trail. You’ll probably want to change the default menu array in the BuildCookieCrumbs2, as it is set up to reflect our site.

This may not be the best solution, but it works pretty well.

Browser Tools for Web Designers

Tuesday, November 7th, 2006

I told Kathryn that I had a few browser tools for Macs she should check out for web design. I decided to make a post about it instead.

Make Safari Better

I really prefer to work in Safari on a Mac. Firefox, frankly, is slow as hell. The problem is that Safari, like most of Apple’s software, is simplified for general use. Out-of-the-box, it lacks a lot of features that even Internet Explorer have. The qualifier there is out-of-the-box.

Debugging JavaScript

While it doesn’t feel as robust as Firefox’s JavaScript debugger, Safari ships with one hidden away. One of the first things I do with a fresh install of Safari is turn on the Debug menu. To turn it on, open Terminal and enter defaults write com.apple.Safari IncludeDebugMenu 1 and press enter. The next time you launch Safari, the Debug menu will appear. Make sure Log JavaScript Exceptions is checked, then open the JavaScript Console from the Debug menu (or press command + shift + j).

The interface is very minimal. At first blush, it seems to be lacking compared to Firefox’s console. After you use it some, you’ll find that it is as good as Firefox when it comes to picking up, identifying, and finding errors in your code.

Safari Tidy

The other tool I find quite helpful is Safari Tidy. Safari Tidy is a plugin for Safari that runs every page you browse through HTML Tidy. HTML Tidy helps to find any errors in your HTML. While it isn’t a validator, it does a pretty good job of identifying problems.

Safari Tidy puts a simple message in the bottom right side of the status bar in Safari. It may say 0 errors / 2 warnings. This tells the developer that there are three potential problems in the code. Double clicking the message will bring up a modified view source window that displays the errors. By double clicking an error in the view source window, the line with the problem is highlighted. Identifying errors is much quicker this way.

Make Firefox Better

Firefox is already a great browser for developers. The JavaScript debugger is top notch and it has a built-in DOM inspector. However, I’ve found one extension that I can’t live without: The Web Developer Toolbar.

The Web Development Toolbar

This toolbar adds a lot of functionality by allowing web designers to see tons of information about what is in the HTML. It has too many features to list all of them, but I’ll list the ones I use the most (which aren’t necessarily the most helpful).

  1. JavaScript Error Notification

    In the far left of the tool bar, there is a small info icon. When a JavaScript error is encountered, it turns into a red icon. Clicking it will show the JavaScript Error Console. This at-a-glance error notification is the feature I use the most.

  2. Validate Local HTML

    Under the tools menu, there is an option to run the current page through the World Wide Web Consortium’s validator as a local file. The source is submitted as a file, which allows any page to be validated. To boot, they have assigned a key combo to do this quickly in a new tab. There is also options to validate local style sheets, as well as regular validation options.

  3. Resize Window

    This sounds pretty silly, but there is no way to accurately resize a browser window without JavaScript or a tool bar. This one includes resizing to 800×600 as well as custom values.

There are tons of other features packed into this tool bar. The features I use most don’t accurately represent how powerful it is.

FireBug

FireBug is a great extension that is very useful in certain situations. While I don’t use it every day, FireBug is very powerful. It exposes the HTML on the page at a given time. That means any changes to the DOM are accounted for in the source view.

What makes FireBug great is that you can then live edit the HTML and CSS. The browser updates as you type. FireBug won’t let you save your work, but it does allow for rapid debugging without impacting the actual files. Basically, you can experiment with various ideas to debug your layout without having to deal with backups or limited undos. Once you figure out your issue, you can copy and paste the updates to live files.

Got Any Suggestions?

Do you have any browser add-ons for web designers or developers that you can’t live without? Let me know!