Jekyll: How to generate new Tags on the fly

My site has many snippets of different languages, and I wanted to tag them for CSS purposes among other possible useful things marking them might make possible. One problem with that is I am still searching out the “correct” labelling, so using mutable tags would be easier to remember as well as change later. Time for a new data file, jekyll-root/_data/langs.json, with records that look like so:

    "pyn": {
	"language": "Romanized Chinese-Pin Yin",
	"latag": "zh-Latn"
    },

which I wanted to call like so:

{% la_pyn pinyin text %}

which would generate: <span lang="zh-Latn">pinyin text</span> but how to create a bunch of tags from a data file?

As before, my filter and first tag are actually implemented in the same plugin file.

require 'json'              # to access the json data file outside of the scope of the Jekyll module

module Jekyll
  ######################################################################
  # this is where my *filter* code is, removed for clarity

  # this is where my cantag *tag* is, removed for clarity 
  ######################################################################

  ######################################################################
  # Language tags

  # {% la_chs text to tag %}
  ######################################################################
  class RenderLangTag &lt; Liquid::Tag
    def initialize(tag_name, params, tokens)
      super
      @langkey = tag_name.split("_")[1]               # the "@" makes params global in scope (I think)
      @textstr = params.strip                         # strip trailing whitespace
    end

    def render(context)                                         # render is where the output happens
      langdata = context.registers[:site].data["langs"]         # the incantation required to access the site data
      langrec = langdata[@langkey]                              # getting to my specific langs.json data record
      langtag = langrec['latag']
      return "<span lang=\"#{langtag}\">#{@textstr}</span>"
    end                         # render
  end                           # class RenderLangTag
end                             # Jekyll module

######################################################################
# generate a tag for each language in the code list
######################################################################
langfile = File.read("_data/langs.json")                # accessing the json data file outside of the Jekyll module
langdata = JSON.parse(langfile)                         # parse the contents of the langs.json file

langdata.each_key do |key|                              # loop through all the records
  Liquid::Template.register_tag("la_#{key}", Jekyll::RenderLangTag)      # register a *tag* for each one
end

I realize in retrospect that I could have created basically the same functionality with a single “la” tag and parsed the first 3 characters as a language key, but done is done and it’s more fun this way in any case. 8-)