Skip to the Main Content

Note:These pages make extensive use of the latest XHTML and CSS Standards. They ought to look great in any standards-compliant modern browser. Unfortunately, they will probably look horrible in older browsers, like Netscape 4.x and IE 4.x. Moreover, many posts use MathML, which is, currently only supported in Mozilla. My best suggestion (and you will thank me when surfing an ever-increasing number of sites on the web which have been crafted to use the new standards) is to upgrade to the latest version of your browser. If that's not possible, consider moving to the Standards-compliant and open-source Mozilla browser.

May 26, 2003

Serve it Up!

For the fourth in my series of MT How-To articles, I’ll focus on serving your blog as XHTML 1.1, with Content-Type of application/xhtml+xml. Why would you want to do such a thing? Well, my reason is that I want to be able to serve embedded MathML content. You may have a similar practical reason. Or you may just enjoy following the W3C’s recommendations. I’ll assume, for the purposes of this article, that you’re interested in MathML or SVG content because that is — to my mind — the most compelling current application.

Before we plunge in, it would be wise to make sure your pages are valid XHTML 1.1 (and I mean all your pages — your individual archive pages, your Comment-Listing popup, your Search Results page, … — validate them all!). And you should follow the advice in my previous articles (I, II) about bullet-proofing your content, so that what’s valid today stays valid tomorrow.

So, where to start? We’re going to use mod_rewrite to set the MIME-type of your static pages. Some people use PHP for this, but mod_rewrite seems more reasonable, as you can set the MIME-type of anything from an entire web site to a single file by editing one configuration file (either .htaccess, or your server configuation file; the latter yields higher performance, but requires restarting the server everytime you make a change). And we’re going to use the USER_AGENT string to decide what MIME-type to send. Some people use the ACCEPT header, but I’ve found that some browser which say they can handle application/xhtml+xml will actually choke if you send them MathML with that Content-Type. So I want to choose explicitly which browsers to send application/xhtml+xml

Without further ado, here are the mod_rewrite rules

RewriteEngine On
RewriteBase /~distler/blog/
RewriteRule ^$ index.shtml
RewriteCond  %{HTTP_USER_AGENT} Gecko|W3C.*Validator|MSIE.*MathPlayer
RewriteRule \.html$|\.shtml$   - [T=application/xhtml+xml]
RewriteCond  %{HTTP_USER_AGENT} Chimera|Camino|KHTML
RewriteRule \.html$|\.shtml$   - [T=text/html]
RewriteCond  %{HTTP_USER_AGENT} Camino.*MathML-Enabled
RewriteRule \.html$|\.shtml   - [T=application/xhtml+xml]

The RewriteBase is the URL of your blog (everything after the hostname). All browsers with “Gecko” in the USER_AGENT, except Safari and Camino get sent application/xhtml+xml. So do the W3C Validators. Everybody else gets text/html.

That takes care of all our static pages. For CGI-generated pages (produced by mt-comments.cgi and mt-search.cgi), we need to be a bit cleverer. The trick we’ll use is to set an environment variable.

First, we’ll ever-so-gently patch lib/MT/

--- lib/MT/  Tue Mar 25 11:09:03 2003
+++ lib/MT/       Tue Mar 25 11:10:38 2003
@@ -52,6 +52,9 @@
 sub send_http_header {
     my $app = shift;
     my($type) = @_;
+    if ($ENV{'HTTP_CONTENT_TYPE'}){
+      $type= $ENV{'HTTP_CONTENT_TYPE'};
+    }
     $type ||= 'text/html';
     if (my $charset = $app->{charset}) {
         $type .= "; charset=$charset"

Then we’ll use mod_rewrite again to set the environment variable (n. b., the name of the environment variable was specially chosen for compatibility with suEXEC. Thanks to Jacob Childress for pointing out the difficulty with an earlier version of this hint.)

RewriteEngine On
RewriteBase /cgi-bin/MT-2.5
RewriteCond  %{HTTP_USER_AGENT} Gecko|W3C.*Validator|MSIE.*MathPlayer
RewriteRule ^mt-comments|^mt-search   - [E=HTTP_CONTENT_TYPE:application/xhtml+xml]
RewriteCond  %{HTTP_USER_AGENT} Chimera|Camino|KHTML
RewriteRule ^mt-comments|^mt-search   - [E=HTTP_CONTENT_TYPE:text/html]
RewriteCond  %{HTTP_USER_AGENT} Camino.*MathML-Enabled
RewriteRule ^mt-comments|mt-search   - [E=HTTP_CONTENT_TYPE:application/xhtml+xml]

Now those CGI-generated pages will be sent out with the right Content-Type, too. That’s very handy, especially if you’re going to give people the option of leaving comments using itexToMML. Now they’ll actually be able to preview them!

One drawback of this approach comes if you have multiple blogs sharing a common MovableType installation, and you want to send some as application/xhtml+xml and some as text/html. There’s no problem with the static pages, but the /cgi-bin/ directory is shared between the different blogs. The most straightforward approach is to create a hard-link to mt-comment.cgi and mt-search.cgi in the user’s blog directory, and then use the mod_rewrite rules there. If you do that, you need to set the value of the $MT_DIR variable in those two cgi scripts “by hand”. Something like

$MT_DIR = '/my/mt/directory/';

(Thanks, again, to Jacob Childress, who’s implemented this particular solution on his site.)

Yuan-Chung Cheng has a different approach to setting the Content-Type in the context of a shared MovableType installation. He also has some cool things to say about using UTF-8 in this context. If you’re using UTF-8, you probably want to set

NoHTMLEntities 1

in mt.cfg. But, if you do, it will totally mess with any HTML entities in your Comment-editing form on your Comment Preview page. Yuan-Chung has figured out the solution, which he explains in more detail here. Definitely not for the faint of heart, but if you gotta have Traditional Chinese and MathML in the same blog, this is the only way to go.

If you’ve come this far, you’ll notice that the rememberMe javascript on your Comment-entry form has just broken. There are three problems.

  1. For historical reasons, the javascript code supplied in MovableType is wrapped in an HTML comment

    <script type="text/javascript" >
    When served application/xhtml+xml, Mozilla will studiously ignore the contents of HTML comments. You need to uncomment the script to make it work. This holds for all the javascript on your blog.
  2. The script itself needs to be updated for XHTML compatibility. Look at the javascript in my Comment-Listing Template to see how to do it right.
  3. Even after all of this, you’ll need a recent version of Mozilla for cookies to work with application/xhtml+xml.

Well, that’s it. You should be up and running with application/xhtml+xml! Down the road, you may have to adjust your mod_rewrite rules, as new browsers become MathML-capable (MathML support in Camino is coming soon). But, for now, these’ll do.

Update (6/7/2003): Tweaked mod_rewrite rules to support OmniWeb 4.5

Update (8/31/2003): Set the MIME type sent to the W3C Validators to application/xhtml+xml as well. That way, they see the page as it “should” be seen.

Update (10/20/2003): Send application/xhtml+xml to Dave Haas’s MathML-enabled builds of Camino.

Update (2/16/2004): Add support for Mathplayer 2.0.

Posted by distler at May 26, 2003 1:25 AM

TrackBack URL for this Entry:

15 Comments & 10 Trackbacks

Re: Serve it Up!

Very helpful indeed. I actually threw out the rememberMe Javascript code when I made the move to XHTML, but maybe I’ll work it back in to my site.

I had forgotten to mention it when discussing this topic with you before, but of course you’ll also need to create a hard link to mt-tb.cgi if your situation is like mine.

Posted by: jacob on May 29, 2003 2:28 PM | Permalink | Reply to this


Good point. Since I use MT-SimpleComments, it slipped my mind that the “default” installation uses mt-tb.cgi to generate trackback listings (in addition to its function of receiving trackback pings). So, if you’re in that situation, you want to apply the same techniques to mt-tb.cgi as well.


Posted by: Jacques Distler on May 30, 2003 10:15 PM | Permalink | Reply to this

Re: Serve it Up!

Hmnmm.. We’ll give it a try here. However, the “historical reasons” for ignoring javascript as it’s commented are to be considered… How far does ‘historical’ goes?
Too much forward compatibilty w/o looking back?

Posted by: escuela de multimedia on June 18, 2003 12:01 AM | Permalink | Reply to this

Re: Serve it Up!

To elaborate: really old browsers do not recognize the <script>...</script> element and will therefore attempt to render the contents. Such browsers are extemely rarely used nowadays and I’m sure this is far from the only problem such a browser would have with XHTML.

If you really want to support such browsers, you can always load your javascripts from an external file. But I think it would be more worthwhile to persuade the three remaining people using these browsers to upgrade.

Posted by: Jacques Distler on June 18, 2003 12:26 AM | Permalink | Reply to this
Read the post HowTo: MT Individual Entry Archive
Excerpt: Inspired by this post, I set out to convert my Individual Entry Archive pages to XHTML 1.1 from the default XHTML 1.0 Transitional. This is something that I'd tried and failed at before, due to my noobishness with JavaScript and...
Tracked: September 2, 2003 6:29 PM
Read the post What You Should Know about XHTML 1.1
Weblog: Dewayne Mikkelson and his Radio WebDog, Shadow
Excerpt: Source: Anne van Kesteren's weblog has been home lately to a few fantastic posts related to important differences between XHTML 1.0 Strict and XHTML 1.1.
Tracked: September 7, 2003 6:28 PM
Read the post About XHTML
Excerpt: Serving XHTML with the Right MIME Type Media types summary for serving XHTML documents by W3C What You Should...
Tracked: September 10, 2003 5:29 PM
Read the post Time to convert to XHTML 1.1
Weblog: Eclectic Echoes
Excerpt: After the New York trip, I think it will be time to change the site over from XHTML(eXtensible Hypertext Markup Language) 1.0 Transitional to XHTML 1.1. The changes should be limited, mostly changing the javascript and form areas. The main area's right...
Tracked: January 13, 2004 3:46 PM

Re: Serve it Up!

This is a bit off topic but I am in desperate search for an answer. I have formated my page elements (i.e. doctype, xml tags, etc.) to the MathML types and requirements to get MathML to render properly. However, whenever I view the documents the MathML portion appears as plain text.


Look at this source and see if you can decypher what exactly is going on. It appears all the formatting for the MathML tags is setup properly: possibly something is overwritting this formatting? Any help would be GREATLY appreciated (I’ve spent 2 hours researching and have got no further than when I started!)


John Wyles

Posted by: John Wyles on January 28, 2004 2:08 AM | Permalink | Reply to this

That’s bad?

Your page is currently being served as text/html, instead of application/xhtml+xml.

On the one had that’s bad: Mozilla won’t render the MathML unless the page is served up with the correct MIME type.

On the other hand, it’s good, since the page is not well-formed XHTML, which means that if you sent it with the correct MIME type, Mozilla would not render it at all.

Correct your XHTML errors, send out the correct MIME type, and all will be well.

Posted by: Jacques Distler on January 28, 2004 2:23 AM | Permalink | Reply to this

Re: Serve it Up!

I have a blog with XHTML 1.1 and I have tried employing your Mathenable feature and I keep getting the same error code default #F3423 substring expected could I be applying it incorrectly as maybe my lib/mt/app is a different library version.

Posted by: Sony Cybershot on December 20, 2004 4:33 PM | Permalink | Reply to this
Read the post New Look, XHTML 1.1 and MathML
Weblog: Procrastination
Excerpt: You might have noticed the new look of this weblog. It all started due to Asif and Jacques Distler. Asif just started using LaTeX formulae on his weblog and Jacques has been doing so for quite a while. Asif is...
Tracked: January 9, 2005 11:19 PM

Re: Serve it Up!

I can’t get the mod_rewrite rules to work for non-cgi files. Firefox shows (in Page Info) the web pages as text/html. I know the ReWriteConds are working because if I change the rule to redirecting to another file, that works. Any idea what could be wrong?

Posted by: Zack on January 11, 2005 5:16 PM | Permalink | PGP Sig | Reply to this

Re: Serve it Up!

Never mind. I had forgotten the xml declaration at the top on the individual entry template.

Posted by: Zack on January 11, 2005 5:40 PM | Permalink | PGP Sig | Reply to this
Read the post Front-end and Back-end Changes
Weblog: Procrastination
Excerpt: There have been a lot of changes here recently, most of them on the back-end. Most of this work was related to having a bilingual (English and Urdu) blog along with MathML equations. This required valid XHTML 1.1 and serving...
Tracked: February 11, 2005 8:26 AM

Re: Serve it Up!

I use XHTML too and it is great!

Posted by: Elodie on February 19, 2005 7:09 AM | Permalink | Reply to this

Re: Serve it Up!

Ah the quest for MathML webpages. I’m finally at the point where everything is valid, you have to preview comments, you can use iTeX2MML in comments, everything is validated before you submit anything, etc. For some reason, though mod_rewrite doesn’t want to set the mime type. The static pages I can set via php, which is my current setup, but the cgi wants to stay text … very frustrating…

Posted by: Brian on September 16, 2005 12:21 PM | Permalink | Reply to this
Read the post Are You Being Served? -- Part I
Weblog: Upon Reflection
Excerpt: For about a year I have been working on ways to integrate mathematics into this weblog.
Tracked: September 23, 2005 4:19 PM
Read the post New Look, XHTML 1.1 and MathML
Weblog: Procrastination
Excerpt: You might have noticed the new look of this weblog. It all started due to Asif and Jacques Distler. Asif just started using LaTeX formulae on his weblog and Jacques has been doing so for quite a while. Asif is...
Tracked: March 14, 2007 7:41 AM

Re: Serve it Up!

Jacques, considering the major browsers that are being used today, do you still recommend using application/xhtml+xml?

If I don’t do that, is there any chance that pages won’t render correctly?

Thanks a lot,

Posted by: Jerome Verger on May 13, 2007 10:45 PM | Permalink | Reply to this

Re: Serve it Up!

Jacques, I’ve been working on a side project that involves auto XHTML error checking and debugging. Even considering it’s age, this article/site has been a resource. Thanks.

Posted by: Marc on May 16, 2007 2:56 PM | Permalink | Reply to this
Read the post Blosxom: Less is More
Weblog: Jason Blevins
Excerpt: Blosxom, a lightweight weblog program written in Perl, is a minimalist's paradise. It embodies elegant simplicity both in terms of design and implementation. The version 2 core weig
Tracked: January 22, 2008 1:47 PM

Re: Serve it Up!

I made a translation of this post for the dutch learn wiki. In case this is not in line with your policy, please let me know.
Open Source Pioneer
Dutch tutorial wiki

Posted by: Bob on January 25, 2008 9:27 AM | Permalink | Reply to this
Read the post Are You Being Served?
Weblog: Upon Reflection
Excerpt: This is a summary of the process of going from a standard Movable Type installation to a fully functional, math-friendly website. It can be done, and you don't have to be a code-jockey, but it is not for the timid....
Tracked: August 28, 2008 1:37 PM

Re: Serve it Up!

Very good article. I was wondering if i can make a one on one translation for my own howto section at Beginners Informatie.

I can make a copyright with your credentials if that’s okay with you.

Posted by: John on February 12, 2009 4:30 PM | Permalink | Reply to this

Post a New Comment