From 31f238f8816bd031d538609cfa3833db647829a7 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 29 May 2013 14:00:37 -0400 Subject: [PATCH] Refactor some of i18n for better codeclimate scores. In the process, make nested i18n files work like rails --- middleman-core/features/i18n_preview.feature | 14 ++ .../fixtures/i18n-nested-app/locales/en.yml | 4 + .../i18n-nested-app/locales/en/more.yml | 3 + .../fixtures/i18n-nested-app/locales/es.yml | 4 + .../i18n-nested-app/locales/es/mucho.yml | 3 + .../source/localizable/index.html.erb | 3 + .../lib/middleman-core/renderers/redcarpet.rb | 17 +-- middleman-core/lib/middleman-core/version.rb | 2 +- .../middleman-more/core_extensions/i18n.rb | 128 ++++++++++-------- 9 files changed, 109 insertions(+), 69 deletions(-) create mode 100644 middleman-core/fixtures/i18n-nested-app/locales/en.yml create mode 100644 middleman-core/fixtures/i18n-nested-app/locales/en/more.yml create mode 100644 middleman-core/fixtures/i18n-nested-app/locales/es.yml create mode 100644 middleman-core/fixtures/i18n-nested-app/locales/es/mucho.yml create mode 100644 middleman-core/fixtures/i18n-nested-app/source/localizable/index.html.erb diff --git a/middleman-core/features/i18n_preview.feature b/middleman-core/features/i18n_preview.feature index c34b7708..ec77e884 100644 --- a/middleman-core/features/i18n_preview.feature +++ b/middleman-core/features/i18n_preview.feature @@ -228,3 +228,17 @@ Feature: i18n Preview Then I should see "Current locale: en" Then I should see "Buenos días" Then I should see "Howdy" + + Scenario: Nested i18n yaml + Given a fixture app "i18n-nested-app" + And a file named "config.rb" with: + """ + activate :i18n + """ + Given the Server is running at "i18n-nested-app" + When I go to "/" + Then I should see "Howdy" + Then I should see "More" + When I go to "/es/" + Then I should see "Como Esta?" + Then I should see "Mucho" \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-nested-app/locales/en.yml b/middleman-core/fixtures/i18n-nested-app/locales/en.yml new file mode 100644 index 00000000..91519342 --- /dev/null +++ b/middleman-core/fixtures/i18n-nested-app/locales/en.yml @@ -0,0 +1,4 @@ +--- +en: + greetings: "Howdy" + hi: "Hello" \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-nested-app/locales/en/more.yml b/middleman-core/fixtures/i18n-nested-app/locales/en/more.yml new file mode 100644 index 00000000..cdbe7828 --- /dev/null +++ b/middleman-core/fixtures/i18n-nested-app/locales/en/more.yml @@ -0,0 +1,3 @@ +--- +en: + more: "More" \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-nested-app/locales/es.yml b/middleman-core/fixtures/i18n-nested-app/locales/es.yml new file mode 100644 index 00000000..38c7e31e --- /dev/null +++ b/middleman-core/fixtures/i18n-nested-app/locales/es.yml @@ -0,0 +1,4 @@ +--- +es: + greetings: "Como Esta?" + hi: "Hola" \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-nested-app/locales/es/mucho.yml b/middleman-core/fixtures/i18n-nested-app/locales/es/mucho.yml new file mode 100644 index 00000000..15aac394 --- /dev/null +++ b/middleman-core/fixtures/i18n-nested-app/locales/es/mucho.yml @@ -0,0 +1,3 @@ +--- +es: + more: "Mucho" \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-nested-app/source/localizable/index.html.erb b/middleman-core/fixtures/i18n-nested-app/source/localizable/index.html.erb new file mode 100644 index 00000000..da872ad2 --- /dev/null +++ b/middleman-core/fixtures/i18n-nested-app/source/localizable/index.html.erb @@ -0,0 +1,3 @@ +<%= t(:greetings) %> + +<%= t(:more) %> diff --git a/middleman-core/lib/middleman-core/renderers/redcarpet.rb b/middleman-core/lib/middleman-core/renderers/redcarpet.rb index 7c3412ac..86bb8398 100644 --- a/middleman-core/lib/middleman-core/renderers/redcarpet.rb +++ b/middleman-core/lib/middleman-core/renderers/redcarpet.rb @@ -37,24 +37,11 @@ module Middleman cattr_accessor :middleman_app def image(link, title, alt_text) - if middleman_app && middleman_app.respond_to?(:image_tag) - middleman_app.image_tag(link, :title => title, :alt => alt_text) - else - img = "\"#{alt_text}\""" - end + middleman_app.image_tag(link, :title => title, :alt => alt_text) end def link(link, title, content) - if middleman_app && middleman_app.respond_to?(:link_to) - middleman_app.link_to(content, link, :title => title) - else - a = "#{content}" - end + middleman_app.link_to(content, link, :title => title) end end diff --git a/middleman-core/lib/middleman-core/version.rb b/middleman-core/lib/middleman-core/version.rb index 27a41b3d..4ab4bc45 100644 --- a/middleman-core/lib/middleman-core/version.rb +++ b/middleman-core/lib/middleman-core/version.rb @@ -1,5 +1,5 @@ module Middleman # Current Version # @return [String] - VERSION = '3.1.0.rc.1' unless const_defined?(:VERSION) + VERSION = '3.1.0.rc.2' unless const_defined?(:VERSION) end diff --git a/middleman-core/lib/middleman-more/core_extensions/i18n.rb b/middleman-core/lib/middleman-more/core_extensions/i18n.rb index 755a3836..e8db66ae 100644 --- a/middleman-core/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-more/core_extensions/i18n.rb @@ -22,24 +22,15 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end def after_configuration - @locales_glob = File.join(app.config[:locals_dir] || options[:data], "**", "*.{rb,yml,yaml}") + app.files.reload_path(app.config[:locals_dir] || options[:data]) - # File.fnmatch doesn't support brackets: {rb,yml,yaml} - regex = @locales_glob.sub(/\./, '\.').sub(File.join("**", "*"), ".*").sub(/\//, '\/').sub("{rb,yml,yaml}", "rb|ya?ml") - @locales_regex = %r{^#{regex}} + @locales_glob = File.join(app.config[:locals_dir] || options[:data], "**", "*.{rb,yml,yaml}") + @locales_regex = convert_glob_to_regex(@locales_glob) @maps = {} - - ::I18n.load_path += Dir[File.join(app.root, @locales_glob)] - ::I18n.reload! - @mount_at_root = options[:mount_at_root].nil? ? langs.first : options[:mount_at_root] - ::I18n.default_locale = @mount_at_root - # Reset fallbacks to fall back to our new default - if ::I18n.respond_to? :fallbacks - ::I18n.fallbacks = ::I18n::Locale::Fallbacks.new - end + configure_i18n if !app.build? logger.info "== Locales: #{langs.join(", ")} (Default #{@mount_at_root})" @@ -48,27 +39,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension # Don't output localizable files app.ignore File.join(options[:templates_dir], "**") - app.sitemap.provides_metadata_for_path do |url| - if d = get_localization_data(url) - lang, page_id = d - else - # Default to the @mount_at_root lang - page_id = nil - lang = @mount_at_root - end - - instance_vars = Proc.new do - @lang = lang - @page_id = page_id - end - - locals = { :lang => lang, - :page_id => page_id } - { :blocks => [instance_vars], - :locals => locals, - :options => { :lang => lang } } - end - + app.sitemap.provides_metadata_for_path(&method(:metadata_for_path)) app.files.changed(&method(:on_file_changed)) app.files.deleted(&method(:on_file_changed)) end @@ -81,27 +52,10 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension delegate :logger, :to => :app - def on_file_changed(file) - if @locales_regex =~ file - ::I18n.reload! - end - end - def langs - if options[:langs] - Array(options[:langs]).map(&:to_sym) - else - Dir[File.join(app.root, @locales_glob)].map { |file| - File.basename(file).sub(/\.ya?ml$/, "").sub(/\.rb$/, "") - }.sort.map(&:to_sym) - end + @_langs ||= get_known_languages end - - def get_localization_data(path) - @_localization_data ||= {} - @_localization_data[path] - end - + # Update the main sitemap resource list # @return [void] def manipulate_resource_list(resources) @@ -129,6 +83,74 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension private + + def on_file_changed(file) + if @locales_regex =~ file + @_langs = nil # Clear langs cache + ::I18n.reload! + end + end + + def convert_glob_to_regex(glob) + # File.fnmatch doesn't support brackets: {rb,yml,yaml} + regex = @locales_glob.sub(/\./, '\.').sub(File.join("**", "*"), ".*").sub(/\//, '\/').sub("{rb,yml,yaml}", "rb|ya?ml") + %r{^#{regex}} + end + + def configure_i18n + ::I18n.load_path += Dir[File.join(app.root, @locales_glob)] + ::I18n.reload! + + ::I18n.default_locale = @mount_at_root + # Reset fallbacks to fall back to our new default + if ::I18n.respond_to? :fallbacks + ::I18n.fallbacks = ::I18n::Locale::Fallbacks.new + end + end + + def metadata_for_path(url) + if d = get_localization_data(url) + lang, page_id = d + else + # Default to the @mount_at_root lang + page_id = nil + lang = @mount_at_root + end + + instance_vars = Proc.new do + @lang = lang + @page_id = page_id + end + + locals = { + :lang => lang, + :page_id => page_id + } + + { + :blocks => [instance_vars], + :locals => locals, + :options => { :lang => lang } + } + end + + def get_known_languages + if options[:langs] + Array(options[:langs]).map(&:to_sym) + else + known_langs = app.files.known_paths.select do |p| + p.to_s.match(@locales_regex) && (p.to_s.split(File::SEPARATOR).length === 2) + end.map { |p| + File.basename(p.to_s).sub(/\.ya?ml$/, "").sub(/\.rb$/, "") + }.sort.map(&:to_sym) + end + end + + def get_localization_data(path) + @_localization_data ||= {} + @_localization_data[path] + end + # Parse locale extension filename # @return [lang, path, basename] # will return +nil+ if no locale extension