Opening External Links in New Windows / Tabs by Default

I’d like to configure XWiki to open all external links in new Windows / Tabs, i.e. with ‘target=“_blank”’.

The first think I found concerning this was JIRA XWIKI-1217, according to which I should configure the following setting in xwiki.cfg:

xwiki.render.externallinks.defaulttarget=_blank

This did not work at all however, and I don’t seem to be the only one having trouble with this:

http://lists.xwiki.org/pipermail/users/2014-April/027972.html

So it probably just isn’t supported any more, I guess.

An alternative approach I stumbled accross uses JavaScript to “patch” all links on the page after loading:

Ok, obviously can be done this way, but does not appear to me as a really elegant solution…

So is this the recommended way to go for recent XWiki versions, or did I miss something obvious?

I searched some time for this and found the easiest solution was to throw a small jQuery script on a page.

I’ll list my detailed steps in case anyone who comes across this post needs them (something I, as a newbie, wish everyone did!).

Verified working in 11.3

  1. Create a new page, or go to an existing page that won’t be removed
  2. Click Edit and select Objects.
  3. In the Select a Class box, select JavaScriptExtension and click the Add button.
  4. In the object that just appeared, enter the following code into the Code box:
    require(['jquery'], function($) {
      jQuery(document.links).filter(function() {
        return this.hostname != window.location.hostname;
      }).attr('target', '_blank');
    });
    
  5. Set Use this extension to On this wiki.

This identifies all external links by comparing them to the current window URL. If the link goes to a different domain, it adds the target="_blank" attribute to its HTML a tag, which will open it in a new window when clicked on.

It might seem elementary to some, but this is what I found that works for me.

Hope it helps!

@thedelk Awesome. Sounds like something that would fit perfectly for a FAQ entry at https://www.xwiki.org/xwiki/bin/view/FAQ/ ! :slight_smile: Would you like to add it there?

@thedelk Actually your implementation is not the best possible. It’s a bit too performance-intensive and it doesn’t need to. You should just look for external links which are identified in the HTML DOM with the “wikiexternallink” class.

See [solved] External links, set default target as "_blank" - #21 by laurin1

Thanks

1 Like

@vmassol: Yes, that’s the snipped from the forum thread I linked to and that’s also how I solved it for now - works fine, I just wanted to know if there was any more elegant or “more official” way to do so. :slight_smile:

There’s no other way, it’s the recommended way on the web AFAIK. Only thing that could be better for xwiki users is to bundle this script in the XWiki Standard distribution and offer a feature in the Admin UI to configure it. You could create a jira for this if you want (maybe there’s one already?).

cool, thanks!

Darn. I was going to do it, but I guess @GOhrner woke up earlier than me today. :upside_down_face:

That snippet does make more sense. I had planned to go back and rewrite some of the objects on my wiki once I got everything in place, so thanks @vmassol for saving me some time!

A quick note, for anyone who may happen upon this post:

This code in the FAQ article will only work if the link has a parent element with the wikiexternallink class.

Summary
function fixExternalLinks() {
  var nodes = document.querySelectorAll('.wikiexternallink a');
  for(var i=0; i< nodes.length; i++){
    var link = nodes[i];
    if (link.hasAttribute('target') == false)  {
      link.setAttribute('target', '_blank');
    }
  }
}
document.addEventListener("DOMContentLoaded", fixExternalLinks);

These are rendered by default when using Wiki syntax to create the link, e.g. [[http://xwiki.org]] or [[XWiki>>http://xwiki.org]].

However, if you are directly writing HTML, either through the {{html}} macro or directly in a Velocity .vm file, you will need to manually wrap your links in an element with that class. Otherwise, the link has nothing that the snippet can use to identify it as an external link.

You can use the jQuery code to work for all links without having to add the extra parent element. As @vmassol pointed out, it’s not the most performant solution, but the impact is pretty negligible. I tested them both on a page with about 400 external links and saw no difference in load times.

Summary
require(['jquery'], function($) {
  jQuery(document.links).filter(function() {
    return this.hostname != window.location.hostname;
  }).attr('target', '_blank');
});

I’ve updated the FAQ article with this information.

Mh, good point.

Is jQuery always automatically available in every XWiki instance?

Yep! They’re automatically included as Webjars.

You just have to make sure to use RequireJS to load it when you need it.

Can this be turned into an extension, that one can install? Even if it consists of a few lines of code, I’d much prefer something to install rather than something I have to manually add.