Last active
August 29, 2015 14:01
-
-
Save sp3c73r2038/f2ddcc0f386bcea2964f to your computer and use it in GitHub Desktop.
multilingualism support for jekyll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# example | |
# . | |
# |-- about.md | |
# |-- _config.yml | |
# |-- css | |
# | `-- main.css | |
# |-- feed.xml | |
# |-- .gitignore | |
# |-- _includes | |
# | |-- footer.html | |
# | |-- header.html | |
# | `-- head.html | |
# |-- index.html | |
# |-- _layouts | |
# | |-- default.html | |
# | |-- page.html | |
# | `-- post.html | |
# |-- _plugins | |
# | `-- multilingualism.rb | |
# |-- _posts | |
# | |-- 2014-05-12-hello-world.en.md | |
# | |-- 2014-05-12-hello-world.ja.md | |
# | `-- 2014-05-13-hello-world.md | |
# `-- _site | |
# |-- about | |
# | `-- index.html | |
# |-- css | |
# | `-- main.css | |
# |-- en | |
# | `-- 2014 | |
# | `-- 05 | |
# | `-- 12 | |
# | `-- hello-world | |
# | `-- index.html | |
# |-- feed.xml | |
# |-- index.html | |
# `-- ja | |
# `-- 2014 | |
# `-- 05 | |
# `-- 12 | |
# `-- hello-world | |
# `-- index.html | |
# | |
# 18 directories, 22 files | |
# require 'jekyll/mpultiple/languages/plugin' | |
module Jekyll | |
class Site | |
attr_accessor :i18n | |
alias :process_orig :process | |
def process() | |
i18n_config = "#{self.source}/_i18n.yml" | |
if File.exists? i18n_config | |
@i18n = YAML.load(File.read(i18n_config)) | |
p @i18n | |
else | |
Jekyll.logger.warn "Your site lacks a _i18n.yml config, it's required for multilingualism plugin." | |
end | |
process_orig | |
end | |
end | |
class Post | |
LANG_MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*?)(\.[\w]{2})?(\.[^.]+)$/ | |
attr_accessor :lang | |
alias :process_orig :process | |
def process(name) | |
m, cats, date, slug, lang, ext = *name.match(LANG_MATCHER) | |
self.date = Time.parse(date) | |
self.slug = slug | |
self.ext = ext | |
self.lang = (lang && lang.gsub('.', '')) || site.config['languages'].first | |
rescue ArgumentError | |
path = File.join(@dir || "", name) | |
msg = "Post '#{path}' does not have a valid date.\n" | |
msg << "Fix the date, or exclude the file or directory from being processed" | |
raise FatalException.new(msg) | |
end | |
def path_in_lang(lang) | |
path.gsub(".#{@lang}", "").gsub("#{ext}", "") + ".#{lang}" + ext | |
end | |
def path_without_lang | |
path.gsub(".#{@lang}", "") | |
end | |
def in_language?(lang) | |
return true if lang == self.lang | |
return true if File.exists? path_in_lang(lang) | |
(lang == site.config['languages'].first) && (File.exists? path_without_lang) | |
end | |
def template | |
case site.permalink_style | |
when :pretty | |
"/:lang/:categories/:year/:month/:day/:title/" | |
when :none | |
"/:lang/:categories/:title.html" | |
when :date | |
"/:lang/:categories/:year/:month/:day/:title.html" | |
when :ordinal | |
"/:lang/:categories/:year/:y_day/:title.html" | |
else | |
site.permalink_style.to_s | |
end | |
end | |
def url_placeholders | |
{ | |
:year => date.strftime("%Y"), | |
:month => date.strftime("%m"), | |
:day => date.strftime("%d"), | |
:title => slug, | |
:i_day => date.strftime("%d").to_i.to_s, | |
:i_month => date.strftime("%m").to_i.to_s, | |
:categories => (categories || []).map { |c| c.to_s }.join('/'), | |
:short_month => date.strftime("%b"), | |
:short_year => date.strftime("%y"), | |
:y_day => date.strftime("%j"), | |
:output_ext => output_ext, | |
:lang => @lang | |
} | |
end | |
end | |
class Page | |
LANG_MATCHER = /^(.*?)(\.[\w]{2})?(\.[^.]+)$/ | |
attr_accessor :lang | |
alias :process_orig :process | |
def process(name) | |
m, basename, lang, ext = *name.match(LANG_MATCHER) | |
self.basename = basename | |
self.lang = (lang && lang.gsub('.', '')) || site.config['languages'].first | |
self.ext = ext | |
end | |
def path_in_lang(lang) | |
path.gsub(".#{@lang}", "").gsub("#{ext}", "") + ".#{lang}" + ext | |
end | |
def path_without_lang | |
path.gsub(".#{@lang}", "") | |
end | |
def in_language?(lang) | |
File.exists? path_in_lang(lang) | |
return true if lang == self.lang | |
return true if File.exists? path_in_lang(lang) | |
(lang == site.config['languages'].first) && (File.exists? path_without_lang) | |
end | |
def template | |
if site.permalink_style == :pretty | |
if index? && html? | |
"/:path/" | |
elsif html? | |
"/:lang/:path/:basename/" | |
elsif excluded? | |
"/:path/:basename:output_ext" | |
else | |
"/:lang/:path/:basename:output_ext" | |
end | |
else | |
"/:lang/:path/:basename:output_ext" | |
end | |
end | |
def url_placeholders | |
{ | |
:path => @dir, | |
:basename => basename, | |
:output_ext => output_ext, | |
:lang => lang | |
} | |
end | |
def excluded? | |
site.config['multilingual_exclude'].include? name | |
end | |
end | |
module Convertible | |
def write(dest) | |
path = destination(dest) | |
FileUtils.mkdir_p(File.dirname(path)) | |
File.open(path, 'wb') do |f| | |
f.write(output) | |
end | |
end | |
end | |
class LocalizeTag < Liquid::Tag | |
def initialize(tag_name, params, tokens) | |
super | |
@key, @lang = params.strip.split(' ') | |
end | |
def render(context) | |
lang = @lang || context.registers[:site].config['languages'].first | |
if (context.registers[:site].i18n.include? @key) && | |
(context.registers[:site].i18n[@key].include? lang) | |
context.registers[:site].i18n[@key][lang] | |
else | |
raise KeyError.new "I found no key: #{@key} in #{lang} defined in _i18n.yml" | |
end | |
end | |
end | |
end | |
Liquid::Template.register_tag('t', Jekyll::LocalizeTag) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With multilingual plugin, posts/pages should be named in
yyyy-mm-dd-foo-bar.#{lang}.ext
form, which#{lang}
is the ISO 639 codes. Posts/pages which lack a#{lang}
part is considered as in default language.use
in_language?(lang)
method to check if the post is in the corresponding language (useful when show link in templates).