linktag.rb
I wrote a custom Liquid tag for writing standalone links with their associated metadata like so:
<a href="http://url" title="title • subtitle • date • author • site">title</a> • subtitle • date • author • site
…using this syntax:
{% link url: "url", title: "title", subtitle: "subtitle", date: "date", author: "author", site: "site" %}
All the parameters except for the URL and the title are optional (although you probably don’t need this tag if that’s all you’re going to use anyway.) You can also include variables instead of strings. And you can put Liquid tags inside the strings.
{% link url: post.url, title: post.title, date: post.date, author: post.author, site: site.title %}
{% link url: "url", title: "{{ post.title }} • {{ post.description }}", date: "date", site: site.title %}
Place the following file in the _plugins
directory:
module Jekyll
class LinkTag < Liquid::Tag
include Jekyll::LiquidExtensions
def initialize(tag_name, markup, tokens)
super
@attributes = { 'separator' => ' • ' }
markup.scan(Liquid::TagAttributes) do |key, value|
@attributes[key] = value
end
end
def expression_parse(context, markup)
case markup
when /\A'(.*)'\z/m # Single quoted strings
$1
when /\A"(.*)"\z/m # Double quoted strings
$1
else
lookup_variable(context, markup)
end
end
def render(context)
url = expression_parse(context, @attributes['url'])
attribute_list = [@attributes['title'], @attributes['subtitle'], @attributes['date'], @attributes['author'], @attributes['site']].reject{ |attribute| attribute.nil? or attribute.empty? }
attribute_list.map! { |attribute|
Liquid::Template.parse(expression_parse(context, attribute)).render(context)
}
html = [%Q(<a href="#{url}" title="#{attribute_list.join(@attributes['separator'])}">#{attribute_list.first}</a>), attribute_list.drop(1)].join(@attributes['separator'])
end
end
end
Liquid::Template.register_tag('link', Jekyll::LinkTag)
At the very least, this can serve as an example of how to parse named tag parameters and how to pass variable names