Skip to content

Commit

Permalink
Ruby 1.9: ERB template encoding using a magic comment at the top of t…
Browse files Browse the repository at this point in the history
…he file
  • Loading branch information
jeremy committed Apr 25, 2010
1 parent 457a546 commit 81e0607
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 10 deletions.
5 changes: 4 additions & 1 deletion actionpack/CHANGELOG
@@ -1,4 +1,7 @@
*Edge* *2.3.6 (unreleased)*

* Ruby 1.9: ERB template encoding using a magic comment at the top of the file. [Jeremy Kemper]
<%# encoding: utf-8 %>


* Fixed that default locale templates should be used if the current locale template is missing [DHH] * Fixed that default locale templates should be used if the current locale template is missing [DHH]


Expand Down
14 changes: 12 additions & 2 deletions actionpack/lib/action_view/renderable.rb
Expand Up @@ -65,16 +65,26 @@ def compile(local_assigns)
def compile!(render_symbol, local_assigns) def compile!(render_symbol, local_assigns)
locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join


code = compiled_source
encoding_comment = $1 if code.sub!(/\A(#.*coding.*)\n/, '')

source = <<-end_src source = <<-end_src
def #{render_symbol}(local_assigns) def #{render_symbol}(local_assigns)
old_output_buffer = output_buffer;#{locals_code};#{compiled_source} old_output_buffer = output_buffer;#{locals_code};#{code}
ensure ensure
self.output_buffer = old_output_buffer self.output_buffer = old_output_buffer
end end
end_src end_src


if encoding_comment
source = "#{encoding_comment}\n#{source}"
line = -1
else
line = 0
end

begin begin
ActionView::Base::CompiledTemplates.module_eval(source, filename, 0) ActionView::Base::CompiledTemplates.module_eval(source, filename, line)
rescue Errno::ENOENT => e rescue Errno::ENOENT => e
raise e # Missing template file, re-raise for Base to rescue raise e # Missing template file, re-raise for Base to rescue
rescue Exception => e # errors from template code rescue Exception => e # errors from template code
Expand Down
6 changes: 1 addition & 5 deletions actionpack/lib/action_view/template_handlers/erb.rb
Expand Up @@ -11,11 +11,7 @@ class ERB < TemplateHandler
self.erb_trim_mode = '-' self.erb_trim_mode = '-'


def compile(template) def compile(template)
src = ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src

# Ruby 1.9 prepends an encoding to the source. However this is
# useless because you can only set an encoding on the first line
RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
end end
end end
end end
Expand Down
5 changes: 4 additions & 1 deletion actionpack/test/fixtures/test/utf8.html.erb
@@ -1,2 +1,5 @@
<%# encoding: utf-8 -%>
Русский текст Русский текст
日本語のテキスト <%= "日".encoding %>
<%= @output_buffer.encoding %>
<%= __ENCODING__ %>
2 changes: 1 addition & 1 deletion actionpack/test/template/render_test.rb
Expand Up @@ -251,7 +251,7 @@ def test_render_with_nested_layout
if '1.9'.respond_to?(:force_encoding) if '1.9'.respond_to?(:force_encoding)
def test_render_utf8_template def test_render_utf8_template
result = @view.render(:file => "test/utf8.html.erb", :layouts => "layouts/yield") result = @view.render(:file => "test/utf8.html.erb", :layouts => "layouts/yield")
assert_equal "Русский текст\n日本語のテキスト", result assert_equal "Русский текст\nUTF-8\nUTF-8\nUTF-8\n", result
assert_equal Encoding::UTF_8, result.encoding assert_equal Encoding::UTF_8, result.encoding
end end
end end
Expand Down

0 comments on commit 81e0607

Please sign in to comment.