Jekyll: produce custom HTML for external links (target and CSS class)

4.1k views Asked by At

I understand that the target attribute of an <a> link cannot be specified by CSS. I would like to be able to generate external links in a Jekyll based markdown document with the following output:

<a href="the-url" class="external" target="_blank">the text</a>

without resorting to something like this:

[the text](the url){:target"_blank" class="external"}

I don't want to hard-code the target in each link, because I might want to change it at some point, also it's noisy. So ideally I would have

[the text](the url){:class="external"}

...but then CSS cannot add the target="_blank".

So my idea would be a custom plugin that allows me to write

{% ext-link the-url the text %}

Does such a plugin exist? Are there better ways to achieve this?

4

There are 4 answers

0
0__ On BEST ANSWER

It seems writing a plugin is straight forward. This is what I have come up with:

module Jekyll
  class ExtLinkTag < Liquid::Tag
    @text = ''
    @link = ''

    def initialize(tag_name, markup, tokens)
      if markup =~ /(.+)(\s+(https?:\S+))/i
        @text = $1
        @link = $3
      end
      super
    end

    def render(context)
      output = super
      "<a class='external' target='_blank' href='"+@link+"'>"+@text+"</a>"
    end
  end
end

Liquid::Template.register_tag('extlink', Jekyll::ExtLinkTag)

Example usage:

Exhibition at {% extlink Forum Stadtpark http://forum.mur.at %}.

HTML output:

<p>Exhibition at <a class="external" target="_blank" href="http://forum.mur.at">Forum Stadtpark</a>.</p>
0
David Jacquel On

When you need to do this on Github pagesand then cannot use plugins, you can do it with javascript :

// any link that is not part of the current domain is modified

(function() {
  var links = document.links;
  for (var i = 0, linksLength = links.length; i < linksLength; i++) {
    // can also be
    //  links[i].hostname != 'subdomain.example.com'
    if (links[i].hostname != window.location.hostname) {
      links[i].target = '_blank';
      links[i].className += ' externalLink';
    }
  }
})();

Inspired by this answer.

0
Keith Mifsud On

My plugin can automatically force all external links to open in a new browser.

https://keith-mifsud.me/projects/jekyll-target-blank

And as of v1.1.0 you can also add optional extra CSS class names.

1
nourish On

There is a small Jekyll plugin to apply target="_blank", rel="nofollow", class names, and any other attributes of your choice to external links automatically:

Jekyll ExtLinks Plugin

A list of hosts to be skipped when applying rel can be configured if you want to keep some links untouched. This way, you don't have to mangle with Markdown anymore.

UPD: This plugin has been released to RubyGems now: jekyll-extlinks. Use gem install jekyll-extlinks to install it. Also available on GitHub.