Eleventy: Customised link rendering in Markdown.

Created on 8 Jun 2019  路  10Comments  路  Source: 11ty/eleventy

Disclaimer: I'm just starting out and building something very simple from scratch.

I have markdown files like index.md that contain all the textual content:

layout: layout.njk
---
# Title
Content here...
[Link3000](/link3000.html) here...

And the layout.njk basically just applies {{ content | safe }} where appropriate.

It's worked pretty well for me so far. But what if I sometimes need customised link rendering?
I mean what if I'd like the published link to open in a new tab

<a href="/link3000.html" target="_blank">Link3000</a>

or even take a step further and automatically insert an image (with the same name as the link title and .gif extension)

<a href="/link3000.html" target="_blank"><img src="img/Link3000.gif">Link3000</a>

I could probably shove pure HTML inside my markdown but that's not really clean nor reusable.
I was dreaming about something along the lines of [Link3000](!/link3000.html) where an extra exclamation mark would trigger the custom logic.

Is something like that possible or recommended?

Most helpful comment

Thank you all. I ended up using markdown-it-link-attributes and a configuration along these lines

  let markdownIt = require("markdown-it");
  let markdownItOptions = {
    html: true
  };
  let mila = require("markdown-it-link-attributes");
  let milaOptions = {
    attrs: {
      target: "_blank",
      rel: "noopener noreferrer"
    }
  };
  let markdownLib = markdownIt(markdownItOptions).use(mila, milaOptions);
  eleventyConfig.setLibrary("md", markdownLib);

All 10 comments

Markdown files are processed by markdown-it, so anything that would need to be done by customizing the markdown-it configuration that your instance of eleventy is using.

You may be able to find an existing markdown-it plugin that supports customized link rendering.

Add markdown-it-attrs to be able to add attributes to your link:
[yourlink](https://linkhref.com) {target="_blank" rel="noreferrer"}

To add both libraries:

  let markdown_o =
  {
    html: true, 
    //: add any settings you need
  }
 eleventyconfig.setLibrary('md',
    require( 'markdown-it' )( markdown_o )
    .use( require( 'markdown-it-attrs' ) )

Thank you all. I ended up using markdown-it-link-attributes and a configuration along these lines

  let markdownIt = require("markdown-it");
  let markdownItOptions = {
    html: true
  };
  let mila = require("markdown-it-link-attributes");
  let milaOptions = {
    attrs: {
      target: "_blank",
      rel: "noopener noreferrer"
    }
  };
  let markdownLib = markdownIt(markdownItOptions).use(mila, milaOptions);
  eleventyConfig.setLibrary("md", markdownLib);
    attrs: {
      target: "_blank",
      rel: "noopener noreferrer"
    }

:100:

I arrived here looking for a way to convert .md links in the input Markdown to links to index.html in the output HTML. See https://github.com/markdown-it/markdown-it/issues/548#issuecomment-623078580 for what I did using markdown-it-replace-link.

You can also use a shortcode for this. See https://github.com/11ty/eleventy/issues/1148.

Here's a configuration that opens every external URL in a new window and ignores the domain your site runs on along with #anchor links when using markdown-it-link-attributes:

attrs: {
  pattern: /^(?!(https:\/\/domain\.com|#)).*$/gm,
  target: '_blank',
  rel: 'noopener noreferrer',
}

Here's a configuration that opens every external URL in a new window and ignores the domain your site runs on along with #anchor links when using markdown-it-link-attributes:

attrs: {
  pattern: /^(?!(https:\/\/domain\.com|#)).*$/gm,
  target: '_blank',
  rel: 'noopener noreferrer',
}

For anyone who comes across this thread in the future, the above configuration didn't work for me. To add rel="noopener noferrer" target="_blank" to all external links move pattern to the same level as attrs:

pattern: /^(?!(https:\/\/domain\.com|#)).*$/gm,
attrs: {
  target: '_blank',
  rel: 'noopener noreferrer',
},

Don't forget to replace the example domain.com in pattern.

There are more examples available in the README for markdown-it-link-attributes

For my site, I used some JavaScript on-load, because not all my input files are markdown.
See https://github.com/binyamin/binyam.in/blob/master/src/js/index.js

@joshbuchea You're absolutely right. The pattern key has to be outside of attrs, thanks for pointing that out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zachleat picture zachleat  路  3Comments

matt-auckland picture matt-auckland  路  3Comments

nilsmielke picture nilsmielke  路  4Comments

nebrelbug picture nebrelbug  路  3Comments

ndaidong picture ndaidong  路  4Comments