Skip to content

Develop an easier way to include external links in articles' content. #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
5 tasks
keithmifsud opened this issue May 10, 2018 · 4 comments
Closed
5 tasks
Assignees

Comments

@keithmifsud
Copy link
Contributor

keithmifsud commented May 10, 2018

I'll develop an include that takes variables for the anchor's link options.

Update as per #GH-83

  • Look into extending Jekyll or the MD processor so that all external links are automatically opened in a new window and have the correct "rel" attribute.

  • Develop the feature and run integration tests.

  • Bear in mind and check previous posts.

  • Remove the include from the previous PR.

  • Updated the docs. Possibly just remove the content from the previous PR.

@keithmifsud
Copy link
Contributor Author

@danielepolencic, In brief, I want to either refactor the URL's once Jekyll has rendered the _site using the post_render hook, meaning the links will already be in html format. Or else, generate the html from markup before Jekyll builds the _site using the (I think) pre_render hook. Both methods will require a condition to check if the host matches the site.url.

I have found this @mentions plugin that I think works the same way I need mine to work. Although, I'm still not sure because ...

This plugin uses the html/pipeline gem and the part of it which handles URLs uses rinku gem. As I understand rinku will process anchor tags but text that matches a URL.

To explain my workflow: I am building a separate Gem in a Ruby Editor (because it helps) and also so that I can TDD and then I'm copying the code inside our site's _plugin directory. I had to run gem install for the dependencies (i.e: rinku and htm/pipeline). Not sure how Netlify handles this. Jekyll required the manual installation.

Please bear in mind that I'm still not sure this way will work due to Rinku. Other options are:

  1. Using JS on the client-side
  2. Jekyll (liquid) now supports arguments to the url tag such as:
[LINK](http:link.com){:target"_blank"}

Thoughts?

@keithmifsud
Copy link
Contributor Author

_This is my work in progress:

_The Gem class

require 'jekyll-auto-link/version'
require 'jekyll'
require 'html/pipeline'

module Jekyll
  class AutoLink

    BODY_START_TAG = "<body"
    OPENING_BODY_TAG_REGEX = %r!<body(.*)>\s*!
  
    InvalidJekyllConfig = Class.new(Jekyll::Errors::FatalException)

    class << self
      def linkify(doc)
        content = doc.output
        return unless content.include?('<a')
        src = base_url(doc.site.config)
        if content.include? BODY_START_TAG
          head, opener, tail = content.partition(OPENING_BODY_TAG_REGEX)
          body_content, *rest = tail.partition('</body>')

          processed_markup = filter_with_link(src).call(body_content)[:output].to_s
          doc.output = String.new(head) << opener << processed_markup << rest.join
        end
      end

      def filter_with_link(src)
        filters[src] ||= HTML::Pipeline.new([
            HTML::Pipeline::AutolinkFilter,
        ], {:autolink => true, :link_attr => 'target="_blank"'})
      end

      def filters
        @filters ||= {}
      end

      def base_url(config = {})
        url = config['url']
        case url
        when String
          url.to_s

        else
          raise InvalidJekyllConfig,
                'Site URL is required in config.'

        end
      end
    end
  end
end
Jekyll::Hooks.register %i[pages documents], :post_render do |doc|
  Jekyll::AutoLink.linkify(doc)
end

@keithmifsud
Copy link
Contributor Author

If I add the code to the _plugins file without the rewuirements at the top I get errors as the HTML::PIpeline is not found. If I just require "html/pipeline", I get an error that Rinku is not found, even though it is not a direct dependency but rather a dependency of "html/pipeline".

In all cases I had to manually install both gems on LearnK8s.

gem install html/pipeline && gem install rinku

@danielepolencic
Copy link
Contributor

I think this article is suggesting that you could simply add a custom converter: http://tbrink.science/blog/2017/04/23/typographic-improvements-for-jekyll-kramdown/

_plugins/open_in_tab.rb:

class Kramdown::Converter::TBHtml < Kramdown::Converter::Html
  def convert_a(el, indent)
    el["target"] = "_blank"
    super(el, indent)
  end
end

class Jekyll::Converters::Markdown
  class KramdownTB < KramdownParser
    def convert(content)
      Kramdown::Document.new(content, @config).to_t_b_html
    end
  end
end

You should add markdown: KramdownTB to your _config.yml. Don't forget to delete your _site folder before you try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants