I am querying a third party database that has both web site urls and email address in a table. If I setup my url field in Views to "Output this field as a link" with the token, [website_url] (a field from the table), and set the "Use absolute path" flag, my rendered links will very.

If "website_url" = 'http://www.example.com', the link will render fine. However, if "website_url" = 'www.example.com', the link renders as 'http://localhost/www.example.com'. I could set my path and token to 'http://[website_url]' and make it work, but I am working with thrid party data and I do not have control this fields. The data could easily be a mix of any of the following:
'http://www.example.com'
'www.example.com'
'example.com'

I want my links to just work no matter what the user enters. The patch below fixes this issue.

I also have an 'email' field. I would like that field to render as a mailto:name@example.com email link. To do this, you just have to add 'mailto:' to the "Prefix text:" field setting in Views. However, when working on the above issue, I discovered that there was an error in the render_as_link() function. It uses the following code to skip the link creation process:

if (empty($path)) {
  return $text;
}

// Parse the URL and move any query and fragment parameters out of the path.
$url = parse_url($path);

If you use a "Prefix text:" like 'mailto:' or even 'http://', $path is no longer empty. The following is a better was to handle this:

// Parse the URL and move any query and fragment parameters out of the path.
$url = parse_url($path);

if (empty($url['path'])) {
  return $text;
}

The above change is also included in the patch.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bendiy’s picture

FileSize
3.58 KB

Sorry, wrong file, ignore this one.

bendiy’s picture

FileSize
1.55 KB

Here is the real patch.

merlinofchaos’s picture

What if someone has "node/1" as the path and checks absolute. That's going to break with this patch, won't it?

bendiy’s picture

You're right. For some reason I was thinking absolute==external domain, not root path of the server. I need more coffee.

It looks like this is not going to be as easy as I had hoped. The PHP parse_url is not very good at what it is supposed to do. http://php.net/manual/en/function.parse-url.php I'm really looking for the $url['host'] value, not the path. However, without a scheme, it will put www.example.com in the $url['path'] value, not $url['host'] value.

You also have to keep in mind IP addresses as hosts, 192.168.0.1, could be a link. There are also the urls like this:

$path = array(
  'node/1',
  'node/1/',
  '/node/1',
  '/node/1/',
  'user',
  'user/',
  '/user',
  '/user/',
  'example.com',
  'www.example.com',
  'http://example.com',
  'http://www.example.com',
  'http://username:password@example.com',
  'http://192.168.0.1',
  'filename.ext',
  '/filename.ext',
  'you get the idea',
  );

The regular expression that matches all of these cases scares me.

Different Solution Idea

How about using a new flag like the current "Use absolute path"? It could be "External Server" and the code could check that value and prevent the 'http://localhost/www.example.com' situation I described above.

merlinofchaos’s picture

It could certainly work okay as a checkbox and assume that the path is always external and then treat it appropriately.

The regex to discover paths is scary, and it gets worse every time TLDs get added since really that's the basis for detecting. And if you happen to have a filename that looks like a TLD? No regex will ever get that one right. It's definitely best to try to have the data be explicit.

bendiy’s picture

FileSize
3.07 KB

Attached is a patch that adds an 'External server URL' check box to the field handler. When checked, fields will be checked for a scheme in the URL path. If one is found, it will work just like it always has. If no scheme is found, a default of 'http://' will be added. If this box is check, internal URLs will work as well, as long as they have the full URL with the site's domain, http://example.com or example.com, not just an absolute path.

The fix for 'mailto:' prefixes with no emails rendering as blank links has also been included. It checks for empty($url['path']) and empty($url['host']) because 'http://www.example.com' will have an empty path, but will have a host value.

Please review.

Thanks!

bendiy’s picture

Version: 6.x-2.x-dev » 6.x-3.x-dev
FileSize
3.09 KB

I've rerolled this patch for 6.x-3.x-dev. See attached.

dawehner’s picture

FileSize
3.36 KB

Very good patch. I like the inline documentation a lot!

Sadly you missed to add it to option_definition, so i rerolled both patches.

This patch fixed this. The rest was rtbc from my perspective.

I updated also some comment styles.

bendiy’s picture

Great. Thanks for fixing that. I hope it gets committed soon.

strellman’s picture

Could we make this to allow URLs like:
Skype:skype.name?call

Views keeps making this into a relative URL when I need it to be an absolute.
I am trying to rewrite the output of a skype_field and turn it into a Skype button link, which would be a great integration for a social networking site. Maybe I will have to try computed_field, but Views would have been much easier. I got my hopes up when I found the check box "Use absolute path" on 6.x-3.x-dev but it didn't work, no URL at all is produced.

Here is the output rewrite:

<!--
Skype 'My status' button
http://www.skype.com/go/skypebuttons
--><p>
<script src="http://download.skype.com/share/skypebuttons/js/skypeCheck.js" type="text/javascript"></script>
<a href="skype:[field_skype_value]?call"><img src="http://mystatus.skype.com/bigclassic/[field_skype_value]" alt="My status" width="182" height="44" style="border: none;" /></a></p>

I also tried moving the link path, but keeping this in rewrite:
<p>
<script src="http://download.skype.com/share/skypebuttons/js/skypeCheck.js" type="text/javascript"></script>
<img src="http://mystatus.skype.com/bigclassic/[field_skype_value]" alt="My status" width="182" height="44" style="border: none;" /></a></p>

This is the link path:
skype:[field_skype_value]?call
strellman’s picture

Figured out my own question. Adding // before skype: worked, but only in the chrome browser.
Ended up using computed field snippet http://drupal.org/node/957646
Be sure to use Raw Text format.
Be sure to save computed field to the database.

Rj-dupe-1’s picture

Status: Needs review » Needs work

The patch doesn't apply cleanly due to views_handler_field.inc not having a $form['alter']['absolute'] = array(...) also note that as strellman discovered, this patch does not allow arbitrary URL schemes (seems to expect/enforce http as the protocol).

dawehner’s picture

FileSize
34.76 KB

@Rj

Are you sure you are at the right version of views?
The current dev has this.

Rj-dupe-1’s picture

@dereine:

Hmm; I drush dl views-6.x-3.x-dev so unless there was a cache somewhere I'm pretty sure it was fresh. I then had a look in case the patch had been applied but it didn't seem to have this functionality in the UI. I then tried to patch it, which partially failed so I hand-applied the patch. I didn't specifically look for existing code but I also didn't notice any. After patching, I had the checkbox described above but not the functionality that I was looking for (arbitrary URL schemes), so I deleted it all and tried a few other ideas.

None of the other ideas have panned out so far, so I might try to develop a patch to add support for arbitrary URL schemes and will look at 3.x-dev a little closer to make sure... but I can't imagine the steps above working if the version I downloaded had this patch already applied.

dawehner’s picture

Status: Needs work » Needs review

Please please try it again. it's there 100%.

Back to needs review.

dawehner’s picture


 drush dl views-6.x-3.x-dev
Project views (6.x-3.x-dev) downloaded to /home/dawehner/Desktop/views.                            [success]
Project views contains 3 modules: views_export, views, views_ui.
dawehner@Bitrenner ~/Desktop % cd views
dawehner@Bitrenner ~/Desktop/views % patcha http://drupal.org/files/issues/views-869172-7_0.patch
--2010-12-10 11:36:42--  http://drupal.org/files/issues/views-869172-7_0.patch
Resolving drupal.org... 140.211.166.21, 140.211.166.6
Connecting to drupal.org|140.211.166.21|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3445 (3.4K) [text/plain]
Saving to: `STDOUT'

100%[====================================================================>] 3,445       17.4K/s   in 0.2s    

2010-12-10 11:36:43 (17.4 KB/s) - written to stdout [3445/3445]

patching file handlers/views_handler_field.inc
Hunk #1 succeeded at 294 (offset 132 lines).
Hunk #2 succeeded at 458 (offset 218 lines).
Hunk #3 succeeded at 847 (offset 241 lines).
bendiy’s picture

Make sure an clear your Views cache. Did you have Views 2 installed before? I'm not sure how the upgrade path works. Try and fresh install of Drupal and Views.

Also:

this patch does not allow arbitrary URL schemes (seems to expect/enforce http as the protocol).

Sounds like a feature request. This patch is for domains and mailtos, not web services "Skype:skype.name?call".

dawehner’s picture

Drupal by default allows this types in the url:

    $allowed_protocols = array_flip(variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal', 'rtsp')));

But it's a variable so you can allow skype and manymore if you need them.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

In general this patch needs a rerole against 7.x-3.x

www.google.de/[nid]

Worked.

http://www.google.de/[nid]

Worked

node-test/[nid]

with absolute still works.

node-test/[nid]

without absolute still works.

Based on this RTBC, because the main part of this patch is not from myself.

merlinofchaos’s picture

Version: 6.x-3.x-dev » 7.x-3.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)
FileSize
3.98 KB

Committed to 6.x-3.x with a small logic adjustment to make sure parse_url() is safe (and to eliminate an unnecessarily nested if).

dawehner’s picture

Status: Patch (to be ported) » Fixed

Ported and commited to the 7.x branch.

bendiy’s picture

Thanks for finishing this. I haven't had time to work on Drupal for a while. Glad to see this get committed to both 6 and 7.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.