2015-02-14 21:39:47 +02:00
|
|
|
module Jekyll
|
2016-01-14 04:23:18 +02:00
|
|
|
module Multiple
|
|
|
|
module Languages
|
2015-02-14 21:39:47 +02:00
|
|
|
module Plugin
|
2016-01-14 04:23:18 +02:00
|
|
|
VERSION = "1.2.9"
|
2015-02-14 21:39:47 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module Jekyll
|
2016-01-14 04:23:18 +02:00
|
|
|
class Site
|
|
|
|
def read_directories(dir = '')
|
|
|
|
base = in_source_dir(dir)
|
|
|
|
entries = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
|
|
|
|
|
|
|
|
read_posts(dir)
|
|
|
|
read_drafts(dir) if show_drafts
|
|
|
|
posts.sort!
|
|
|
|
limit_posts! if limit_posts > 0 # limit the posts if :limit_posts option is set
|
|
|
|
|
|
|
|
entries.each do |f|
|
|
|
|
f_abs = in_source_dir(base, f)
|
|
|
|
if File.directory?(f_abs)
|
|
|
|
f_rel = File.join(dir, f)
|
|
|
|
read_directories(f_rel) unless dest.sub(/\/$/, '') == f_abs
|
|
|
|
elsif Utils.has_yaml_header?(f_abs)
|
|
|
|
page = Page.new(self, source, dir, f)
|
|
|
|
pages << page if publisher.publish?(page)
|
|
|
|
else
|
|
|
|
static_files << StaticFile.new(self, source, dir, f)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
pages.sort_by!(&:name)
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_posts(dir)
|
|
|
|
posts = read_content(dir, '_posts', Post)
|
|
|
|
|
|
|
|
posts.each do |post|
|
|
|
|
aggregate_post_info(post) if publisher.publish?(post)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_content(dir, magic_dir, klass)
|
|
|
|
get_entries(dir, magic_dir).map do |entry|
|
|
|
|
klass.new(self, source, dir, entry) if klass.valid?(entry)
|
|
|
|
end.reject do |entry|
|
|
|
|
entry.nil?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_entries(dir, subfolder)
|
|
|
|
base = in_source_dir(dir, subfolder)
|
|
|
|
return [] unless File.exist?(base)
|
|
|
|
entries = Dir.chdir(base) { filter_entries(Dir['**/*'], base) }
|
|
|
|
entries.delete_if { |e| File.directory?(in_source_dir(base, e)) }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
module Jekyll
|
|
|
|
@parsedlangs = {}
|
|
|
|
|
|
|
|
def self.langs
|
|
|
|
@parsedlangs
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.setlangs(l)
|
|
|
|
@parsedlangs = l
|
|
|
|
end
|
|
|
|
|
|
|
|
class Site
|
|
|
|
alias :process_org :process
|
|
|
|
|
|
|
|
def process
|
|
|
|
if !self.config['baseurl']
|
|
|
|
self.config['baseurl'] = ""
|
|
|
|
end
|
|
|
|
#Variables
|
|
|
|
config['baseurl_root'] = self.config['baseurl']
|
|
|
|
baseurl_org = self.config['baseurl']
|
|
|
|
languages = self.config['languages']
|
|
|
|
exclude_org = self.exclude
|
|
|
|
dest_org = self.dest
|
|
|
|
|
|
|
|
#Loop
|
|
|
|
self.config['lang'] = self.config['default_lang'] = languages.first
|
|
|
|
puts
|
|
|
|
puts "Building site for default language: \"#{self.config['lang']}\" to: #{self.dest}"
|
|
|
|
process_org
|
|
|
|
languages.drop(1).each do |lang|
|
|
|
|
|
|
|
|
# Build site for language lang
|
|
|
|
@dest = @dest + "/" + lang
|
|
|
|
self.config['baseurl'] = self.config['baseurl'] + "/" + lang
|
|
|
|
self.config['lang'] = lang
|
|
|
|
|
|
|
|
# exclude folders or files from beeing copied to all the language folders
|
|
|
|
exclude_from_localizations = self.config['exclude_from_localizations'] || []
|
|
|
|
@exclude = @exclude + exclude_from_localizations
|
|
|
|
|
|
|
|
puts "Building site for language: \"#{self.config['lang']}\" to: #{self.dest}"
|
|
|
|
process_org
|
|
|
|
|
|
|
|
#Reset variables for next language
|
|
|
|
@dest = dest_org
|
|
|
|
@exclude = exclude_org
|
|
|
|
|
|
|
|
self.config['baseurl'] = baseurl_org
|
|
|
|
end
|
|
|
|
Jekyll.setlangs({})
|
|
|
|
puts 'Build complete'
|
|
|
|
end
|
|
|
|
|
|
|
|
alias :read_posts_org :read_posts
|
|
|
|
|
|
|
|
def read_posts(dir)
|
|
|
|
if dir == ''
|
|
|
|
read_posts("_i18n/#{self.config['lang']}/")
|
|
|
|
else
|
|
|
|
read_posts_org(dir)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
alias :read_directories_org :read_directories
|
|
|
|
|
|
|
|
def read_directories(dir = '')
|
|
|
|
if dir == ''
|
|
|
|
dir = "_i18n/#{self.config['lang']}/"
|
|
|
|
end
|
|
|
|
|
|
|
|
base = in_source_dir(dir)
|
|
|
|
entries = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
|
|
|
|
|
|
|
|
read_posts(dir)
|
|
|
|
read_drafts(dir) if show_drafts
|
|
|
|
posts.sort!
|
|
|
|
limit_posts! if limit_posts > 0 # limit the posts if :limit_posts option is set
|
|
|
|
|
|
|
|
entries.each do |f|
|
|
|
|
f_abs = in_source_dir(base, f)
|
|
|
|
|
|
|
|
if File.directory?(f_abs)
|
|
|
|
f_rel = File.join(dir, f)
|
|
|
|
read_directories(f_rel) unless dest.sub(/\/$/, '') == f_abs
|
|
|
|
elsif Utils.has_yaml_header?(f_abs) || File.extname(f_abs) == ".md"
|
|
|
|
page = Page.new(self, source, dir, f)
|
|
|
|
pages << page if publisher.publish?(page)
|
|
|
|
else
|
|
|
|
static_files << StaticFile.new(self, source, dir, f)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
pages.sort_by!(&:name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module Convertible
|
|
|
|
def write(dest)
|
|
|
|
lang = self.site.config['lang']
|
|
|
|
default_lang = self.site.config['default_lang']
|
|
|
|
path = destination(dest)
|
|
|
|
dest_path = path
|
|
|
|
|
|
|
|
if path.include?('/_i18n/')
|
|
|
|
start_index = path.index '_i18n/'
|
|
|
|
|
|
|
|
if self.is_a?(Jekyll::Post)
|
|
|
|
end_index = path.index '/posts/'
|
|
|
|
dest_path = path[0..start_index-1] + path[(end_index + 1) .. path.length]
|
|
|
|
elsif self.is_a?(Jekyll::Page)
|
|
|
|
dest_path = path[0..start_index-1] + path[(start_index + 9) .. path.length]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
|
|
|
|
|
|
File.open(dest_path, 'wb') do |f|
|
|
|
|
f.write(output)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Post
|
|
|
|
def url
|
|
|
|
rel_url = URL.new({
|
|
|
|
:template => template,
|
|
|
|
:placeholders => url_placeholders,
|
|
|
|
:permalink => permalink
|
|
|
|
}).to_s
|
|
|
|
|
|
|
|
if rel_url.include?('/_i18n/')
|
|
|
|
start_index = rel_url.index '_i18n/'
|
|
|
|
end_index = rel_url.index '/posts/'
|
|
|
|
rel_url = rel_url[0..start_index-1] + rel_url[(end_index + 1) .. rel_url.length]
|
|
|
|
end
|
|
|
|
|
|
|
|
@url ||= rel_url
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class StaticFile
|
|
|
|
def write(dest)
|
|
|
|
dest_path = destination(dest)
|
|
|
|
|
|
|
|
orig_path = dest_path
|
|
|
|
if dest_path.include?('/_i18n/')
|
|
|
|
start_index = dest_path.index '_i18n/'
|
|
|
|
dest_path = dest_path[0..start_index-1] + dest_path[(start_index + 9) .. dest_path.length]
|
|
|
|
end
|
|
|
|
|
|
|
|
# p "#{self.class} #{dest_path}"
|
|
|
|
|
|
|
|
return false if File.exist?(dest_path) and !modified?
|
|
|
|
@@mtimes[path] = mtime
|
|
|
|
|
|
|
|
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
|
|
FileUtils.rm(dest_path) if File.exist?(dest_path)
|
|
|
|
FileUtils.cp(path, dest_path)
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-14 21:39:47 +02:00
|
|
|
class LocalizeTag < Liquid::Tag
|
|
|
|
|
|
|
|
def initialize(tag_name, key, tokens)
|
|
|
|
super
|
|
|
|
@key = key.strip
|
|
|
|
end
|
|
|
|
|
|
|
|
def render(context)
|
|
|
|
if "#{context[@key]}" != "" #Check for page variable
|
|
|
|
key = "#{context[@key]}"
|
|
|
|
else
|
|
|
|
key = @key
|
|
|
|
end
|
2016-01-14 04:23:18 +02:00
|
|
|
lang = context.registers[:site].config['lang']
|
|
|
|
unless Jekyll.langs.has_key?(lang)
|
|
|
|
puts "Loading translation from file #{context.registers[:site].source}/_i18n/#{lang}.yml"
|
|
|
|
Jekyll.langs[lang] = YAML.load_file("#{context.registers[:site].source}/_i18n/#{lang}.yml")
|
|
|
|
end
|
|
|
|
translation = Jekyll.langs[lang].access(key) if key.is_a?(String)
|
|
|
|
if translation.nil? or translation.empty?
|
|
|
|
translation = Jekyll.langs[context.registers[:site].config['default_lang']].access(key)
|
|
|
|
puts "Missing i18n key: #{lang}:#{key}"
|
|
|
|
puts "Using translation '%s' from default language: %s" %[translation, context.registers[:site].config['default_lang']]
|
|
|
|
end
|
2016-01-17 22:03:02 +02:00
|
|
|
site = context.registers[:site]
|
|
|
|
if translation.include? '@'
|
|
|
|
converter = site.find_converter_instance(::Jekyll::Converters::Markdown)
|
|
|
|
translation = converter.convert(translation)[3..-6]
|
|
|
|
end
|
2016-01-14 04:23:18 +02:00
|
|
|
translation
|
|
|
|
end
|
|
|
|
end
|
2015-02-14 21:39:47 +02:00
|
|
|
|
2016-01-14 04:23:18 +02:00
|
|
|
module Tags
|
|
|
|
class LocalizeInclude < IncludeTag
|
|
|
|
def render(context)
|
|
|
|
if "#{context[@file]}" != "" #Check for page variable
|
|
|
|
file = "#{context[@file]}"
|
|
|
|
else
|
|
|
|
file = @file
|
|
|
|
end
|
2015-02-14 21:39:47 +02:00
|
|
|
|
2016-01-14 04:23:18 +02:00
|
|
|
includes_dir = File.join(context.registers[:site].source, '_i18n/' + context.registers[:site].config['lang'])
|
2015-02-14 21:39:47 +02:00
|
|
|
|
2016-01-14 04:23:18 +02:00
|
|
|
if File.symlink?(includes_dir)
|
|
|
|
return "Includes directory '#{includes_dir}' cannot be a symlink"
|
|
|
|
end
|
|
|
|
if file !~ /^[a-zA-Z0-9_\/\.-]+$/ || file =~ /\.\// || file =~ /\/\./
|
|
|
|
return "Include file '#{file}' contains invalid characters or sequences"
|
|
|
|
end
|
2015-02-14 21:39:47 +02:00
|
|
|
|
2016-01-14 04:23:18 +02:00
|
|
|
Dir.chdir(includes_dir) do
|
|
|
|
choices = Dir['**/*'].reject { |x| File.symlink?(x) }
|
|
|
|
if choices.include?(file)
|
|
|
|
source = File.read(file)
|
|
|
|
partial = Liquid::Template.parse(source)
|
2015-02-21 13:02:12 +02:00
|
|
|
|
2016-01-14 04:23:18 +02:00
|
|
|
context.stack do
|
|
|
|
context['include'] = parse_params(context) if @params
|
|
|
|
contents = partial.render(context)
|
|
|
|
site = context.registers[:site]
|
|
|
|
ext = File.extname(file)
|
|
|
|
|
|
|
|
converter = site.converters.find { |c| c.matches(ext) }
|
|
|
|
contents = converter.convert(contents) unless converter.nil?
|
|
|
|
|
|
|
|
contents
|
|
|
|
end
|
|
|
|
else
|
|
|
|
"Included file '#{file}' not found in #{includes_dir} directory"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2015-02-14 21:39:47 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
unless Hash.method_defined? :access
|
|
|
|
class Hash
|
|
|
|
def access(path)
|
|
|
|
ret = self
|
|
|
|
path.split('.').each do |p|
|
|
|
|
if p.to_i.to_s == p
|
|
|
|
ret = ret[p.to_i]
|
|
|
|
else
|
|
|
|
ret = ret[p.to_s] || ret[p.to_sym]
|
|
|
|
end
|
|
|
|
break unless ret
|
|
|
|
end
|
|
|
|
ret
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Liquid::Template.register_tag('t', Jekyll::LocalizeTag)
|
|
|
|
Liquid::Template.register_tag('translate', Jekyll::LocalizeTag)
|
2016-01-14 04:23:18 +02:00
|
|
|
Liquid::Template.register_tag('tf', Jekyll::Tags::LocalizeInclude)
|
|
|
|
Liquid::Template.register_tag('translate_file', Jekyll::Tags::LocalizeInclude)
|