This weblog is no longer being maintained. All information here has been ported to EclecticEchoes.com. This site (heupel.com/eclectic) remains only for archival purposes.
Just a place holder for when this gets implemented here:
I serve all these pages through PHP (using DefaultType application/x-httpd-php in the .htaccess file. I was looking for a way to deliver XHTML1.0 Strict or XHTML 1.1 documents using the correct mime type when possible, yet still serving something to brain-dead browsers. I tested a couple of solutions, but in most cases it failed miserably in IE one way or another. Fortunately, I stumbled across a solution using PHP to not only switch the content mime type, but also serve up an appropriate prolog, based on the HTTP_ACCEPT string of the requesting agent. I modified the solution a bit, mainly simplifying it and then adding support for the W3C Validator. This setup serves modern browsers—and the main validators— XHTML 1.1 pages as application/xhtml+xml and falls back to serving the same pages as XHTML 1.0 Transitional with a text/html content type for legacy and brain-dead browsers. I could have dropped all the way to an HTML 4.x doctype, but why?
.htaccess changes:
AddType application/x-httpd-php .html .htm .php .shtml
DefaultType application/x-httpd-php
php_value auto_prepend_file /home/www/c_mime.php
/home/www/c_mime.php’s contents:
<?php
$charset = "UTF-8";
$mime = "text/html";
if(stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml")||
stristr($_SERVER["HTTP_USER_AGENT"],"Validator")) {
$mime = "application/xhtml+xml";
$prolog_type = "<?xml version=\"1.0\" encoding=\"$charset\" ?>\n
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n
<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n";
} else {
$prolog_type = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0
Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n
<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
}
header("Content-Type: $mime;charset=$charset");
print $prolog_type;
?>
Tested lightly, any suggestions welcomed. I can’t recall where I found the original code, to be able to give fair credit… I know it wasn’t Anne van Kesteren but I did notice in a short search for the origial source that she has a similar solution (hers does a bit more browser sniffing and doesn’t send the prolog dynamically) If anyone knows a good reason not to do it this way let me know…
I’ve seen some PHP scripts which attempt to ‘downgrade’ an XHTML 1.1 document all the way to HTML 4, with a few regexp search and replaces. As you can imagine, these scripts suck rocks. If you’re going to do something like that, use server-side XSLT.
Backing off to XHTML 1.0 Transitional is a bit better. You only have to change the prolog, if your document uses nothing beyond what’s in XHTML 1.0.
But there’s something surreal about going to the trouble of changing the DOCTYPE declaration (and none of the body of the document) for a browser that’s just going to parse your document as tag-soup anyway.
Yes, I know know you’re not supposed to send XHTML 1.1 as text/html. But you are sending the same frigging document all the same. All you’ve done is change the DOCTYPE (to another compatible one).
Well … almost. You did remove the XML PI in the XHTML 1.0 version, which would have caused IE to go into quirks mode.
That’s a good reason to go to this trouble, though it could be done with less code.
On the other hand, you included the lang=”” attribute in the XHTML 1.1 version, which is invalid.
Surreal ain’t the word. Truth be told I was cussing up a storm while failing to get the .htaccess rewrites to work. Part of the problem is that I am using PHP and don’t have control over enabling or disabling PHP’s short tags (<?) feature. The XML PI instantly causes a problem with PHP parsing. This may be surreal but it is consistent and predictable, as long as the site is written XHTML 1.x validable, it just works. Of course for your MathML needs it would be extremely ugly.
You’re right about the lang attribute, which I caught right after I posted the entry. Thanks for reminding me to edit the code above!
You’re right it is sending the same frellin’ document everytime, but that seems to be life with the browser that must not be named and “new” standards. Again in honesty half the problem here is PHP’s shorttags which could be remedied by placing the PI and DOCTYPE in the page itself and using [php] 'print "<?xml version="1.0" encoding="UTF-8"?>' to correctly pass the PI through the PHP parser, but then that would end up with IE always in quirks mode, which I find less predictable.
You are welcome to use the script I have outlined here: http://keystonewebsites.com/articles/mime_type.php