diff --git a/domain.admin.inc b/domain.admin.inc
index a91e96a..603e791 100644
--- a/domain.admin.inc
+++ b/domain.admin.inc
@@ -349,14 +349,7 @@ function domain_configure_form($form, &$form_state, $user_submitted = FALSE) {
     '#collapsed' => TRUE
   );
   // Get the available tokens.
-  $prefixes = array('current-domain', 'default-domain');
-  module_load_include('inc', 'domain', 'domain.tokens');
-  $info = domain_token_info();
-  foreach($prefixes as $prefix) {
-    foreach($info['tokens']['domain'] as $token => $data) {
-      $tokens[] = t('!token : !description', array('!token' => "[$prefix:$token]", '!description' => $data['description']));
-    }
-  }
+  $tokens = domain_get_tokens();
   $form['domain_classes']['domain_classes'] = array(
     '#type' => 'textarea',
     '#rows' => 5,
diff --git a/domain.module b/domain.module
index c740105..b8f00df 100644
--- a/domain.module
+++ b/domain.module
@@ -3490,3 +3490,109 @@ function domain_page_classes() {
   }
   return $classes;
 }
+
+/**
+ * Implements hook_filter_info().
+ */
+function domain_filter_info() {
+  $filters['domain'] = array(
+    'title' => t('Insert domain-specific placeholders'), 
+    'description' => t('Allows you to add domain-sensitive variables to content.'), 
+    'process callback' => 'domain_filter_process',
+    'tips callback' => 'domain_filter_tips',
+    'cache' => FALSE, // These cannot be cached.
+    'weight' => 0,
+  );
+  $filters['domain_url'] = array(
+    'title' => t('Insert domain-sensitive URLs'), 
+    'process callback' => 'domain_url_filter_process',
+    'tips callback' => 'domain_url_filter_tips',
+    'cache' => FALSE, // These cannot be cached.
+    'weight' => -10,
+  );
+  return $filters;
+}
+
+/**
+ * Implements hook_filter_FILTER_tips() magic callback.
+ */
+function domain_filter_tips($filter, $format, $long) {
+  $tokens = domain_get_tokens();
+  if ($long) {
+    return t('The following site-specific token replacements are allowed: !tokens', array('!tokens' => theme('item_list', array('items' => $tokens))));
+  }
+  else {
+    $fieldset = array(
+      '#collapsed' => TRUE,
+      '#collapsible' => TRUE,
+      '#title' => t('Domain tokens'),
+      '#children' => theme('item_list', array('items' => $tokens)),
+    );
+    return t('The following site-specific token replacements are allowed: !tokens', array('!tokens' => theme('fieldset', array('element' => $fieldset))));
+  }
+}
+
+/**
+ * Implements hook_filter_FILTER_process() magic callback.
+ */
+function domain_filter_process($text, $filter, $format, $langcode, $cache, $cache_id) {
+  $tokens = domain_get_tokens();
+  $patterns = array_keys($tokens);
+  foreach ($patterns as $pattern) {
+    $match = "[$pattern]";
+    $text = preg_replace(preg_quote("/$match/"), token_replace($match), $text);
+  }
+  return $text;
+}
+
+/**
+ * Returns all domain module tokens in a human-readable array.
+ *
+ * The array key is the token string (without brackets) and the value is the
+ * token string : description.
+ *
+ * @return
+ *  An array of token data formatted as explained above.
+ */
+function domain_get_tokens($prefixes = array()) {
+  if (empty($prefixes)) {
+    $prefixes = array('current-domain', 'default-domain');
+  }
+  module_load_include('inc', 'domain', 'domain.tokens');
+  $info = domain_token_info();
+  foreach($prefixes as $prefix) {
+    foreach($info['tokens']['domain'] as $token => $data) {
+      $tokens["$prefix:$token"] = t('!token : !description', array('!token' => "[$prefix:$token]", '!description' => $data['description']));
+    }
+  }
+  return $tokens;
+}
+
+/**
+ * Implements hook_filter_FILTER_process() magic callback.
+ */
+function domain_url_filter_process($text, $filter, $format, $langcode, $cache, $cache_id) {
+  $pattern = '/\[domain:(.+?)\]/';
+  $text = preg_replace_callback($pattern, 'domain_url_replace', $text);
+  return $text;
+}
+
+/**
+ * Processes pattern matches for the url filter.
+ *
+ * @param $matches
+ *  An array of matching elements. Item 1 is the path string.
+ *
+ * @return
+ *  A Drupal-processed url string.
+ */
+function domain_url_replace($matches) {
+  return url($matches[1]);
+}
+
+/**
+ * Implements hook_filter_FILTER_tips() magic callback.
+ */
+function domain_url_filter_tips($filter, $format, $long) {
+  return t('Enter a relative URL in the format <em>[domain:path/to/item]</em> to make the URL link to the canonical path.');
+}
diff --git a/domain.tokens.inc b/domain.tokens.inc
index 876dac2..a5234a6 100644
--- a/domain.tokens.inc
+++ b/domain.tokens.inc
@@ -35,6 +35,10 @@ function domain_token_info() {
     'name' => t('Domain machine name'),
     'description' => t('The domain machine identifier.'),
   );
+  $info['tokens']['domain']['path'] = array(
+    'name' => t('Domain path'),
+    'description' => t('The base url path for the domain.'),
+  );
   $info['tokens']['domain']['name'] = array(
     'name' => t('Domain name'),
     'description' => t('The domain name.'),
@@ -72,6 +76,9 @@ function domain_tokens($type, $tokens, array $data = array(), array $options = a
         case 'name':
           $replacements[$original] = $sanitize ? check_plain($domain['sitename']) : $domain['sitename'];
           break;
+        case 'path':
+          $replacements[$original] = $domain['path'];
+          break;
         case 'url':
           $url = domain_url_encode($domain['subdomain']);
           $replacements[$original] = $sanitize ? check_plain($url) : $url;
