diff --git includes/VersioncontrolRepository.php includes/VersioncontrolRepository.php
index 7482a9c..a42ffe9 100644
--- includes/VersioncontrolRepository.php
+++ includes/VersioncontrolRepository.php
@@ -99,7 +99,7 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
    * The current plugin types(array keys) are:
    * - author_mapper
    * - committer_mapper
-   * - auth_handler
+   * - webviewer_url_handler
    *
    * @var array
    */
@@ -366,24 +366,24 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
    * Convinience method to retrieve url handler.
    */
   public function getUrlHandler() {
-    if (!isset($this->data['versioncontrol']['url_handler'])) {
-      $this->data['versioncontrol']['url_handler'] =
-        new VersioncontrolRepositoryUrlHandler(
-          $this, VersioncontrolRepositoryUrlHandler::getEmpty()
-        );
+    if (!isset($this->pluginInstances['webviewer_url_handler'])) {
+      $plugin = $this->getPlugin('webviewer_url_handler', 'webviewer_url_handlers');
+      $class_name = ctools_plugin_get_class($plugin, 'handler');
+      if (!class_exists($class_name)) {
+        throw new Exception("Plugin '{$this->plugins['webviewer_url_handler']}' of type 'webviewer_url_handlers' does not contain a valid class name in handler slot 'handler'", E_WARNING);
+        return FALSE;
+      }
+      $this->pluginInstances['webviewer_url_handler'] = new $class_name(
+        $this, $this->data['webviewer_base_url'], $plugin['url_templates']
+      );
     }
-    return $this->data['versioncontrol']['url_handler'];
+    return $this->pluginInstances['webviewer_url_handler'];
   }
 
   /**
-   * Get an instantiated plugin object based on a requested plugin slot, and the
-   * plugin this repository object has assigned to that slot.
-   *
-   * Internal function - other methods should provide a nicer public-facing
-   * interface. This method exists primarily to reduce code duplication involved
-   * in ensuring error handling and sound loading of the plugin.
+   * Get a ctools plugin based on plugin slot passed.
    */
-  protected function getPluginClass($plugin_slot, $plugin_type, $class_type) {
+  protected function getPlugin($plugin_slot, $plugin_type) {
     ctools_include('plugins');
 
     if (empty($this->plugins[$plugin_slot])) {
@@ -398,9 +398,23 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
       return FALSE;
     }
 
+    return $plugin;
+  }
+
+  /**
+   * Get an instantiated plugin object based on a requested plugin slot, and the
+   * plugin this repository object has assigned to that slot.
+   *
+   * Internal function - other methods should provide a nicer public-facing
+   * interface. This method exists primarily to reduce code duplication involved
+   * in ensuring error handling and sound loading of the plugin.
+   */
+  protected function getPluginClass($plugin_slot, $plugin_type, $class_type) {
+    $plugin = $this->getPlugin($plugin_slot, $plugin_type);
+
     $class_name = ctools_plugin_get_class($plugin, $class_type);
     if (!class_exists($class_name)) {
-      throw new Exception("Plugin '$plugin_name' of type '$plugin_type' does not contain a valid class name in handler slot '$class_type'", E_WARNING);
+      throw new Exception("Plugin '$plugin_slot' of type '$plugin_type' does not contain a valid class name in handler slot '$class_type'", E_WARNING);
       return FALSE;
     }
 
@@ -448,231 +462,3 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
   }
 
 }
-
-/**
- * Contains the urls mainly for displaying.
- */
-class VersioncontrolRepositoryUrlHandler {
-
-  /**
-   * Repository where this urls belongs.
-   *
-   * @var    VersioncontrolRepository
-   */
-  public $repository;
-
-  /**
-   * An array of repository viewer URLs.
-   *
-   * @var    array
-   */
-  public $urls;
-
-  public function __construct($repository, $urls) {
-    $this->repository = $repository;
-    $this->urls = $urls;
-  }
-
-  /**
-   * Explain and return and empty array of urls data member.
-   */
-  public static function getEmpty() {
-    return array(
-      /**
-       * The URL of the repository viewer that displays a given commit in the
-       * repository. "%revision" is used as placeholder for the
-       * revision/commit/changeset identifier.
-       */
-      'commit_view'    => '',
-      /**
-       * The URL of the repository viewer that displays the commit log of a
-       * given file in the repository. "%path" is used as placeholder for the
-       * file path, "%revision" will be replaced by the file-level revision
-       * (the one in {versioncontrol_item_revisions}.revision), and "%branch"
-       * will be replaced by the branch name that the file is on.
-       */
-      'file_log_view'  => '',
-      /**
-       * The URL of the repository viewer that displays the contents of a given
-       * file in the repository. "%path" is used as placeholder for the file
-       * path, "%revision" will be replaced by the file-level revision (the one
-       * in {versioncontrol_item_revisions}.revision), and "%branch" will be
-       * replaced by the branch name that the file is on.
-       */
-      'file_view'      => '',
-      /**
-       * The URL of the repository viewer that displays the contents of a given
-       * directory in the repository. "%path" is used as placeholder for the
-       * directory path, "%revision" will be replaced by the file-level revision
-       * (the one in {versioncontrol_item_revisions}.revision - only makes sense
-       * if directories are versioned, of course), and "%branch" will be
-       * replaced by the branch name that the directory is on.
-       */
-      'directory_view' => '',
-      /**
-       * The URL of the repository viewer that displays the diff between two
-       * given files in the repository. "%path" and "%old-path" are used as
-       * placeholders for the new and old paths (for some version control
-       * systems, like CVS, those paths will always be the same).
-       * "%new-revision" and "%old-revision" will be replaced by the
-       * respective file-level revisions (from
-       * {versioncontrol_item_revisions}.revision), and "%branch" will be
-       * replaced by the branch name that the file is on.
-       */
-      'diff'           => '',
-      /**
-       * The URL of the issue tracker that displays the issue/case/bug page of
-       * an issue id which presumably has been mentioned in a commit message.
-       * As issue tracker URLs are likely specific to each repository, this is
-       * also a per-repository setting. (Although... maybe it would make sense
-       * to have per-project rather than per-repository. Oh well.)
-       */
-      'tracker'        => ''
-    );
-  }
-
-  /**
-   * Retrieve the URL of the repository viewer that displays the given commit
-   * in the corresponding repository.
-   *
-   * @param $revision
-   *   The revision on the commit operation whose view URL should be retrieved.
-   *
-   * @return
-   *   The commit view URL corresponding to the given arguments.
-   *   An empty string is returned if no commit view URL has been defined,
-   *   or if the commit cannot be viewed for any reason.
-   */
-  public function getCommitViewUrl($revision) {
-    if (empty($revision)) {
-      return '';
-    }
-    return strtr($this->urls['commit_view'], array(
-      '%revision' => $revision,
-    ));
-  }
-
-  /**
-   * Retrieve the URL of the repository viewer that displays the commit log
-   * of the given item in the corresponding repository. If no such URL has been
-   * specified by the user, the appropriate URL from the Commit Log module is
-   * used as a fallback (if that module is enabled).
-   *
-   * @param $item
-   *   The item whose log view URL should be retrieved.
-   *
-   * @return
-   *   The item log view URL corresponding to the given arguments.
-   *   An empty string is returned if no item log view URL has been defined
-   *   (and if not even Commit Log is enabled), or if the item cannot be viewed
-   *   for any reason.
-   */
-  public function getItemLogViewUrl(&$item) {
-    $label = $item->getSelectedLabel();
-
-    if (isset($label->type) && $label->type == VERSIONCONTROL_LABEL_BRANCH) {
-      $current_branch = $label['name'];
-    }
-
-    if (!empty($this->urls['file_log_view'])) {
-      if ($item->isFile()) {
-        return strtr($this->urls['file_log_view'], array(
-          '%path'     => $item->path,
-          '%revision' => $item->revision,
-          '%branch'   => isset($current_branch) ? $current_branch : '',
-        ));
-      }
-      // The default URL backend doesn't do log view URLs for directory items:
-      return '';
-    }
-    elseif (module_exists('commitlog')) { // fallback, as 'file_log_view' is empty
-      $query = array(
-        'repos' => $item->repository->repo_id,
-        'paths' => drupal_urlencode($item->path),
-      );
-      if (isset($current_branch)) {
-        $query['branches'] = $current_branch;
-      }
-      return url('commitlog', array(
-        'query' => $query,
-        'absolute' => TRUE,
-      ));
-    }
-    return ''; // in case we really can't retrieve any sensible URL
-  }
-
-  /**
-   * Retrieve the URL of the repository viewer that displays the contents of the
-   * given item in the corresponding repository.
-   *
-   * @param $item
-   *   The item whose view URL should be retrieved.
-   *
-   * @return
-   *   The item view URL corresponding to the given arguments.
-   *   An empty string is returned if no item view URL has been defined,
-   *   or if the item cannot be viewed for any reason.
-   */
-  public function getItemViewUrl(&$item) {
-    $label = $item->getSelectedLabel();
-
-    if (isset($label->type) && $label->type == VERSIONCONTROL_LABEL_BRANCH) {
-      $current_branch = $label->name;
-    }
-    $view_url = $item->isFile()
-      ? $this->urls['file_view']
-      : $this->urls['directory_view'];
-
-    return strtr($view_url, array(
-      '%path'     => $item['path'],
-      '%revision' => $item['revision'],
-      '%branch'   => isset($current_branch) ? $current_branch : '',
-    ));
-  }
-
-  /**
-   * Retrieve the URL of the repository viewer that displays the diff between
-   * two given files in the corresponding repository.
-   *
-   * @param $file_item_new
-   *   The new version of the file that should be diffed.
-   * @param $file_item_old
-   *   The old version of the file that should be diffed.
-   *
-   * @return
-   *   The diff URL corresponding to the given arguments.
-   *   An empty string is returned if no diff URL has been defined,
-   *   or if the two items cannot be diffed for any reason.
-   */
-  public function getDiffUrl(&$file_item_new, $file_item_old) {
-    $label = $file_item_new->getSelectedLabel();
-
-    if (isset($label['type']) && $label['type'] == VERSIONCONTROL_LABEL_BRANCH) {
-      $current_branch = $label['name'];
-    }
-    return strtr($this->urls['diff'], array(
-      '%path'         => $file_item_new['path'],
-      '%new-revision' => $file_item_new['revision'],
-      '%old-path'     => $file_item_old['path'],
-      '%old-revision' => $file_item_old['revision'],
-      '%branch'       => isset($current_branch) ? $current_branch : '',
-    ));
-  }
-
-  /**
-   * Retrieve the URL of the issue tracker that displays the issue/case/bug page
-   * of an issue id which presumably has been mentioned in a commit message.
-   * As issue tracker URLs are specific to each repository, this also needs
-   * to be given as argument.
-   *
-   * @param $issue_id
-   *   A number that uniquely identifies the mentioned issue/case/bug.
-   *
-   * @return
-   *   The issue tracker URL corresponding to the given arguments.
-   *   An empty string is returned if no issue tracker URL has been defined.
-   */
-  public function getTrackerUrl($issue_id) {
-    return strtr($this->urls['tracker'], array('%d' => $issue_id));
-  }
-}
diff --git includes/interfaces.inc includes/interfaces.inc
index 8ef4ffa..1bf31c2 100644
--- includes/interfaces.inc
+++ includes/interfaces.inc
@@ -322,3 +322,76 @@ interface VersioncontrolAuthHandlerInterface {
    */
   public function getErrorMessages();
 }
+
+interface VersioncontrolWebviewerUrlHandlerInterface {
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the main
+   * view of the repository.
+   *
+   * @return
+   *   The repository view URL of the associated repository.
+   */
+  public function getRepositoryViewUrl();
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the given commit
+   * in the corresponding repository.
+   *
+   * @param $revision
+   *   The revision on the commit operation whose view URL should be retrieved.
+   *
+   * @return
+   *   The commit view URL corresponding to the given arguments.
+   *   An empty string is returned if no commit view URL has been defined,
+   *   or if the commit cannot be viewed for any reason.
+   */
+  public function getCommitViewUrl($revision);
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the commit log
+   * of the given item in the corresponding repository. If no such URL has been
+   * specified by the user, the appropriate URL from the Commit Log module is
+   * used as a fallback (if that module is enabled).
+   *
+   * @param $item
+   *   The item whose log view URL should be retrieved.
+   *
+   * @return
+   *   The item log view URL corresponding to the given arguments.
+   *   An empty string is returned if no item log view URL has been defined
+   *   (and if not even Commit Log is enabled), or if the item cannot be viewed
+   *   for any reason.
+   */
+  public function getItemLogViewUrl(&$item);
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the contents of the
+   * given item in the corresponding repository.
+   *
+   * @param $item
+   *   The item whose view URL should be retrieved.
+   *
+   * @return
+   *   The item view URL corresponding to the given arguments.
+   *   An empty string is returned if no item view URL has been defined,
+   *   or if the item cannot be viewed for any reason.
+   */
+  public function getItemViewUrl(&$item);
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the diff between
+   * two given files in the corresponding repository.
+   *
+   * @param $file_item_new
+   *   The new version of the file that should be diffed.
+   * @param $file_item_old
+   *   The old version of the file that should be diffed.
+   *
+   * @return
+   *   The diff URL corresponding to the given arguments.
+   *   An empty string is returned if no diff URL has been defined,
+   *   or if the two items cannot be diffed for any reason.
+   */
+  public function getDiffUrl(&$file_item_new, $file_item_old);
+}
diff --git includes/plugins/webviewer_url_handlers/VersioncontrolRepositoryUrlHandler.inc includes/plugins/webviewer_url_handlers/VersioncontrolRepositoryUrlHandler.inc
new file mode 100644
index 0000000..e7f7bf6
--- /dev/null
+++ includes/plugins/webviewer_url_handlers/VersioncontrolRepositoryUrlHandler.inc
@@ -0,0 +1,180 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Repository Url handler class.
+ */
+
+/**
+ * Base class for URL handlers.
+ */
+class VersioncontrolRepositoryUrlHandler implements VersioncontrolWebviewerUrlHandlerInterface {
+
+  /**
+   * Repository where this urls belongs.
+   *
+   * @var VersioncontrolRepository
+   */
+  public $repository;
+
+  /**
+   * The first part of the URL that is going to be prepended to each URL
+   * retrieved.
+   *
+   * @var string
+   */
+  public $baseUrl;
+
+  /**
+   * An array of template URLs for the web viewer.
+   *
+   * @var array
+   */
+  public $templateUrls;
+
+  public function __construct($repository, $base_url, $template_urls) {
+    $this->repository = $repository;
+    $this->baseUrl = $base_url;
+    $this->templateUrls = $template_urls;
+  }
+
+  public function getTemplateUrl($name) {
+    if (!isset($this->templateUrls[$name]) || empty($this->templateUrls[$name])) {
+      return '';
+    }
+    return strtr($this->templateUrls[$name], array('%base_url' => $this->baseUrl));
+  }
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the main
+   * view of the repository.
+   *
+   * @return
+   *   The repository view URL of the associated repository.
+   */
+  public function getRepositoryViewUrl() {
+    return strtr($this->getTemplateUrl('repository_view'), array(
+      '%repo_name' => $this->repository->name,
+    ));
+  }
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the given commit
+   * in the corresponding repository.
+   *
+   * @param $revision
+   *   The revision on the commit operation whose view URL should be retrieved.
+   *
+   * @return
+   *   The commit view URL corresponding to the given arguments.
+   *   An empty string is returned if no commit view URL has been defined,
+   *   or if the commit cannot be viewed for any reason.
+   */
+  public function getCommitViewUrl($revision) {
+    if (empty($revision)) {
+      return '';
+    }
+    return strtr($this->getTemplateUrl('commit_view'), array(
+      '%repo_name' => $this->repository->name,
+      '%revision' => $revision,
+    ));
+  }
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the commit log
+   * of the given item in the corresponding repository. If no such URL has been
+   * specified by the user, the appropriate URL from the Commit Log module is
+   * used as a fallback (if that module is enabled).
+   *
+   * @param $item
+   *   The item whose log view URL should be retrieved.
+   *
+   * @return
+   *   The item log view URL corresponding to the given arguments.
+   *   An empty string is returned if no item log view URL has been defined
+   *   (and if not even Commit Log is enabled), or if the item cannot be viewed
+   *   for any reason.
+   */
+  public function getItemLogViewUrl(&$item) {
+    $label = $item->getSelectedLabel();
+
+    if (isset($label->type) && $label->type == VERSIONCONTROL_LABEL_BRANCH) {
+      $current_branch = $label->name;
+    }
+
+    $placeholders = array(
+      '%repo_name' => $this->repository->name,
+      '%path'     => $item->path,
+      '%revision' => $item->revision,
+      '%branch'   => isset($current_branch) ? $current_branch : '',
+    );
+
+    if ($item->isFile()) {
+      return strtr($this->getTemplateUrl('file_log_view'), $placeholders);
+    }
+    else { // directory
+      return strtr($this->getTemplateUrl('directory_log_view'), $placeholders);
+    }
+  }
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the contents of the
+   * given item in the corresponding repository.
+   *
+   * @param $item
+   *   The item whose view URL should be retrieved.
+   *
+   * @return
+   *   The item view URL corresponding to the given arguments.
+   *   An empty string is returned if no item view URL has been defined,
+   *   or if the item cannot be viewed for any reason.
+   */
+  public function getItemViewUrl(&$item) {
+    $label = $item->getSelectedLabel();
+
+    if (isset($label->type) && $label->type == VERSIONCONTROL_LABEL_BRANCH) {
+      $current_branch = $label->name;
+    }
+    $view_url = $item->isFile()
+      ? $this->getTemplateUrl('file_view')
+      : $this->getTemplateUrl('directory_view');
+
+    return strtr($view_url, array(
+      '%repo_name' => $this->repository->name,
+      '%path'     => $item->path,
+      '%revision' => $item->revision,
+      '%branch'   => isset($current_branch) ? $current_branch : '',
+    ));
+  }
+
+  /**
+   * Retrieve the URL of the repository viewer that displays the diff between
+   * two given files in the corresponding repository.
+   *
+   * @param $file_item_new
+   *   The new version of the file that should be diffed.
+   * @param $file_item_old
+   *   The old version of the file that should be diffed.
+   *
+   * @return
+   *   The diff URL corresponding to the given arguments.
+   *   An empty string is returned if no diff URL has been defined,
+   *   or if the two items cannot be diffed for any reason.
+   */
+  public function getDiffUrl(&$file_item_new, $file_item_old) {
+    $label = $file_item_new->getSelectedLabel();
+
+    if (isset($label->type) && $label->type == VERSIONCONTROL_LABEL_BRANCH) {
+      $current_branch = $label->name;
+    }
+    return strtr($this->getTemplateUrl('diff'), array(
+      '%repo_name' => $this->repository->name,
+      '%path'         => $file_item_new->path,
+      '%new_revision' => $file_item_new->revision,
+      '%old_path'     => $file_item_old->path,
+      '%old_revision' => $file_item_old->revision,
+      '%branch'       => isset($current_branch) ? $current_branch : '',
+    ));
+  }
+
+}
diff --git includes/plugins/webviewer_url_handlers/none.inc includes/plugins/webviewer_url_handlers/none.inc
new file mode 100644
index 0000000..242de9e
--- /dev/null
+++ includes/plugins/webviewer_url_handlers/none.inc
@@ -0,0 +1,129 @@
+<?php
+// $Id$
+/**
+ * @file
+ * This plugin contains the main documentation of how to make a
+ * webviewer_url_handler. It does not really provide any functionallity.
+ */
+
+$plugin = array(
+
+  // The versioncontrol system machine name as the backend declares.
+  'vcs' => 'test',
+
+  // This title is going to be shown on the repository edition, for the
+  // user to identify the plugin.
+  'title' => t('Empty URL handler'),
+
+  // The list of URL templates this webviewer. Leave empty the URL
+  // template entry if the web viewer do not support that template.
+  'url_templates' => array(
+
+    /**
+     * Template URL for the main page for this repository.
+     *
+     * It contains the following placeholders:
+     * - "%base_url" the URL to the repository viewer.
+     * - "%repo_name" the name of the repository on the filesystem.
+     */
+    'repository_view' => '',
+
+    /**
+     * Template url for the commit view.
+     *
+     * The URL of the repository viewer that displays a given commit in the
+     * repository.
+     * It contains the following placeholders:
+     * - "%base_url" the URL to the repository viewer.
+     * - "%repo_name" the name of the repository on the filesystem.
+     * - "%revision" for the revision/commit/changeset identifier.
+     */
+    'commit_view' => '',
+
+    /**
+     * Template url for the file log view.
+     *
+     * The URL of the repository viewer that displays the commit log of
+     * a given file in the repository.
+     * It contains the following placeholders:
+     * - "%base_url" the URL to the repository viewer.
+     * - "%repo_name" the name of the repository on the filesystem.
+     * - "%path" for the file path
+     * - "%revision" will be replaced by the file-level revision (the one
+     *   in {versioncontrol_item_revisions}.revision)
+     * - "%branch" will be replaced by the branch name that the file is on
+     */
+    'file_log_view' => '',
+
+    /**
+     * Template url for the file directory log view.
+     *
+     * The URL of the repository viewer that displays the commit log of
+     * a given directoryin the repository.
+     * It contains the following placeholders:
+     * - "%base_url" the URL to the repository viewer.
+     * - "%repo_name" the name of the repository on the filesystem.
+     * - "%path" for the file path
+     * - "%revision" will be replaced by the file-level revision (the one
+     *   in {versioncontrol_item_revisions}.revision)
+     * - "%branch" will be replaced by the branch name that the file is on
+     */
+    'directory_log_view' => '',
+
+    /**
+     * Template url for the file view.
+     *
+     * The URL of the repository viewer that displays the contents of a
+     * given file in the repository.
+     * It contains the following placeholders:
+     * - "%base_url" the URL to the repository viewer.
+     * - "%repo_name" the name of the repository on the filesystem.
+     * - "%path" for the file path
+     * - "%revision" will be replaced by the file-level revision (the
+     *   one in {versioncontrol_item_revisions}.revision)
+     * - "%branch" will be replaced by the branch name that the file is on
+     */
+    'file_view' => '',
+
+    /**
+     * Template url for the directory view.
+     *
+     * The URL of the repository viewer that displays the contents of a given
+     * directory in the repository.
+     * It contains the following placeholders:
+     * - "%base_url" the URL to the repository viewer.
+     * - "%repo_name" the name of the repository on the filesystem.
+     * - "%path" for the directory path
+     * - "%revision" will be replaced by the file-level revision (the
+     *   one in {versioncontrol_item_revisions}.revision - only makes sense
+     *   if directories are versioned, of course)
+     * - "%branch" will be replaced by the branch name that the
+     *   directory is on.
+     */
+    'directory_view' => '',
+
+    /**
+     * Template url for the diff view.
+     *
+     * The URL of the repository viewer that displays the diff between two
+     * given files in the repository.
+     * It contains the following placeholders:
+     * - "%base_url" the URL to the repository viewer.
+     * - "%repo_name" the name of the repository on the filesystem.
+     * - "%path" and "%old_path" for the new and old paths (for some
+     *   version control systems, like CVS, those paths will always be
+     *   the same).
+     * - "%new_revision" and "%old_revision" will be replaced by the
+     *   respective file-level revisions (from
+     *   {versioncontrol_item_revisions}.revision)
+     * - "%branch" will be replaced by the branch name that the file is on.
+     */
+    'diff' => '',
+
+  ),
+  'handler' => array(
+    'class' => 'VersioncontrolRepositoryUrlHandler',
+    'file' => 'VersioncontrolRepositoryUrlHandler.inc',
+    'path' => drupal_get_path('module', 'versioncontrol') . '/includes/plugins/webviewer_url_handlers',
+  ),
+);
diff --git tests/VersioncontrolTestCase.test tests/VersioncontrolTestCase.test
index 4799be6..fa258f2 100644
--- tests/VersioncontrolTestCase.test
+++ tests/VersioncontrolTestCase.test
@@ -149,9 +149,13 @@ abstract class VersioncontrolTestCase extends DrupalWebTestCase {
       'auth_handler' => 'ffa',
       'author_mapper' => 'simple_mail',
       'committer_mapper' => 'simple_mail',
+      'webviewer_url_handler' => 'none',
     );
 
     $data += $default_data;
+    if (!isset($data['webviewer_base_url'])) {
+      $data['data']['webviewer_base_url'] = '';
+    }
     foreach ($default_plugins as $plugin_slot => $default_plugin) {
       if (empty($data['plugins'][$plugin_slot])) {
         $data['plugins'][$plugin_slot] = $default_plugin;
diff --git versioncontrol.admin.inc versioncontrol.admin.inc
index ac81a9d..c5ef9ba 100644
--- versioncontrol.admin.inc
+++ versioncontrol.admin.inc
@@ -371,6 +371,31 @@ function versioncontrol_admin_repository_edit(&$form_state, $repository, $vcs =
     '#options' => versioncontrol_auth_handlers_get_names(),
   );
 
+  $repo_url_handler = $repository_exists ? $repository->getUrlHandler() : NULL;
+
+  $form['repository_urls'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Repository browser URL handler'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#weight' => 5,
+  );
+  $form['repository_urls']['base_url'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Base URL'),
+    '#default_value' => isset($repo_url_handler) ? $repo_url_handler->baseUrl : '',
+    '#size' => 40,
+    '#maxlength' => 255,
+    '#description' => t('The URL that let you see the repository web viewer. Do not use a trailing slash.'),
+  );
+  $form['repository_urls']['url_handler'] = array(
+    '#type' => 'radios',
+    '#title' => t('Web viewer URL handler'),
+    '#description' =>  t('The handler which will  provide the URLs that will be used to add links to item and commit displays such as the commit log.'),
+    '#default_value' => $repository_exists ? $repository->plugins['webviewer_url_handler'] : 0,
+    '#options' => versioncontrol_webviewer_url_handlers_get_names($form['#vcs']),
+  );
+
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Save repository'),
@@ -414,6 +439,7 @@ function versioncontrol_admin_repository_edit_submit($form, &$form_state) {
       'author_mapper' => $form_state['values']['author_mapper'],
       'committer_mapper' => $form_state['values']['committer_mapper'],
       'auth_handler' => $form_state['values']['auth_handler'],
+      'webviewer_url_handler' => $form_state['values']['url_handler'],
     );
   }
   else {
@@ -428,11 +454,14 @@ function versioncontrol_admin_repository_edit_submit($form, &$form_state) {
         'author_mapper' => $form_state['values']['author_mapper'],
         'committer_mapper' => $form_state['values']['committer_mapper'],
         'auth_handler' => $form_state['values']['auth_handler'],
+        'webviewer_url_handler' => $form_state['values']['url_handler'],
       ),
     );
     $repository = $backends[$form['#vcs']]->buildEntity('repo', $repository);
   }
 
+  $repository->data['webviewer_base_url'] = $form_state['values']['base_url'];
+
   // Let other modules alter the repository array.
   foreach (module_implements('versioncontrol_repository_submit') as $module) {
     $function = $module .'_versioncontrol_repository_submit';
diff --git versioncontrol.info versioncontrol.info
index 835bba9..660c3d6 100644
--- versioncontrol.info
+++ versioncontrol.info
@@ -13,7 +13,6 @@ files[] = includes/VersioncontrolRepository.php
 files[] = includes/VersioncontrolTag.php
 files[] = includes/interfaces.inc
 files[] = includes/controllers.inc
-files[] = includes/VersioncontrolRepository.php
 files[] = includes/views_sets.inc
 package = Version Control
 core = 6.x
diff --git versioncontrol.install versioncontrol.install
index bd81477..e416b39 100644
--- versioncontrol.install
+++ versioncontrol.install
@@ -1139,3 +1139,22 @@ function versioncontrol_update_6311() {
 
   return $ret;
 }
+
+/**
+ * Remove url_handler from repository data.
+ * Add base_url to repository data.
+ */
+function versioncontrol_update_6312() {
+  $ret = array();
+  $result = db_query("SELECT repo_id, data FROM {versioncontrol_repositories}");
+
+  while ($row = db_fetch_object($result)) {
+    $data = unserialize($row->data);
+    unset($data['versioncontrol']['url_handler']);
+    $data['webviewer_base_url'] = '';
+    $data = serialize($row->data);
+    db_query('UPDATE {versioncontrol_repositories} SET data = %s WHERE repo_id = %d', $row->data, $row->repo_id);
+  }
+
+  return $ret;
+}
diff --git versioncontrol.module versioncontrol.module
index b4435a7..06f5033 100644
--- versioncontrol.module
+++ versioncontrol.module
@@ -1019,3 +1019,25 @@ function versioncontrol_auth_handlers_get_names() {
   asort($names);
   return $names;
 }
+
+/**
+ * Load the names of all 'webviewer_url_handlers' for use at forms.
+ */
+function versioncontrol_webviewer_url_handlers_get_names($vcs='') {
+  ctools_include('plugins');
+
+  $names = array();
+  foreach (ctools_get_plugins('versioncontrol', 'webviewer_url_handlers') as $name => $plugin) {
+    if (!empty($vcs)) {
+      if ($plugin['vcs'] == $vcs) {
+        $names[$name] = $plugin['title'];
+      }
+    }
+    else {
+      $names[$name] = $plugin['title'];
+    }
+  }
+
+  asort($names);
+  return $names;
+}
