Internationalization again

I was complaining in my last Jekyll related post about its lack of i18n support. This is at least partially solved by the jekyll-localization plugin, but it also rewrites file names from the original name.lang.ext to name.ext.lang, a feature I don't like. I proposed a very basic ruby solution to avoid that. It turns out that a simpler and cleaner solution is possible. It was offered to me by Jens Wille one of the author of jekyll-localization. You just have to write the following code in a ruby file in your _plugins directory (code © Jens Wille, available under the terms of the GNU Affero General Public License, version 3 or later):

require 'jekyll/localization'
module Jekyll

  class Page

    # restore standard paths
    %w[url destination process].each { |name|
      alias_method name, "_localization_original_#{name}"
    }

  end

end

Tagging

I got in contact with Jens because I found a very minor bug in his other plugin jekyll-tagging: it would break when a number was used as a tag. I reported the bug and an ugly fix (being a ruby ignorant), and this started some email traffic.

in particular, I showed my (ugly) ruby code that patched jekyll-tagging to suit my i18n strategy. Indeed, the plugin generates tag pages assuming a single language and using a single layout page specified in the _config.yml file in the tag_page_layout variable. I wanted tag pages for all my languages using a layout for each language.

Well, Jens not only fixed my ruby code, he actually refactored jekyll-tagging to facilitate the patching! So if you need something similar to me, you have first to install jekyll-tagging in version 0.4.0 and then to install in tagging.rb in your _plugins directory the following code (code © Jens Wille, available under the terms of the GNU Affero General Public License, version 3 or later):

require 'jekyll/tagging'

module Jekyll

  class Tagger

    alias_method :_apiacoa_original_generate_tag_pages, :generate_tag_pages

    def generate_tag_pages(site)
      unless languages = site.config['languages']
	return _apiacoa_original_generate_tag_pages(site)
      end

      site.tags.each { |tag, posts| languages.each { |lang|
	new_tag(site, tag, posts) { |data|
	  data['tag'], name = tag, "#{tag}.#{lang}"
	  ext = site.layouts[data['layout'] += ".#{lang}"].ext

	  (languages - [lang]).each { |other_lang|
	      data["#{other_lang}-version"] = "#{tag}.#{other_lang}#{ext}"
	  }

	  name
	}
      } }
    end

  end

end

Then add something modeled after the following yaml snippet to your _config.yml:

tag_page_layout: tag_page
tag_page_dir: blog/tag
languages: [fr, en]

As in the original jekyll-tagging plugin, tag_page_dir is the directory in which tag pages will be generated. Then tag_page_layout is the stem of the layouts. For each language (e.g., fr and en in this example), Jekyll will be using tag_page_layout.lang as the actual layout (so tag_page.en and tag_page.fr in my case). Finally, languages is an array of languages used in your blog. The final result is that for each tag in your posts, Jekyll will generate as many tag pages as languages you have specified, using a specific tag page layout for each language.

Thanks a lot to Jens!

Published

20 October 2012

Tags

i18n

jekyll

ruby

tagging