diff --git a/middleman-core/features/i18n_link_to.feature b/middleman-core/features/i18n_link_to.feature new file mode 100644 index 00000000..9fd29d10 --- /dev/null +++ b/middleman-core/features/i18n_link_to.feature @@ -0,0 +1,43 @@ +Feature: i18n Links + + Scenario: A template changes i18n during preview + Given a fixture app "empty-app" + And a file named "data/pages.yml" with: + """ + - hello.html + """ + And a file named "locales/en.yml" with: + """ + --- + en: + msg: Hello + """ + And a file named "locales/es.yml" with: + """ + --- + es: + paths: + hello: "hola" + msg: Hola + """ + And a file named "source/localizable/hello.html.erb" with: + """ + Page: <%= t(:msg) %> + <% data.pages.each_with_index do |p, i| %> + <%= link_to "Current #{p}", "/#{p}" %> + <%= link_to "Other #{p}", "/#{p}", ::I18n.locale == :en ? :es : :en %> + <% end %> + """ + And a file named "config.rb" with: + """ + activate :i18n + """ + Given the Server is running at "empty-app" + When I go to "/hello.html" + Then I should see "Page: Hello" + Then I should see 'Current hello.html' + Then I should see 'Other hello.html' + When I go to "/es/hola.html" + Then I should see "Page: Hola" + Then I should see 'Current hello.html' + Then I should see 'Other hello.html' \ No newline at end of file diff --git a/middleman-core/lib/middleman-more/core_extensions/i18n.rb b/middleman-core/lib/middleman-more/core_extensions/i18n.rb index a3d842ad..abb8377e 100644 --- a/middleman-core/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-more/core_extensions/i18n.rb @@ -7,9 +7,13 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension option :mount_at_root, nil, 'Mount a specific language at the root of the site' option :data, 'locales', 'The directory holding your locale configurations' + attr_reader :lookup + def initialize(app, options_hash={}, &block) super + @lookup = {} + # TODO # If :directory_indexes is already active, # throw a warning explaining the bug and telling the use @@ -27,9 +31,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end def after_configuration - app.files.reload_path(app.config[:locals_dir] || options[:data]) + app.files.reload_path(app.config[:locales_dir] || options[:data]) - @locales_glob = File.join(app.config[:locals_dir] || options[:data], '**', '*.{rb,yml,yaml}') + @locales_glob = File.join(app.config[:locales_dir] || options[:data], '**', '*.{rb,yml,yaml}') @locales_regex = convert_glob_to_regex(@locales_glob) @maps = {} @@ -53,6 +57,11 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension def t(*args) ::I18n.t(*args) end + + def link_to(text, target, lang=::I18n.locale) + url = extensions[:i18n].localized_path(target, lang) + url ? super(text, url) : super(text, target) + end end delegate :logger, to: :app @@ -85,7 +94,17 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end - resources + new_resources + @lookup = new_resources.each_with_object({}) do |desc, sum| + abs_path = desc.source_path.sub(options[:templates_dir], '') + sum[abs_path] ||= {} + sum[abs_path][desc.lang] = '/' + desc.path + end + + resources + new_resources.map { |r| r.to_resource(app) } + end + + def localized_path(path, lang) + @lookup[path] && @lookup[path][lang] end private @@ -173,6 +192,14 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension [lang, path, basename] end + LocalizedPageDescriptor = Struct.new(:path, :source_path, :lang) do + def to_resource(app) + p = ::Middleman::Sitemap::Resource.new(app.sitemap, path) + p.proxy_to(source_path) + p + end + end + def build_resource(path, source_path, page_id, lang) old_locale = ::I18n.locale ::I18n.locale = lang @@ -194,11 +221,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension @_localization_data[path] = [lang, path, localized_page_id] - p = ::Middleman::Sitemap::Resource.new(app.sitemap, path) - p.proxy_to(source_path) - ::I18n.locale = old_locale - p + + LocalizedPageDescriptor.new(path, source_path, lang) end module LocaleHelpers @@ -209,10 +234,10 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end def locate_partial(partial_name, try_static=false) - locals_dir = extensions[:i18n].options[:templates_dir] + locales_dir = extensions[:i18n].options[:templates_dir] # Try /localizable - partials_path = File.join(locals_dir, partial_name) + partials_path = File.join(locales_dir, partial_name) lang_suffix = current_resource.metadata[:locals] && current_resource.metadata[:locals][:lang] @@ -226,7 +251,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension if lang_suffix super(suffixed_partial_name, maybe_static) || - super(File.join(locals_dir, suffixed_partial_name), maybe_static) || + super(File.join(locales_dir, suffixed_partial_name), maybe_static) || super(partials_path, try_static) || super else