mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
add template support to namespaces
This commit is contained in:
parent
961644dfca
commit
825c7e2412
5 changed files with 131 additions and 19 deletions
|
@ -23,5 +23,3 @@
|
||||||
|
|
||||||
* Extend `sinatra-content-for` to support Liquid, Radius, Markaby, Nokogiri and
|
* Extend `sinatra-content-for` to support Liquid, Radius, Markaby, Nokogiri and
|
||||||
Builder. At least the first two probably involve patching Tilt.
|
Builder. At least the first two probably involve patching Tilt.
|
||||||
|
|
||||||
* Have `sinatra-namespace` support namespace local templates.
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require 'backports'
|
||||||
require 'sinatra/base'
|
require 'sinatra/base'
|
||||||
require 'sinatra/decompile'
|
require 'sinatra/decompile'
|
||||||
|
|
||||||
|
@ -6,21 +7,32 @@ module Sinatra
|
||||||
def self.new(base, pattern, conditions = {}, &block)
|
def self.new(base, pattern, conditions = {}, &block)
|
||||||
Module.new do
|
Module.new do
|
||||||
extend NamespacedMethods
|
extend NamespacedMethods
|
||||||
|
include InstanceMethods
|
||||||
@base, @extensions = base, []
|
@base, @extensions = base, []
|
||||||
@pattern, @conditions = compile(pattern, conditions)
|
@pattern, @conditions = compile(pattern, conditions)
|
||||||
|
@templates = Hash.new { |h,k| @base.templates[k] }
|
||||||
namespace = self
|
namespace = self
|
||||||
before { extend namespace }
|
before { extend(@namespace = namespace) }
|
||||||
define_method(:error_block!) do |*keys|
|
class_eval(&block)
|
||||||
if block = keys.inject(nil) { |b,k| b ||= namespace.errors[k] }
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module InstanceMethods
|
||||||
|
def settings
|
||||||
|
@namespace
|
||||||
|
end
|
||||||
|
|
||||||
|
def template_cache
|
||||||
|
super.fetch(:nested, @namespace) { Tilt::Cache.new }
|
||||||
|
end
|
||||||
|
|
||||||
|
def error_block!(*keys)
|
||||||
|
if block = keys.inject(nil) { |b,k| b ||= @namespace.errors[k] }
|
||||||
instance_eval(&block)
|
instance_eval(&block)
|
||||||
else
|
else
|
||||||
super(*keys)
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class_eval(&block)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module SharedMethods
|
module SharedMethods
|
||||||
|
@ -32,7 +44,7 @@ module Sinatra
|
||||||
module NamespacedMethods
|
module NamespacedMethods
|
||||||
include SharedMethods
|
include SharedMethods
|
||||||
include Sinatra::Decompile
|
include Sinatra::Decompile
|
||||||
attr_reader :base
|
attr_reader :base, :templates
|
||||||
|
|
||||||
def self.prefixed(*names)
|
def self.prefixed(*names)
|
||||||
names.each { |n| define_method(n) { |*a, &b| prefixed(n, *a, &b) }}
|
names.each { |n| define_method(n) { |*a, &b| prefixed(n, *a, &b) }}
|
||||||
|
@ -75,6 +87,30 @@ module Sinatra
|
||||||
@conditions[:provides] = args
|
@conditions[:provides] = args
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set(key, value = self, &block)
|
||||||
|
raise ArgumentError, "may not set #{key}" if key != :views
|
||||||
|
return key.each { |k,v| set(k, v) } if block.nil? and value == self
|
||||||
|
block ||= proc { value }
|
||||||
|
singleton_class.send(:define_method, key, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def enable(*opts)
|
||||||
|
opts.each { |key| set(key, true) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable(*opts)
|
||||||
|
opts.each { |key| set(key, false) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def template(name, &block)
|
||||||
|
filename, line = caller_locations.first
|
||||||
|
templates[name] = [block, filename, line.to_i]
|
||||||
|
end
|
||||||
|
|
||||||
|
def layout(name=:layout, &block)
|
||||||
|
template name, &block
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def app
|
def app
|
||||||
|
@ -118,8 +154,7 @@ module Sinatra
|
||||||
end
|
end
|
||||||
|
|
||||||
def method_missing(meth, *args, &block)
|
def method_missing(meth, *args, &block)
|
||||||
return super if args.any? or block or not base.respond_to? meth
|
base.send(meth, *args, &block)
|
||||||
base.send meth
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
1
sinatra-contrib/spec/namespace/foo.erb
Normal file
1
sinatra-contrib/spec/namespace/foo.erb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
hi
|
1
sinatra-contrib/spec/namespace/nested/foo.erb
Normal file
1
sinatra-contrib/spec/namespace/nested/foo.erb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ho
|
|
@ -490,9 +490,86 @@ describe Sinatra::Namespace do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'templates' do
|
describe 'templates' do
|
||||||
it "allows to define nested templates"
|
it "allows using templates from the base" do
|
||||||
it "allows to define nested layouts"
|
mock_app do
|
||||||
it "allows setting a different views directory"
|
template(:foo) { 'hi' }
|
||||||
|
send(verb, '/') { erb :foo }
|
||||||
|
namespace '/foo' do
|
||||||
|
send(verb) { erb :foo }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if verb != :head
|
||||||
|
send(verb, '/').body.should == "hi"
|
||||||
|
send(verb, '/foo').body.should == "hi"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows to define nested templates" do
|
||||||
|
mock_app do
|
||||||
|
template(:foo) { 'hi' }
|
||||||
|
send(verb, '/') { erb :foo }
|
||||||
|
namespace '/foo' do
|
||||||
|
template(:foo) { 'ho' }
|
||||||
|
send(verb) { erb :foo }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if verb != :head
|
||||||
|
send(verb, '/').body.should == "hi"
|
||||||
|
send(verb, '/foo').body.should == "ho"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows to define nested layouts" do
|
||||||
|
mock_app do
|
||||||
|
layout { 'Hello <%= yield %>!' }
|
||||||
|
template(:foo) { 'World' }
|
||||||
|
send(verb, '/') { erb :foo }
|
||||||
|
namespace '/foo' do
|
||||||
|
layout { 'Hi <%= yield %>!' }
|
||||||
|
send(verb) { erb :foo }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if verb != :head
|
||||||
|
send(verb, '/').body.should == "Hello World!"
|
||||||
|
send(verb, '/foo').body.should == "Hi World!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows using templates from the base" do
|
||||||
|
mock_app do
|
||||||
|
layout { "he said: <%= yield %>" }
|
||||||
|
template(:foo) { 'hi' }
|
||||||
|
send(verb, '/') { erb :foo }
|
||||||
|
namespace '/foo' do
|
||||||
|
template(:foo) { 'ho' }
|
||||||
|
send(verb) { erb :foo }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if verb != :head
|
||||||
|
send(verb, '/').body.should == "he said: hi"
|
||||||
|
send(verb, '/foo').body.should == "he said: ho"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows setting a different views directory" do
|
||||||
|
mock_app do
|
||||||
|
set :views, File.expand_path('../namespace', __FILE__)
|
||||||
|
send(verb, '/') { erb :foo }
|
||||||
|
namespace('/foo') do
|
||||||
|
set :views, File.expand_path('../namespace/nested', __FILE__)
|
||||||
|
send(verb) { erb :foo }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if verb != :head
|
||||||
|
send(verb, '/').body.should == "hi\n"
|
||||||
|
send(verb, '/foo').body.should == "ho\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'extensions' do
|
describe 'extensions' do
|
||||||
|
|
Loading…
Reference in a new issue