multiple-languages.rb 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. module Jekyll
  2. @parsedlangs = {}
  3. def self.langs
  4. @parsedlangs
  5. end
  6. def self.setlangs(l)
  7. @parsedlangs = l
  8. end
  9. class Site
  10. alias :process_org :process
  11. def process
  12. if !self.config['baseurl']
  13. self.config['baseurl'] = ""
  14. end
  15. #Variables
  16. config['baseurl_root'] = self.config['baseurl']
  17. baseurl_org = self.config['baseurl']
  18. languages = self.config['languages']
  19. dest_org = self.dest
  20. #Loop
  21. self.config['lang'] = self.config['default_lang'] = languages.first
  22. puts
  23. puts "Building site for default language: \"#{self.config['lang']}\" to: #{self.dest}"
  24. process_org
  25. languages.drop(1).each do |lang|
  26. # Build site for language lang
  27. self.dest = self.dest + "/" + lang
  28. self.config['baseurl'] = self.config['baseurl'] + "/" + lang
  29. self.config['lang'] = lang
  30. puts "Building site for language: \"#{self.config['lang']}\" to: #{self.dest}"
  31. process_org
  32. #Reset variables for next language
  33. self.dest = dest_org
  34. self.config['baseurl'] = baseurl_org
  35. end
  36. Jekyll.setlangs({})
  37. puts 'Build complete'
  38. end
  39. alias :read_posts_org :read_posts
  40. def read_posts(dir)
  41. if dir == ''
  42. read_posts("_i18n/#{self.config['lang']}/")
  43. else
  44. read_posts_org(dir)
  45. end
  46. end
  47. end
  48. class LocalizeTag < Liquid::Tag
  49. def initialize(tag_name, key, tokens)
  50. super
  51. @key = key.strip
  52. end
  53. def render(context)
  54. if "#{context[@key]}" != "" #Check for page variable
  55. key = "#{context[@key]}"
  56. else
  57. key = @key
  58. end
  59. lang = context.registers[:site].config['lang']
  60. unless Jekyll.langs.has_key?(lang)
  61. puts "Loading translation from file #{context.registers[:site].source}/_i18n/#{lang}.yml"
  62. Jekyll.langs[lang] = YAML.load_file("#{context.registers[:site].source}/_i18n/#{lang}.yml")
  63. end
  64. translation = Jekyll.langs[lang].access(key) if key.is_a?(String)
  65. if translation.nil? or translation.empty?
  66. translation = Jekyll.langs[context.registers[:site].config['default_lang']].access(key)
  67. puts "Missing i18n key: #{lang}:#{key}"
  68. puts "Using translation '%s' from default language: %s" %[translation, context.registers[:site].config['default_lang']]
  69. end
  70. translation
  71. end
  72. end
  73. module Tags
  74. class LocalizeInclude < IncludeTag
  75. def render(context)
  76. if "#{context[@file]}" != "" #Check for page variable
  77. file = "#{context[@file]}"
  78. else
  79. file = @file
  80. end
  81. includes_dir = File.join(context.registers[:site].source, '_i18n/' + context.registers[:site].config['lang'])
  82. if File.symlink?(includes_dir)
  83. return "Includes directory '#{includes_dir}' cannot be a symlink"
  84. end
  85. if file !~ /^[a-zA-Z0-9_\/\.-]+$/ || file =~ /\.\// || file =~ /\/\./
  86. return "Include file '#{file}' contains invalid characters or sequences"
  87. end
  88. Dir.chdir(includes_dir) do
  89. choices = Dir['**/*'].reject { |x| File.symlink?(x) }
  90. if choices.include?(file)
  91. source = File.read(file)
  92. partial = Liquid::Template.parse(source)
  93. context.stack do
  94. context['include'] = parse_params(context) if @params
  95. contents = partial.render(context)
  96. site = context.registers[:site]
  97. ext = File.extname(file)
  98. converter = site.converters.find { |c| c.matches(ext) }
  99. contents = converter.convert(contents) unless converter.nil?
  100. contents
  101. end
  102. else
  103. "Included file '#{file}' not found in #{includes_dir} directory"
  104. end
  105. end
  106. end
  107. end
  108. end
  109. end
  110. unless Hash.method_defined? :access
  111. class Hash
  112. def access(path)
  113. ret = self
  114. path.split('.').each do |p|
  115. if p.to_i.to_s == p
  116. ret = ret[p.to_i]
  117. else
  118. ret = ret[p.to_s] || ret[p.to_sym]
  119. end
  120. break unless ret
  121. end
  122. ret
  123. end
  124. end
  125. end
  126. Liquid::Template.register_tag('t', Jekyll::LocalizeTag)
  127. Liquid::Template.register_tag('translate', Jekyll::LocalizeTag)
  128. Liquid::Template.register_tag('tf', Jekyll::Tags::LocalizeInclude)
  129. Liquid::Template.register_tag('translate_file', Jekyll::Tags::LocalizeInclude)