Mistress of My Domain

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-)

Post a New Comment






?

Note: for security reasons, a mailto link is being used. If configured on your end, this is the safest way for both parties. This activates your mailer to send the data entered. See here or here for why that might not work and what to do about it.