Permalink
Browse files

Add localized templates

  # Default locale
  app/views/messages/index.html.erb

  # I18n.locale is set to :da (Danish)
  app/views/messages/index.da.html.erb
  • Loading branch information...
1 parent 5c062bf commit a98cd7ca9b2f24a4500963e58ba5c37d6bdf9259 @josh josh committed Jan 26, 2009
@@ -37,7 +37,11 @@ def find_template(original_template_path, format = nil)
template_path = original_template_path.sub(/^\//, '')
each do |load_path|
- if format && (template = load_path["#{template_path}.#{format}"])
+ if format && (template = load_path["#{template_path}.#{I18n.locale}.#{format}"])
+ return template
+ elsif format && (template = load_path["#{template_path}.#{format}"])
+ return template
+ elsif template = load_path["#{template_path}.#{I18n.locale}"]
return template
elsif template = load_path[template_path]
return template
@@ -93,13 +93,14 @@ def self.exempt_from_layout(*extensions)
@@exempt_from_layout.merge(regexps)
end
- attr_accessor :filename, :load_path, :base_path, :name, :format, :extension
+ attr_accessor :filename, :load_path, :base_path
+ attr_accessor :locale, :name, :format, :extension
delegate :to_s, :to => :path
def initialize(template_path, load_paths = [])
template_path = template_path.dup
@load_path, @filename = find_full_path(template_path, load_paths)
- @base_path, @name, @format, @extension = split(template_path)
+ @base_path, @name, @locale, @format, @extension = split(template_path)
@base_path.to_s.gsub!(/\/$/, '') # Push to split method
# Extend with partial super powers
@@ -137,17 +138,17 @@ def mime_type
memoize :mime_type
def path
- [base_path, [name, format, extension].compact.join('.')].compact.join('/')
+ [base_path, [name, locale, format, extension].compact.join('.')].compact.join('/')
end
memoize :path
def path_without_extension
- [base_path, [name, format].compact.join('.')].compact.join('/')
+ [base_path, [name, locale, format].compact.join('.')].compact.join('/')
end
memoize :path_without_extension
def path_without_format_and_extension
- [base_path, name].compact.join('/')
+ [base_path, [name, locale].compact.join('.')].compact.join('/')
end
memoize :path_without_format_and_extension
@@ -207,6 +208,10 @@ def valid_extension?(extension)
!Template.registered_template_handler(extension).nil?
end
+ def valid_locale?(locale)
+ I18n.available_locales.include?(locale.to_sym)
+ end
+
def find_full_path(path, load_paths)
load_paths = Array(load_paths) + [nil]
load_paths.each do |load_path|
@@ -217,19 +222,42 @@ def find_full_path(path, load_paths)
end
# Returns file split into an array
- # [base_path, name, format, extension]
+ # [base_path, name, locale, format, extension]
def split(file)
- if m = file.match(/^(.*\/)?([^\.]+)\.?(\w+)?\.?(\w+)?\.?(\w+)?$/)
- if valid_extension?(m[5]) # Multipart formats
- [m[1], m[2], "#{m[3]}.#{m[4]}", m[5]]
- elsif valid_extension?(m[4]) # Single format
- [m[1], m[2], m[3], m[4]]
- elsif valid_extension?(m[3]) # No format
- [m[1], m[2], nil, m[3]]
+ if m = file.match(/^(.*\/)?([^\.]+)\.(.*)$/)
+ base_path = m[1]
+ name = m[2]
+ extensions = m[3]
+ else
+ return
+ end
+
+ locale = nil
+ format = nil
+ extension = nil
+
+ if m = extensions.match(/^(\w+)?\.?(\w+)?\.?(\w+)?\.?/)
+ if valid_locale?(m[1]) && m[2] && valid_extension?(m[3]) # All three
+ locale = m[1]
+ format = m[2]
+ extension = m[3]
+ elsif m[1] && m[2] && valid_extension?(m[3]) # Multipart formats
+ format = "#{m[1]}.#{m[2]}"
+ extension = m[3]
+ elsif valid_extension?(m[1]) # Just extension
+ extension = m[1]
+ elsif valid_locale?(m[1]) && valid_extension?(m[2]) # locale and extension
+ locale = m[1]
+ extension = m[2]
+ elsif valid_extension?(m[2]) # format and extension
+ format = m[1]
+ extension = m[2]
else # No extension
- [m[1], m[2], m[3], nil]
+ format = m[1]
end
end
+
+ [base_path, name, locale, format, extension]
end
end
end
@@ -32,6 +32,10 @@
ActionController::Base.session_store = nil
+# Register danish language for testing
+I18n.backend.store_translations 'da', {}
+ORIGINAL_LOCALES = I18n.available_locales
+
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
ActionController::Base.view_paths = FIXTURE_LOAD_PATH
@@ -0,0 +1 @@
+Hey verden
@@ -5,6 +5,13 @@ module RenderTestCases
def setup_view(paths)
@assigns = { :secret => 'in the sauce' }
@view = ActionView::Base.new(paths, @assigns)
+
+ # Reload and register danish language for testing
+ I18n.reload!
+ I18n.backend.store_translations 'da', {}
+
+ # Ensure original are still the same since we are reindexing view paths
+ assert_equal ORIGINAL_LOCALES, I18n.available_locales
end
def test_render_file
@@ -19,6 +26,14 @@ def test_render_file_without_specific_extension
assert_equal "Hello world!", @view.render(:file => "test/hello_world")
end
+ def test_render_file_with_localization
+ old_locale = I18n.locale
+ I18n.locale = :da
+ assert_equal "Hey verden", @view.render(:file => "test/hello_world")
+ ensure
+ I18n.locale = old_locale
+ end
+
def test_render_file_at_top_level
assert_equal 'Elastica', @view.render(:file => '/shared')
end

4 comments on commit a98cd7c

Contributor

Hi,

when I use localized template like : index.fr.html.erb, the Content-Type header sent by the server becomes “fr.html; charset=utf-8” instead of the standard “text/html; charset=utf-8”.

Because of this problem, my browser (Firefox 3) sets a bad character decoder (ISO instead of UTF-8) and my views are broken.

Member

@slainer68, I think you should warn that in the mailing list. This seems like high priority!

boof replied Feb 3, 2009

Maybe a Lighthouse ticket would be good.

Contributor

OK.

More information : the bad Content-Type is only sent when the locale is not properly loaded/valid (for example in a new Rails application, you set the locale to :fr in the environment.rb file but you don’t put a fr.yml file).

But IMHO, the Content-Type sent by Rails should be valid even if the locale is not valid/loaded.

Please sign in to comment.