here is a use case for internal URLs:

A site has links to internal content. The site is used on multiple servers - one for development, test, and production. When moving the database backup between environments they would prefer to simply use a relative URL instead of the full URL.

This has several impacts on the code:

1. Validation of the URL would need to be removed since relative URLs can take almosts any format
2. cleanup of the URL is removed so that we no longer add the protocol

So, this removes quite a bit of code from the module.

I've provided a patch that does this for CVS. If we really wanted to do this we should probably include a hook_update that added http:// to the beginning of all links that don't currently begin with http:// that existed prior to this patch

CommentFileSizeAuthor
link_allow_internal.patch3.86 KBgreggles

Comments

quicksketch’s picture

Maybe a field-level option to simply disable the checking would be more appropriate? The current validation is largely in place to prevent mistakes (and therefor dead-links). I kind of think taking the validation out makes this module a little too much like any other field. If you don't want any validation, you might as well make two textfields and a checkbox in CCK seperately.

Maybe we could provide additional validation which allows internal links? Internal links will still have some kind of pattern to them. They still can't include certain characters and you might want to prevent people from starting the URL with a slash ('/') so the Drupal links are valid. What do you think?

greggles’s picture

Thanks for the quick response.

You raise good points. Is there a use case for the validation aside from dead links? Because there are other ways to check for dead links that might be more appropriate (e.g. making an http request for the page).

The idea of a user input for "internal/external" is also a good way to allow different kinds of validation - as you point out, the current code allows users to mistakenly add a front slash on an internal URL.

I could go either way - let me know if you want me to try to implement the checkbox system.

quicksketch’s picture

Status: Needs review » Needs work

How about the following GUI: Add a new category in the 'Data settings' fieldset for 'Validation' with the following options:

Validation
[x] Validate internal links (a Drupal path)
[x] Validate external links (beginning with http:// or another protocol)
[x] Automatically prepend 'http://' to external links without a protocol
If no checkboxes are selected, no validation will be preformed

The last checkbox is a killer I know. Because we'll have to check for a domain name or www before prepending the http://. But I know if we took out this feature, another 5 people are going to ask next week where it went and want it back. In terms of making things easy for the end-user, I think that this feature prevents a minor annoyance.

Feel free to change the arguments for the validate_link function and add to the return array to accomplish these ends.

RayZ’s picture

I think allowing for internal links is important. After some discussion on the dev list about how to handle greggles' use case in other content, I settled on what has now become the Path Filter module. This filter converts things like internal:node/123 into the proper URL.

For consistency with Path Filter, I would vote for allowing internal:node/123 style URI's to be used in Link fields.

greggles’s picture

RayZ brings up a good point - and it keeps the validation similar enough that we wouldn't need the extra UI junk but would just need to validate URLS either as we do currently OR as "internal:stuff".

@quicksketch - if you agree then I'll work on that.

quicksketch’s picture

Nice, sounds great. It'd be a piece of cake to validate also. I'd recommend that we do not store the 'internal:' part of the URL in the database though, just the path. I'm not sure if you can use other languages with path filter module, but I imagine some users will want to type 'internal' in a different language.

greggles’s picture

Pardon me if I'm dense, but if we don't store the internal: in the DB then how can we tell the difference from

node/3
www.something.com
subdomain.something.com
internal_url.html

quicksketch’s picture

Sounds like it's time for another DB column :). Probably a one bit integer in the node_field_link_data table would do the job. Although it's a little more work now, but down the road it'll be easy to change the syntax (or allow different languages). So on insert, str_replace(t('internal:'),""); and on edit add it back to the default value of the field.

Anonymous’s picture

quicksketch, you mention the following a the top:

you might want to prevent people from starting the URL with a slash ('/') so the Drupal links are valid

Why would that be so? Wouldn't it be a good way to distinguish internal from external link?

Francis

greggles’s picture

I'm basically not interested in pushing this patch forward as long as it uses an internal DB field to keep track of the internal/external.

We've discussed using internal:node/123 as the UI to be consistent with other modules, I think we should keep it that string in the DB as the indicator.

@quicksketch if you agree with that then I can see about working on it. Otherwise, it's up to someone else interested in this feature.

fadeout32’s picture

Title: support for internal URLs » Support for internal URLs

Is this being carried out? It is very necessary functionality in my view, without it links cannot be moved between domains without breaking, which means if you want any sort of test or development environment, you can't use CCK link.

greggles’s picture

@fadeout32 - the patch I provided in the original post will allow internal URLs to work at the cost of losing all validation. That may or may not be a big deal depending on how you use your site.

I'd be willing to add validation for internal:node/10 style links if we could store that whole thing in the DB and add some text to the UI to explain the special meaning of the internal: token on the beginning of the URL. That would allow for keeping the validation for other kinds of URLs.

tanepiper’s picture

While on the subject of the link.module, I would like to see the ability to add a class to a link, maybe using a check box to say "Add class to link" and then a text box to enter the name. This would allow different types of links to be created depending on content type, same with menu items as well (but I've already raised that as a feature request for menu)

greggles’s picture

@Digital Spaghetti - in the issue queue there is no "while on the subject" conversation. If you want a new feature you should file a new feature request.

Please don't pollute this discussion with a separate feature request.

quicksketch’s picture

There's been a lot of activity on the link.module front in the past few days. The patch KarenS put up makes link module utilize CCK's DB schema much better. I think this is still an important feature, which now should be easier to implement (I think). I'll have a look at implementing this feature soon.

quicksketch’s picture

Status: Needs work » Fixed

I revisited all the suggestions made thus far for internal links. Once I implemented preliminary version of the 'internal:' link function I found that both data entry and implementation were a little screwy. Instead I found a little more complicated link checking is really all we need (removing it altogether works also, but I prefer this solution).

Here's the new behavior:
URLs that begin with a protocol OR domain will always be taken as external links so:

Valid External Links:

http://drupal.org
http://drupal.org?param=true#main
drupal.org
drupal.org?param=true#main
<code>

Valid Internal Links:
<code>
sites/drupal.org/themes/favicon.ico
node/5
node/5?param=true#main
<front>
<front>?param=true#main

The one restriction we have is that the first argument or directory of an internal link cannot contain a period. A URL like something.mysite/subdirectory will not be accepted as a valid url, but something/mysite/subdirectory will be rendered as an internal link.

Try out the latest 4.7 development branch or download the nightly snapshot:
http://drupal.org/files/projects/link-4.7.x-1.x.tar.gz

If everything looks good I'll mark as version 1.3.

RayZ’s picture

I haven't looked at the code, but I assume the internal links get run through l() or url() before being passed to the theme functions for output?

The only potential drawback I see to this approach as opposed to using "internal:some/path" is that is impossible to distinguish between a drupal path (which should be run through url()) and a pure relative URL (intended to be put directly in the href attribute). Essentially this approach assumes you never want the latter. I can't think of a reason you would, but I thought I'd mention it just in case.

quicksketch’s picture

In fact, both types of links (absolute and relative) are passed through l(). Absolute links are unaffected, while relative links are converted to absolute and assigned any appropriate alias. The output link will always be a complete URL, ready for insert in a <a> tag.

fadeout32’s picture

Guys? I tried installing the development module and node/xx links are not still valid. Any guidance you could offer?

fadeout32’s picture

Status: Fixed » Active

Hi, I get the following error message when trying to add node/77 to a CCK link:

  • warning: mysql_real_escape_string() expects parameter 1 to be string, array given in /usr/share/drupal/includes/database.mysql.inc on line 350.
  • user warning: Duplicate entry '0' for key 1
    query: INSERT INTO node_content_online_seminar (field_registration__information_url, field_registration__information_title, field_registration__information_attributes, vid, nid) VALUES ('node/77', 'Register online', '', 0, 0) in /usr/share/drupal/includes/database.mysql.inc on line 121.

Is anyone able to offer some assistance?

quicksketch’s picture

fadeout32: Try running update.php as the database schema has changed. If your problem persists please open a new ticket, thanks!

quicksketch’s picture

Status: Active » Fixed

This functionality has been added in the 1.3 release (both 4.7 and 5.0)

Anonymous’s picture

Status: Fixed » Closed (fixed)