Site-relative links with Drupal 4.7+

Versions of Drupal before 4.7 included a <base> in the header that pointed to the top-level URL for the site. On this site, for example, it would have looked like:

<base href="http://jaspan.com/">

The advantage of this tag is that it allowed site-relative links to work from any page on the site. For example, suppose I post a story whose teaser contains a link to another story on my site:

This article is a followup to <a href="flying_monkeys">
my previous article on flying monkeys</a>...

Under 4.6, if this teaser happened to show up while viewing the Drupal path taxonomy/term/36, the <base> tag let the browser know that the link was actually to the URL http://jaspan.com/flying_monkeys and not to the URL http://jaspan.com/taxonomy/term/flying_monkeys.

The <base> tag is no longer included in Drupal 4.7 and newer. I'm sure there were good reasons to remove it (though I've never looked into what they are), but its lack of presence causes quite a quandary. Without the tag, the Web browser has no way to know the correct base path for a site-relative link, so in the example above it would end up pointing to http://jaspan.com/taxonomy/term/flying_monkeys. A normal user can work around this problem only by hard coding an absolute URL but that will break if the site ever moves. An administrator can work around the problem by embedding PHP into the page (e.g. <?php print l('my previous article on flying monkeys', 'flying_monkeys') ?>) but that is a pain in the butt and requires that the page use the PHP Code input format which is often undesirable (I prefer to use Filtered HTML or Markdown as often as possible to keep things simple).

To correct this problem, I wrote a simple input filter:

function site_relative_filter_tips($delta, $format, $long) {
  return site_relative_filter('tip', $delta, $format, $long);
}
function site_relative_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
  case 'list':
    return array(t('Site-relative links filter'));
   
  case 'no cache':
    return 0;
   
  case 'description':
  case 'tip':
    return t('Site-relative links such as &lt;a href="node/123"&gt; will work correctly.');
   
  case 'process':
    $text =
      preg_replace_callback('@(<(?:a|img)\s*[^>]*(?:href|src)=")'.
    '((?:[^/#][-a-z0-9_./ ]*)?)'.
    '("[^>]*>)@i',
    create_function
    ('$m',
     'return $m[1].url($m[2]).$m[3];'),
    $text);
    return $text;
   
  case 'settings':
    return;
   
  default:
    return $text;
  }
}

The filter searches for anchor and image tags with site relative URLs and replaces them with the output of the Drupal url() function which provides the correct site-absolute URL. With this filter in place and added to whatever input format I am using, a site-relative link such as the one shown above always ends up pointing to the right place no matter what Drupal path it is viewed from.

Do other people have this problem? I can't believe I'm the only one. It is a very small piece of code, but I'm happy to contribute it as a module if asked.