Simon
Simon

Reputation: 25983

How do I make link_to open external URLs in a new window?

I need to convert a rails 2.3 site so that all external URLs open in a new window. I could go though every call to link_to and add :target => '_blank', but I'd like to do it in one step for all links, present and future. Is there a way I can monkey patch link_to to get the desired behaviour?

Upvotes: 19

Views: 20307

Answers (4)

Ameen
Ameen

Reputation: 318

In rails 3.2+, it has been added as an option, just add

= link_to 'facebook', 'http://www.facebook.com/fb-page', target: '_blank'

and it'll open the link in a new tab.

Upvotes: 2

Simon
Simon

Reputation: 25983

In the end I went with this, in an initialiser:

module ExternalLinksInNewTabs
  def new_tab_link_to *args, &block
    if block_given?
      options = args.first || {}
      html_options = args[1] || {}

      if options.is_a? String
        if ExternalLinksInNewTabs.is_external_link? @controller.request.host, options
          html_options[:target] = '_BLANK'
        end
      end

      same_tab_link_to options, html_options, &block
    else
      name = args.first
      options = args[1] || {}
      html_options = args[2] || {}

      if options.is_a? String
        if ExternalLinksInNewTabs.is_external_link? @controller.request.host, options
          html_options[:target] = '_BLANK'
        end
      end

      same_tab_link_to name, options, html_options
    end
  end

  def self.is_external_link? host, url
    host.sub! /^www\./, ''
    url =~ /^http/i && url !~ /^http:\/\/(www\.)?#{host}/i
  end
end

module ActionView
  module Helpers
    module UrlHelper
      include ExternalLinksInNewTabs

      alias_method :same_tab_link_to, :link_to
      alias_method :link_to, :new_tab_link_to
    end
  end
end

Upvotes: 4

Nicolas Blanco
Nicolas Blanco

Reputation: 11299

You should not have to change your server-side code for this view problem.

You should use Unobscursive javascript. This example will only make external links showing up in a new window :

// jQuery
//
$(document).ready(function() {
  $("a").click(function() {
    link_host = this.href.split("/")[2];
    document_host = document.location.href.split("/")[2];

    if (link_host != document_host) {
      window.open(this.href);
      return false;
    }
  });
});

Upvotes: 17

shingara
shingara

Reputation: 46914

You just add an helper to add this options in your link_to

If you want add it on each link_to to can add on ApplicationHelper

def link_to(*args, &block)
  if block_given?
    args = [(args.first || {}), (args.second || {}).merge(:target => '_blank')]
  else
    args = [(args.first || {}), (args.second || {}), (args.third || {}).merge(:target => '_blank')]
  end
  super(args, block)
end

Or you can create your own link_to helper

def link_to_blank(*args, &block)
  if block_given?
    args = [(args.first || {}), (args.second || {}).merge(:target => '_blank')]
  else
    args = [(args.first || {}), (args.second || {}), (args.third || {}).merge(:target => '_blank')]
  end
  link_to(args, block)
end

Upvotes: 3

Related Questions