1
0
Fork 0
mirror of https://github.com/sinatra/sinatra synced 2023-03-27 23:18:01 -04:00

Merge pull request #641 from alexeymuranov/template-helpers-with-blocks

Allow `erb` and `haml` helpers to take a block
This commit is contained in:
Konstantin Haase 2013-02-25 17:08:03 -08:00
commit bee7dd4206
8 changed files with 204 additions and 39 deletions

View file

@ -401,6 +401,16 @@ Available Options:
</dd>
</dl>
#### Literal Templates
```ruby
get '/' do
haml '%div.title Hello World'
end
```
Renders the template string.
### Available Template Languages
Some languages have multiple implementations. To specify what implementation
@ -864,16 +874,6 @@ The `:callback` and `:variable` options can be used to decorate the rendered obj
Since calling ruby methods is not idiomatic in wlang, you almost always want to pass locals
to it. Layouts written in wlang and `yield` are supported, though.
#### Embedded Templates
```ruby
get '/' do
haml '%div.title Hello World'
end
```
Renders the embedded template string.
### Accessing Variables in Templates
Templates are evaluated within the same context as route handlers. Instance
@ -898,6 +898,43 @@ Or, specify an explicit Hash of local variables:
This is typically used when rendering templates as partials from within
other templates.
### Templates with `yield` and nested layouts
A layout is usually just a template that calls `yield`.
Such a template can by used either through the `:template` option as
described above, or it can be rendered with a block as follows:
```ruby
erb :post, :layout => false do
erb :index
end
```
This code is mostly equivalent to `erb :index, :layout => :post`.
Passing blocks to rendering methods is most useful for creating nested
layouts:
```ruby
erb :main_layout, :layout => false do
erb :admin_layout do
erb :user
end
end
```
This can also be done in fewer lines of code with:
```ruby
erb :admin_layout, :layout => :main_layout do
erb :user
end
```
Currently the following rendering method accept a block: `erb`, `haml`,
`liquid`, `slim `, `wlang`.
Also the general `render` method accepts a block.
### Inline Templates
Templates may be defined at the end of the source file:

View file

@ -416,6 +416,16 @@ set :views, settings.root + '/templates'
`:'subdir/template'`). Вы должны использовать символы, потому что иначе
шаблонизаторы попросту отображают любые строки, переданные им.
#### Буквальные шаблоны
```ruby
get '/' do
haml '%div.title Hello World'
end
```
Отобразит шаблон, переданный строкой.
### Доступные шаблонизаторы
Некоторые языки шаблонов имеют несколько реализаций. Чтобы указать, какую
@ -886,16 +896,6 @@ var resource = {"foo":"bar","baz":"qux"}; present(resource);
исключением `yield`), то вы почти всегда будете передавать в шаблон локальные
переменные.
### Встроенные шаблоны
```ruby
get '/' do
haml '%div.title Hello World'
end
```
Отобразит встроенный шаблон, переданный строкой.
### Доступ к переменным в шаблонах
Шаблоны интерпретируются в том же контексте, что и обработчики маршрутов.
@ -920,7 +920,46 @@ end
Это обычный подход, когда шаблоны рендерятся как части других шаблонов.
### Вложенные шаблоны
### Шаблоны с `yield` и вложенные раскладки (layout)
Раскладка (layout) обычно представляет собой шаблон, который исполняет
`yield`.
Такой шаблон может быть либо использован с помощью опции `:template`,
как описано выше, либо он может быть дополнен блоком:
```ruby
erb :post, :layout => false do
erb :index
end
```
Эти инструкции в основном эквивалентны `erb :index, :layout => :post`.
Передача блоков интерпретирующим шаблоны методам наиболее полезна для
создания вложенных раскладок:
```ruby
erb :main_layout, :layout => false do
erb :admin_layout do
erb :user
end
end
```
Это же самое может быть сделано короче:
```ruby
erb :admin_layout, :layout => :main_layout do
erb :user
end
```
В настоящее время, следующие интерпретирубщие шаблоны методы
принимают блок:
`erb`, `haml`, `liquid`, `slim `, `wlang`.
Общий метод заполнения шаблонов `render` также принимает блок.
### Включённые шаблоны
Шаблоны также могут быть определены в конце исходного файла:
@ -941,9 +980,9 @@ __END__
%div.title Hello world.
```
Заметьте: вложенные шаблоны, определенные в исходном файле, который подключила
Заметьте: включённые шаблоны, определенные в исходном файле, который подключил
Sinatra, будут загружены автоматически. Вызовите `enable :inline_templates`
напрямую, если используете вложенные шаблоны в других файлах.
напрямую, если используете включённые шаблоны в других файлах.
### Именованные шаблоны

View file

@ -199,7 +199,7 @@ module Sinatra
# Methods available to routes, before/after filters, and views.
module Helpers
# Set or retrieve the response status code.
def status(value=nil)
def status(value = nil)
response.status = value if value
response.status
end
@ -253,7 +253,7 @@ module Sinatra
alias to uri
# Halt processing and return the error status provided.
def error(code, body=nil)
def error(code, body = nil)
code, body = 500, code.to_str if code.respond_to? :to_str
response.body = body unless body.nil?
halt code
@ -265,7 +265,7 @@ module Sinatra
end
# Set multiple response headers with Hash.
def headers(hash=nil)
def headers(hash = nil)
response.headers.merge! hash if hash
response.headers
end
@ -630,8 +630,8 @@ module Sinatra
@default_layout = :layout
end
def erb(template, options = {}, locals = {})
render :erb, template, options, locals
def erb(template, options = {}, locals = {}, &block)
render(:erb, template, options, locals, &block)
end
def erubis(template, options = {}, locals = {})
@ -640,8 +640,8 @@ module Sinatra
render :erubis, template, options, locals
end
def haml(template, options = {}, locals = {})
render :haml, template, options, locals
def haml(template, options = {}, locals = {}, &block)
render(:haml, template, options, locals, &block)
end
def sass(template, options = {}, locals = {})
@ -659,13 +659,13 @@ module Sinatra
render :less, template, options, locals
end
def builder(template=nil, options = {}, locals = {}, &block)
def builder(template = nil, options = {}, locals = {}, &block)
options[:default_content_type] = :xml
render_ruby(:builder, template, options, locals, &block)
end
def liquid(template, options = {}, locals = {})
render :liquid, template, options, locals
def liquid(template, options = {}, locals = {}, &block)
render(:liquid, template, options, locals, &block)
end
def markdown(template, options = {}, locals = {})
@ -680,11 +680,11 @@ module Sinatra
render :rdoc, template, options, locals
end
def radius(template, options ={}, locals = {})
def radius(template, options = {}, locals = {})
render :radius, template, options, locals
end
def markaby(template = nil, options ={}, locals = {}, &block)
def markaby(template = nil, options = {}, locals = {}, &block)
render_ruby(:mab, template, options, locals, &block)
end
@ -698,16 +698,16 @@ module Sinatra
render_ruby(:nokogiri, template, options, locals, &block)
end
def slim(template, options = {}, locals = {})
render :slim, template, options, locals
def slim(template, options = {}, locals = {}, &block)
render(:slim, template, options, locals, &block)
end
def creole(template, options = {}, locals = {})
render :creole, template, options, locals
end
def wlang(template, options = {}, locals = {})
render :wlang, template, options, locals
def wlang(template, options = {}, locals = {}, &block)
render(:wlang, template, options, locals, &block)
end
def yajl(template, options = {}, locals = {})

View file

@ -85,6 +85,24 @@ class ERBTest < Test::Unit::TestCase
assert ok?
assert_equal '<outer><inner>hi</inner></outer>', body
end
it "can rendere truly nested layouts by accepting a layout and a block with the contents" do
mock_app do
template(:main_outer_layout) { "<h1>Title</h1>\n<%= yield %>" }
template(:an_inner_layout) { "<h2>Subtitle</h2>\n<%= yield %>" }
template(:a_page) { "<p>Contents.</p>\n" }
get('/') do
erb :main_outer_layout, :layout => false do
erb :an_inner_layout do
erb :a_page
end
end
end
end
get '/'
assert ok?
assert_body "<h1>Title</h1>\n<h2>Subtitle</h2>\n<p>Contents.</p>\n"
end
end

View file

@ -84,6 +84,24 @@ class HAMLTest < Test::Unit::TestCase
haml_app { haml "= foo", :locals => { :foo => 'bar' }}
assert_equal "bar\n", body
end
it "can rendere truly nested layouts by accepting a layout and a block with the contents" do
mock_app do
template(:main_outer_layout) { "%h1 Title\n= yield" }
template(:an_inner_layout) { "%h2 Subtitle\n= yield" }
template(:a_page) { "%p Contents." }
get('/') do
haml :main_outer_layout, :layout => false do
haml :an_inner_layout do
haml :a_page
end
end
end
end
get '/'
assert ok?
assert_body "<h1>Title</h1>\n<h2>Subtitle</h2>\n<p>Contents.</p>\n"
end
end
rescue LoadError

View file

@ -52,6 +52,24 @@ class LiquidTest < Test::Unit::TestCase
assert ok?
assert_equal 'foo', body
end
it "can rendere truly nested layouts by accepting a layout and a block with the contents" do
mock_app do
template(:main_outer_layout) { "<h1>Title</h1>\n{{ yield }}" }
template(:an_inner_layout) { "<h2>Subtitle</h2>\n{{ yield }}" }
template(:a_page) { "<p>Contents.</p>\n" }
get('/') do
liquid :main_outer_layout, :layout => false do
liquid :an_inner_layout do
liquid :a_page
end
end
end
end
get '/'
assert ok?
assert_body "<h1>Title</h1>\n<h2>Subtitle</h2>\n<p>Contents.</p>\n"
end
end
rescue LoadError

View file

@ -77,6 +77,24 @@ class SlimTest < Test::Unit::TestCase
assert ok?
assert_body '<x foo="bar"></x>'
end
it "can rendere truly nested layouts by accepting a layout and a block with the contents" do
mock_app do
template(:main_outer_layout) { "h1 Title\n== yield" }
template(:an_inner_layout) { "h2 Subtitle\n== yield" }
template(:a_page) { "p Contents." }
get('/') do
slim :main_outer_layout, :layout => false do
slim :an_inner_layout do
slim :a_page
end
end
end
end
get '/'
assert ok?
assert_body "<h1>Title</h1>\n<h2>Subtitle</h2>\n<p>Contents.</p>\n"
end
end
rescue LoadError

View file

@ -63,6 +63,23 @@ class WLangTest < Test::Unit::TestCase
assert_body "WLang Layout!\nHello World"
end
it "can rendere truly nested layouts by accepting a layout and a block with the contents" do
mock_app do
template(:main_outer_layout) { "<h1>Title</h1>\n>{ yield }" }
template(:an_inner_layout) { "<h2>Subtitle</h2>\n>{ yield }" }
template(:a_page) { "<p>Contents.</p>\n" }
get('/') do
wlang :main_outer_layout, :layout => false do
wlang :an_inner_layout do
wlang :a_page
end
end
end
end
get '/'
assert ok?
assert_body "<h1>Title</h1>\n<h2>Subtitle</h2>\n<p>Contents.</p>\n"
end
end
rescue LoadError