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