Custom Liquid Tags

March 30, 2016

Coming back to Jekyll from Hugo, I’d grown accus­tomed to short­codes, which are awe­some to keep your Mark­down source as HTML-free as pos­si­ble. You can emu­late short­codes with custom liquid tags!

In your _plugins folder, create a new file, and then write a class that inher­its from Liquid::Tag. Let’s see an exam­ple below of a tag for embed­ding Youtube videos:

class YoutubeTag < Liquid::Tag
  def initialize(tag_name, arg, tokens)
    super # mandatory
    # fill in some awesome codez
  end

  def render(context)
    <<-MARKUP.strip
    # more awesome codez
    MARKUP
  end
end

# register the tag
Liquid::Template.register_tag('youtube', MyTag)

The gen­er­al thing to take note of here is that what­ev­er appears after the tag name will be stringi­fied and sent to the second argu­ment of initialize, so for exam­ple, a custom tag that looks like:

{% raw %}
{% my_tag lol this is a tag %}
{% endraw %}

args in the initialize method above will be lol this is a tag (note the trail­ing white­space). There’s no fur­ther treat­ment, so you will have to parse the string your­self some­how to iden­ti­fy what is what, and then assign what you need to instance vari­ables:

def initialize(tag_name, arg, tokens)
  super
  @youtube_id, @width, @height = arg.split
end

The class must also imple­ment a render method, which returns a string rep­re­sen­ta­tion of the HTML, so in this case of Youtube embeds:

def render(context)
  <<-MARKUP.strip
    <iframe id="ytplayer" type="text/html" width="#{@width}" height="#{@height}" src="http://www.youtube.com/embed/#{@youtube_id} frameborder="0"/>
  MARKUP
end

And voila! You can now use your Youtube tag like so:

{% raw %}
{% youtube M7lc1UVf-VE 600 400 %}
{% endraw %}

Great suc­cess 👍