Last active
August 29, 2015 14:01
-
-
Save tlux/3117918abe7f88b20bd4 to your computer and use it in GitHub Desktop.
I18n power for your JavaScript
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
| window.I18n ||= {} | |
| VALID_OPTIONS = ['scope', 'locale', 'default', 'fallbacks'] | |
| humanizeKeypath = (keypath) -> | |
| console.warn "I18n: no translation found for #{keypath}" | |
| _(keypath.split('.')).chain().last().humanize().value() | |
| sanitizeKeypath = (keypath) -> | |
| str = "" | |
| if keypath | |
| if _(keypath).isArray() | |
| str += _(keypath).chain().flatten().compact().value().join('.') | |
| else | |
| str += keypath | |
| str | |
| buildEvalString = (keypath, locale) -> | |
| ['I18n.translations', locale, sanitizeKeypath(keypath)].join('.') | |
| tryToInterpolate = (str, interpolations) -> | |
| if _(str).isObject() | |
| str | |
| else | |
| str.interpolate(interpolations) | |
| _(I18n).extend | |
| t: (keypath, options = {}) -> | |
| @translate(keypath, options) | |
| translate: (keypath, options = {}) -> | |
| throw "I18n: no keypath defined" unless keypath | |
| throw "I18n: no translations found" unless @translations | |
| interpolations = _(options).omit(VALID_OPTIONS) | |
| options = _(options).chain().pick(VALID_OPTIONS).defaults(locale: I18n.locale, fallbacks: true).value() | |
| fallbacks = {} | |
| fallbacks = I18n.fallbacks[options.locale] if options.fallbacks and _(I18n.fallbacks).has(options.locale) | |
| fallbacks[options.locale] = [options.locale] if _(fallbacks).isEmpty() | |
| translations = _(fallbacks).collect (locale) => | |
| if _(@translations).has(locale) | |
| try | |
| eval(buildEvalString([options.scope, keypath], locale)) | |
| catch | |
| null | |
| translation = _(translations).chain().select((translation) -> translation?).first().value() | |
| if translation? | |
| tryToInterpolate(translation, interpolations) | |
| else | |
| if options.default | |
| tryToInterpolate(options.default, interpolations) | |
| else | |
| humanizeKeypath(keypath) |
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
| namespace :i18n do | |
| desc 'Generates I18n JavaScript files and stores them in public/static/locales' | |
| task :generate_js => :environment do | |
| # Generate contained directory | |
| dirname = ENV.fetch('DIRNAME') { "#{Rails.root}/public/static/locales" } | |
| FileUtils.mkdir_p(dirname) | |
| # Get contents of all translation files and merge them in a single Hash | |
| locale_files = Dir.glob("#{Rails.root}/config/locales/**/*.yml") | |
| translations = locale_files.inject({}) do |translations, file| | |
| locale_translations = YAML.load_file(file) | |
| locale_translations.deep_transform_keys! do |key| | |
| key.split('/').map { |part| part.camelize(:lower) }.join('/') | |
| end | |
| translations.deep_merge!(locale_translations) | |
| end | |
| if I18n.respond_to?(:fallbacks) | |
| fallback_combinations = I18n.available_locales.collect { |locale| I18n.fallbacks[locale].sort }.uniq | |
| fallback_combinations.each do |locale_combination| | |
| file_name = locale_combination.join('+') | |
| path = File.join(dirname, "#{file_name}.js") | |
| File.open(path, 'w') do |file| | |
| file.puts header_data | |
| locale_combination.each do |locale| | |
| file.puts translation_data(locale, translations[locale.to_s]) | |
| end | |
| end | |
| puts "[#{locale_combination.join('+')}] #{path}" | |
| end | |
| else | |
| translations.each do |locale, locale_translations| | |
| path = File.join(dirname, "#{locale}.js") | |
| File.open(path, 'w') do |file| | |
| file.puts header_data | |
| file.puts translation_data(locale, locale_translations) | |
| end | |
| puts "[#{locale}] #{path}" | |
| end | |
| end | |
| end | |
| def header_data | |
| <<-JAVASCRIPT.strip_heredoc | |
| I18n || (I18n = {}); | |
| I18n.translations || (I18n.translations = {}); | |
| JAVASCRIPT | |
| end | |
| def translation_data(locale, translations) | |
| "I18n.translations.#{locale} = #{translations.to_json};" | |
| end | |
| end |
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
| module I18nHelper | |
| def i18n_javascript | |
| fallbacks = I18n.try(:fallbacks) | |
| locales = Array(fallbacks ? fallbacks[I18n.locale] : I18n.locale).sort | |
| capture do | |
| concat javascript_tag <<-JAVASCRIPT.strip_heredoc | |
| I18n || (I18n = {}); | |
| I18n.defaultLocale = #{I18n.default_locale.to_json}; | |
| I18n.fallbacks = #{fallbacks.to_h.to_json}; | |
| I18n.locale = #{I18n.locale.to_json}; | |
| JAVASCRIPT | |
| concat "\n" | |
| concat javascript_include_tag("/static/locales/#{locales.join('+')}.js") | |
| end | |
| end | |
| end |
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
| # "Hello, %{name}!".interpolate(name: 'Tobias') # => "Hello, Tobias!" | |
| String::interpolate = (interpolations = {}) -> | |
| @replace /%\{(.*?)\}/g, (whole, key) -> | |
| camelizedKey = _(key).camelize() | |
| camelizedKey = camelizedKey.charAt(0).toLowerCase() + camelizedKey.slice(1) | |
| interpolations[camelizedKey] || interpolations[key] || '' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment