? views_generic_link.patch
? views_generic_link_2.patch
Index: handlers/views_handler_field_link.inc
===================================================================
RCS file: handlers/views_handler_field_link.inc
diff -N handlers/views_handler_field_link.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ handlers/views_handler_field_link.inc	19 Dec 2008 20:45:10 -0000
@@ -0,0 +1,117 @@
+<?php
+// $Id$
+
+/**
+ * A handler to provide a customizable link field.
+ *
+ * @ingroup views_field_handlers
+ */
+
+class views_handler_field_link extends views_handler_field {
+  static protected $search;
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['link_text'] = array('default' => '');
+    $options['link_path'] = array('default' => '');
+    $options['link_prefix'] = array('default' => '');
+    $options['link_suffix'] = array('default' => '');
+
+    return $options;
+  }
+
+  /**
+   * Set the options for this link. Note that if Path is left empty, this is a custom text field.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['link_text'] = array(
+      '#title' => t('Link text'),
+      '#type' => 'textfield',
+      '#size' => 40,
+      '#default_value' => $this->options['link_text'],
+      '#description' => t('The text to disaply for this link. You may enter the view arguments, such as %1 or database field names, such as [nid]. To view the available field names, click on <em>Theme: Information</em> for this display.'),
+    );
+    $form['link_prefix'] = array(
+      '#title' => t('Prefix text'),
+      '#type' => 'textfield',
+      '#size' => 40,
+      '#default_value' => $this->options['link_prefix'],
+      '#description' => t('Any text to display before this link. You may include HTML.'),
+    );
+    $form['link_suffix'] = array(
+      '#title' => t('Suffix text'),
+      '#type' => 'textfield',
+      '#size' => 40,
+      '#default_value' => $this->options['link_suffix'],
+      '#description' => t('Any text to display after this link. You may include HTML.'),
+    );
+    $form['link_path'] = array(
+      '#title' => t('Link path'),
+      '#type' => 'textfield',
+      '#size' => 40,
+      '#default_value' => $this->options['link_path'],
+      '#description' => t('The drupal path or complete URL for this link.  You may enter the view arguments, such as %1 or database field names, such as [nid]. To view the available field names, click on <em>Theme: Information</em> for this display. If blank, only the above text will be displayed.'),
+    );
+  }
+
+  function query() {
+    // We don't do anything here.  But doing so avoids errors in trying to load a non-existent field.
+  }
+
+  /**
+   * Take the tokens and arguments and run the proper substitutions.
+   */
+  function render($value) {
+    $link_text = $this->options['link_text'];
+    $link_path = $this->options['link_path'];
+    $prefix = $this->options['link_prefix'];
+    $suffix = $this->options['link_suffix'];
+    // If we have arguments, then substitute them.
+    if (!empty($this->view->build_info['substitutions'])) {
+      foreach ($this->view->build_info['substitutions'] as $key => $arg) {
+        $link_text = str_replace($key, $arg, $link_text);
+        $link_path = str_replace($key, $arg, $link_path);
+      }
+    }
+    // Otherwise, we remove the argument handlers.
+    else {
+      for ($i = 0; $i <= 10; $i++) {
+        $subs[] = "%$i";
+      }
+      // A regex might be better here. And what about empty arguments?
+      $link_text = str_replace($subs, '', $link_text);
+      $link_path = str_replace($subs, '', $link_path);
+    }
+    $search = self::_get_search_array($this->view->query->fields);
+    // Now replace the tokens.
+    foreach ($value as $key => $val) {
+      $link_text = str_replace(self::$search[$key], $val, $link_text);
+      $link_path = str_replace(self::$search[$key], $val, $link_path);
+    }
+    $output = filter_xss_admin($prefix);
+    if (!empty($link_path)) {
+      $output .= l($link_text, $link_path);
+    }
+    else {
+      $output .= check_plain($link_text);
+    }
+    $output .= filter_xss_admin($suffix, 1);
+    return $output;
+  }
+  
+  /**
+   * Private function to calculate the search array.
+   */
+   protected function _get_search_array($fields) {
+     if (isset(self::$search)) {
+       return self::$search;
+     }
+     // Prepare the field tokens by finding the proper aliases used in this query.
+     self::$search = array();
+     foreach ($fields as $key => $token) {
+       self::$search[$key] = '['. $token['field'] .']';
+     }
+     return self::$search;
+   }
+}
Index: includes/handlers.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/handlers.inc,v
retrieving revision 1.101
diff -u -p -r1.101 handlers.inc
--- includes/handlers.inc	2 Dec 2008 16:04:59 -0000	1.101
+++ includes/handlers.inc	19 Dec 2008 20:45:12 -0000
@@ -1049,6 +1049,9 @@ function views_views_handlers() {
       'views_handler_field_numeric' => array(
         'parent' => 'views_handler_field',
       ),
+      'views_handler_field_link' => array(
+        'parent' => 'views_handler_field',
+      ),
 
       // filter handlers
       'views_handler_filter' => array(
Index: includes/view.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/view.inc,v
retrieving revision 1.143
diff -u -p -r1.143 view.inc
--- includes/view.inc	16 Dec 2008 19:03:48 -0000	1.143
+++ includes/view.inc	19 Dec 2008 20:45:14 -0000
@@ -504,6 +504,9 @@ class view extends views_db_object {
       $this->build_info['title'] = str_replace(array_keys($substitutions), $substitutions, $title);
     }
 
+    // Store the arguments for later use.
+    $this->build_info['substitutions'] = $substitutions;
+
     return $status;
   }
 
Index: modules/views.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/views.views.inc,v
retrieving revision 1.5
diff -u -p -r1.5 views.views.inc
--- modules/views.views.inc	3 Sep 2008 19:21:29 -0000	1.5
+++ modules/views.views.inc	19 Dec 2008 20:45:14 -0000
@@ -34,6 +34,14 @@ function views_views_data() {
       'handler' => 'views_handler_argument_null',
     ),
   );
+
+  $data['views']['link_field'] = array(
+    'title' => t('Custom link field'),
+    'help' => t('Create a custom links field.'),
+    'field' => array(
+      'handler' => 'views_handler_field_link',
+    ),
+  );
   return $data;
 }
 
