Coming back to Jekyll from Hugo, I’d grown accustomed to shortcodes, which are awesome to keep your Markdown source as HTML-free as possible. You can emulate shortcodes with custom liquid tags!

In your _plugins folder, create a new file, and then write a class that inherits from Liquid::Tag. Let’s see an example below of a tag for embedding 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 general thing to take note of here is that whatever appears after the tag name will be stringified and sent to the second argument of initialize, so for example, a custom tag that looks like:


{% my_tag lol this is a tag %}

args in the initialize method above will be lol this is a tag (note the trailing whitespace). There’s no further treatment, so you will have to parse the string yourself somehow to identify what is what, and then assign what you need to instance variables:

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

The class must also implement a render method, which returns a string representation 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:


{% youtube M7lc1UVf-VE 600 400 %}

Great success 👍