Open ericgj opened 12 years ago
The Sinatra docs say:
NOTE: Inline templates defined in the source file that requires sinatra are automatically loaded. Call enable
:inline_templates
explicitly if you have inline templates in other source files.
This is a puzzler: where do the inline templates defined in the source file that requires sinatra get loaded?
Here's the code that runs when you enable :inline_templates
. Curious to see that you could also do something like set :inline_templates, 'another_file.rb'
.
https://github.com/codereading/sinatra/blob/ver1.3.2/lib/sinatra/base.rb#L1049
# Load embeded templates from the file; uses the caller's __FILE__
# when no file is specified.
def inline_templates=(file=nil)
file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file
begin
io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file)
app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2)
rescue Errno::ENOENT
app, data = nil
end
if data
if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m
encoding = $2
else
encoding = settings.default_encoding
end
lines = app.count("\n") + 1
template = nil
force_encoding data, encoding
data.each_line do |line|
lines += 1
if line =~ /^@@\s*(.*\S)\s*$/
template = force_encoding('', encoding)
templates[$1.to_sym] = [template, file, lines]
elsif template
template << line
end
end
end
end
Inline templates essentially are written after the entire app is written. For example:
require 'sinatra'
get '/' do
erb :index
end
__END__
@@ index
<html>
<!-- Some stuff here -->
</html>
A complete example can be found in the chat application under sinatra/examples folder
This is what I understood:
__END__
is not executed by Ruby.IO.binread(file)
reads the file in binary mode, and splits it into two parts -> app
and data
. This happens at this step: io.gsub("\r\n", "\n").split(/^__END__$/, 2)
. The gsub
method is called to normalize the line ending differences between different OSes (read CRLF, LF, CR issues) and the split
method splits the file at the __END__
keyword into app
and data
. The data
object, essentially contains the inline template info.line =~ /^@@\s*(.*\S)\s*$/
, the inline template "index" specified in the example by @@ index
gets matched so that any line after the regex match is considered as a template.I've never seen inline erb before, online inline HAML. This is good to know for when you're writing really small apps, and don't want to use HAML.
@codereading/readers