multiple-languages.rb 4.6 KB

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