Skip to content

Commit

Permalink
Builder template adheres to source template encoding behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
rtomayko committed Sep 19, 2011
1 parent 7ef2de5 commit 9c0ecf8
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 7 deletions.
38 changes: 31 additions & 7 deletions lib/tilt/builder.rb
@@ -1,8 +1,29 @@
require 'tilt/template'

module Tilt
# Builder template implementation. See:
# http://builder.rubyforge.org/
# XML Builder Template implementation
#
# - http://builder.rubyforge.org/
#
# Builder templates support three types of template input: string, file,
# and block. When the initialize block returns a non-string object that
# responds to call (Proc), template execution consists of calling the block
# with a Builder::XmlMarkup instance:
#
# BuilderTemplate.new do
# lambda do |xml|
# xml.h1 'howdy dudy'
# xml.p 'blaahhh'
# end
# end
#
# Builder templates can also be instantiated from a string or file. In that
# case, the source encoding is determined according to the rules documented
# in the Tilt README under Encodings. The ruby magic comment line is supported
# for specifying an alternative encoding.
#
# Builder templates always produce utf-8 encoded result strings regardless of
# the source string / file encoding.
class BuilderTemplate < Template
self.default_mime_type = 'text/xml'

Expand All @@ -14,7 +35,10 @@ def initialize_engine
require_template_library 'builder'
end

def prepare; end
def prepare
return if !data.respond_to?(:to_str)
@source = assign_source_encoding(data.to_str)
end

def evaluate(scope, locals, &block)
return super(scope, locals, &block) if data.respond_to?(:to_str)
Expand All @@ -23,6 +47,10 @@ def evaluate(scope, locals, &block)
xml.target!
end

def precompiled_template(locals)
@source
end

def precompiled_preamble(locals)
return super if locals.include? :xml
"xml = ::Builder::XmlMarkup.new(:indent => 2)\n#{super}"
Expand All @@ -31,10 +59,6 @@ def precompiled_preamble(locals)
def precompiled_postamble(locals)
"xml.target!"
end

def precompiled_template(locals)
data.to_str
end
end
end

63 changes: 63 additions & 0 deletions test/tilt_buildertemplate_test.rb
@@ -1,3 +1,4 @@
# coding: utf-8
require 'contest'
require 'tilt'

Expand Down Expand Up @@ -53,6 +54,68 @@ class BuilderTemplateTest < Test::Unit::TestCase
template.render(options) { subtemplate.render(options) }
end
end

##
# Encodings

if defined?(Encoding) && Encoding.respond_to?(:default_internal)
original_encoding = Encoding.default_external
setup do
Encoding.default_external = 'utf-8'
Encoding.default_internal = nil
end
teardown do
Encoding.default_external = original_encoding
Encoding.default_internal = nil
end

def tempfile(name='template')
f = Tempfile.open(name)
f.sync = true
yield f
ensure
f.close rescue nil
f.delete
end

test "reading templates using default external encoding" do
Encoding.default_external = 'Shift_JIS'
tempfile do |f|
f.puts("xml.em 'ふが' + @hoge".encode('Shift_JIS'))
template = Tilt::BuilderTemplate.new(f.path)
assert_equal 'Shift_JIS', template.data.encoding.to_s
@hoge = "ほげ".encode('Shift_JIS')
assert_equal 'UTF-8', template.render(self).encoding.to_s
end
end

test "reading templates using :default_encoding option override" do
Encoding.default_external = 'Big5'
tempfile do |f|
f.puts("xml.em 'ふが' + @hoge".encode('Shift_JIS'))
template = Tilt::BuilderTemplate.new(f.path, :default_encoding => 'Shift_JIS')
assert_equal 'Shift_JIS', template.data.encoding.to_s
@hoge = "ほげ".encode('Shift_JIS')
assert_equal 'UTF-8', template.render(self).encoding.to_s
end
end

test "reading template with magic encoding comment" do
Encoding.default_external = 'Big5'
tempfile do |f|
f.puts("# coding: Shift_JIS".encode('Shift_JIS'))
f.puts("xml.em 'ふが' + @hoge".encode('Shift_JIS'))
# require 'ruby-debug'
# debugger
template = Tilt::BuilderTemplate.new(f.path)
assert_equal 'Shift_JIS', template.data.encoding.to_s
@hoge = "ほげ".encode('Shift_JIS')
output = template.render(self)
assert_equal 'UTF-8', output.encoding.to_s
assert_equal "<em>ふがほげ</em>\n", output
end
end
end
end
rescue LoadError
warn "Tilt::BuilderTemplate (disabled)"
Expand Down

0 comments on commit 9c0ecf8

Please sign in to comment.