I set link field url = www.domain.com

PROBLEM this produces an href which is relative to my local drupal site.

when title= 'title-value' I get

Relevant Settings
Link Title: optional
Static title: static title :)
no default values
number of values: 1

Widget Type: Link
Display format: 'Title as link' default

doco(http://drupal.org/project/link) seems to indicate that the following translation should occur for url field
*** drupal.org => http://drupal.org ***

BUT when I look at the formatters eg. function theme_link_formatter_default($vars) only the entered url:'www.domain.com.au' is used...
return l($vars['element']['title'], $vars['element']['url'], array('attributes' => $vars['element']['attributes']));

this is despite having a $vars['element']['display_url'] which is http://www.domain.com.au (unfortunately this may get truncated)

PLUS I asked on IRC and only got others saying they had heard of the problem and the dolution was custom code.

my SOLUTION
It seems that a lot of work has gone into getting the $display_url, so why not use this(or a prcursor) as the href

To do this I just mad a change to _link_sanitize to replace the working $item['url'] with ...
$url = link_cleanup_url($item['url']);
$item['url']= $url;

I don't know what flow-on damage this will cause but it seems OK to me. BUT so simple a change I wonder why it has not been made???

... anyway here is the updated code to

_link_sanitize in link.module
only one line changed as per comments

I really need to setup dev environment to create patches.

Is this change correct/sensible???
THX

function _link_sanitize(&$item, $delta, &$field, $instance, &$node) {
  // Don't try to process empty links.
  if (empty($item['url']) && empty($item['title'])) {
    return;
  }

  // Replace URL tokens.
  if ($instance['settings']['enable_tokens']) {
    global $user;
    // Load the node if necessary for nodes in views.
    $token_node = isset($node->nid) ? node_load($node->nid) : $node;
    $item['url'] = token_replace($item['url'], array('node' => $token_node));
  }

  $type = link_validate_url($item['url']);
  $url = link_cleanup_url($item['url']);

  //dg: set the $item['url'] to the cleaned up verion
  // this (at least) has the effect on $url='www.domain.com' of making the produced href (in eg theme_link_formatter_default) external rather than internal/relative
  $item['url']= $url;

  // Separate out the anchor if any.
  if (strpos($url, '#') !== FALSE) {
    $item['fragment'] = substr($url, strpos($url, '#') + 1);
    $url = substr($url, 0, strpos($url, '#'));
  }
  // Separate out the query string if any.
  if (strpos($url, '?') !== FALSE) {
    $query = substr($url, strpos($url, '?') + 1);
    parse_str($query, $query_array);
    $item['query'] = $query_array;
    $url = substr($url, 0, strpos($url, '?'));
  }

  // Create a shortened URL for display.
  $display_url = $type == LINK_EMAIL ?
                  str_replace('mailto:', '', $url) :
                  url($url, array('query' => isset($item['query']) ?
                                              $item['query'] :
                                              NULL,
                                  'fragment' => isset($item['fragment']) ?
                                                $item['fragment'] :
                                                NULL,
                                  'absolute' => TRUE));
  if ($instance['settings']['display']['url_cutoff'] && strlen($display_url) > $instance['settings']['display']['url_cutoff']) {
    $display_url = substr($display_url, 0, $instance['settings']['display']['url_cutoff']) ."...";
  }
  $item['display_url'] = $display_url;

  // Use the title defined at the instance level.
  if ($instance['settings']['title'] == 'value' && strlen(trim($instance['settings']['title_value']))) {
    $title = $instance['settings']['title_value'];
  }
  // Use the title defined by the user at the widget level.
  else if (isset($item['title'])) {
    $title = $item['title'];
  }
  else {
    $title = '';
  }

  // Replace tokens.
  if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) {
    // Load the node if necessary for nodes in views.
    $token_node = isset($node->nid) ? node_load($node->nid) : $node;
    $title = filter_xss(token_replace($title, array('node' => $token_node)),
                        array('b', 'br', 'code', 'em', 'i', 'img', 'span', 'strong', 'sub', 'sup', 'tt', 'u'));
    $item['html'] = TRUE;
  }
  $item['title'] = empty($title) ? $item['display_url'] : $title;

  if (!isset($item['attributes'])) {
    $item['attributes'] = array();
  }

  // Unserialize attributtes array if it has not been unserialized yet.
  if (!is_array($item['attributes'])) {
    $item['attributes'] = (array)unserialize($item['attributes']);
  }

  // Add default attributes.
  if (!is_array($instance['settings']['attributes'])){
    $instance['settings']['attributes'] = _link_default_attributes();
  }
  else {
    $instance['settings']['attributes'] += _link_default_attributes();
  }

  // Merge item attributes with attributes defined at the field level.
  $item['attributes'] += $instance['settings']['attributes'];

  // If user is not allowed to choose target attribute, use default defined at
  // field level.
  if ($instance['settings']['attributes']['target'] != LINK_TARGET_USER) {
    $item['attributes']['target'] = $instance['settings']['attributes']['target'];
  }

  // Remove the target attribute if the default (no target) is selected.
  if (empty($item['attributes']) || $item['attributes']['target'] == LINK_TARGET_DEFAULT) {
    unset($item['attributes']['target']);
  }

  // Remove the rel=nofollow for internal links.
  if ($type != LINK_EXTERNAL && strpos($item['attributes']['rel'], 'nofollow') !== FALSE) {
    $item['attributes']['rel'] = str_replace('nofollow', '', $item['attributes']);
  }

  // Remove empty attributes.
  $item['attributes'] = array_filter($item['attributes']);

  // Sets title to trimmed url if one exists
  // @TODO: Do we need this?  It seems not.
  /*
  if(!empty($item['display_url']) && empty($item['title'])) {
    $item['title'] = $item['display_url'];
  }
  elseif(!isset($item['title'])) {
    $item['title'] = $item['url'];
  }
  */

}

Comments

dgdgdg’s picture

Some html was stripped ...
main point was

href="my-drupal-dir/?q=www.domain.com"

rather than expected
href="http://www.domain.com"

drew reece’s picture

I've seen this issue too, update to the dev release & it seems to be fixed.

dqd’s picture

Status: Active » Closed (duplicate)

Folks, please read the project page info of link module carefully. There is already an issue to collect and discuss all possible validation scenarios in general. That's why I will mark this one here as a duplicate. I need all concentration inside the ONE and only discussion to move forward. After a D7 implementation we will provide a D6 backport.

Explanation: There are too many corner cases and validation wishes of users to implement them all serially one after the other. We would have a 40 lines cluttered settings form for validation methods only conflicting each other. I think, the right way is to find a maybe more complex but all embracing configuration method, which lets the admin better decide how and when to validate the url. Including a good description which helps to set it up.

dqd’s picture

Version: 7.x-1.0-alpha3 » 7.x-1.x-dev
Issue tags: +field validation