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
Comment #1
dgdgdg commentedSome html was stripped ...
main point was
href="my-drupal-dir/?q=www.domain.com"
rather than expected
href="http://www.domain.com"
Comment #2
drew reece commentedI've seen this issue too, update to the dev release & it seems to be fixed.
Comment #3
dqdFolks, 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.
Comment #4
dqd