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:
commit
bee7dd4206
8 changed files with 204 additions and 39 deletions
57
README.md
57
README.md
|
@ -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:
|
||||
|
|
65
README.ru.md
65
README.ru.md
|
@ -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`
|
||||
напрямую, если используете вложенные шаблоны в других файлах.
|
||||
напрямую, если используете включённые шаблоны в других файлах.
|
||||
|
||||
### Именованные шаблоны
|
||||
|
||||
|
|
|
@ -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 = {})
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue