sinatra-mustache 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -33,6 +33,49 @@ And then put your .mustache files in your app's views folder
33
33
  Instance variables and locals are available to the template as well as yaml
34
34
  front matter.
35
35
 
36
+ Helpers
37
+ ======
38
+
39
+ Use the helpers you defined in your app by passing their names to mustache_helper:
40
+
41
+ require 'sinatra/mustache'
42
+
43
+ class App < Sinatra::Base
44
+ register Sinatra::MustacheHelper #makes mustache_helper available
45
+
46
+ helpers do
47
+ def some_helper *args
48
+ args.join('/')
49
+ end
50
+ end
51
+
52
+ mustache_helper :some_helper
53
+ end
54
+
55
+ Now you can use some_helper in your mustache template. There is also support for mustache's dot-notation:
56
+
57
+ " {{ some_helper.awesome.nice.spectacular }}" #=> "awesome/nice/spectacular"
58
+
59
+ Also, There is support for registering helper modules
60
+
61
+ module SomeHelpers
62
+ def hello what
63
+ "Hello #{what}"
64
+ end
65
+ end
66
+
67
+ class App < Sinatra::Base
68
+ register Sinatra::MustacheHelper
69
+ helpers SomeHelpers
70
+ mustache_helpers SomeHelpers
71
+ end
72
+
73
+ Now, this is possible:
74
+
75
+ " {{ hello.Mars }}" #=> "Hello Mars"
76
+
77
+ Passing arguments to helper methods via dot notation is limited to Strings only.
78
+
36
79
  Caveat
37
80
  ======
38
81
 
@@ -0,0 +1,32 @@
1
+ module Proxies
2
+ class Currystache
3
+
4
+ attr_reader :proc, :args
5
+
6
+ def initialize my_proc
7
+ @proc = my_proc
8
+ @args = []
9
+ end
10
+
11
+ def has_key? arg
12
+ true
13
+ end
14
+
15
+ def call arg
16
+ args << arg
17
+ self
18
+ end
19
+ alias :[] :call
20
+
21
+ def to_s
22
+ result = proc.call(*args)
23
+ args.clear
24
+ result.to_s
25
+ end
26
+
27
+ def inspect
28
+ proc
29
+ end
30
+
31
+ end
32
+ end
@@ -1,5 +1,5 @@
1
1
  module Sinatra
2
2
  module Mustache
3
- VERSION = "0.0.6"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -0,0 +1,25 @@
1
+ module Sinatra
2
+ module MustacheHelper
3
+ METHODS = {}
4
+
5
+ def mustache_helper *args
6
+ args.each do |arg|
7
+ if arg.is_a? Symbol
8
+ add_to_mustache_helper_methods(arg, instance_method(arg).bind(self.new!))
9
+ elsif arg.is_a? Module
10
+ arg.instance_methods.each { |m| add_to_mustache_helper_methods(m, arg.instance_method(m).bind(self.new!)) }
11
+ else
12
+ raise ArgumentError.new("#{arg.class} can not be used with mustache_helper, please provide a symbol or a Module")
13
+ end
14
+ end
15
+ end
16
+ alias :mustache_helpers :mustache_helper
17
+
18
+ def add_to_mustache_helper_methods name, meth
19
+ METHODS[name] = Proxies::Currystache.new(meth)
20
+ end
21
+
22
+ end
23
+
24
+ register MustacheHelper
25
+ end
@@ -1,3 +1,5 @@
1
+ require 'proxies/currystache'
2
+ require 'sinatra/helpers/mustache'
1
3
  require 'tilt/mustache_template'
2
4
 
3
5
  module Sinatra
@@ -16,7 +16,7 @@ module Tilt
16
16
  @output = nil
17
17
  end
18
18
 
19
- def evaluate(scope, locals, &block)
19
+ def evaluate(scope, locals, &block)
20
20
  mustache_locals = locals.dup
21
21
 
22
22
  if data =~ /^(\s*---(.+)---\s*)/m
@@ -39,10 +39,12 @@ module Tilt
39
39
  mustache_locals[symbol] = scope.instance_variable_get(instance_variable)
40
40
  end
41
41
  end
42
+
43
+ mustache_locals = Sinatra::MustacheHelper::METHODS.dup.merge(mustache_locals)
42
44
 
43
- mustache_locals[:yield] = block.nil? ? '' : yield
45
+ mustache_locals[:yield] = block.nil? ? '' : yield
44
46
  mustache_locals[:content] = mustache_locals[:yield]
45
-
47
+
46
48
  @output = ::Mustache.render(template, mustache_locals)
47
49
  end
48
50
  end
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.add_dependency 'sinatra', '~> 1.2', '~> 1.3'
22
+ s.add_dependency 'sinatra', '~> 1'
23
23
  s.add_dependency 'mustache', '~> 0.99'
24
24
  s.add_dependency 'tilt', '~> 1.2', '~> 1.3'
25
25
 
@@ -0,0 +1,14 @@
1
+ module FakeTemplateHelper
2
+ def name first_name, last_name
3
+ [first_name, last_name].join ' '
4
+ end
5
+ def friends *friends
6
+ friends.join ' & '
7
+ end
8
+ def sour_drink type
9
+ "#{type} Sour"
10
+ end
11
+ def random_drink
12
+ "Beer"
13
+ end
14
+ end
@@ -22,6 +22,57 @@ describe 'sinatra-mustache', :type => :request do
22
22
  end
23
23
  end
24
24
  end
25
+
26
+ context "with defined mustache template helpers" do
27
+ before(:each) do
28
+ @app = mock_helper_app {
29
+ register Sinatra::MustacheHelper
30
+ layout { 'Hello, I am {{ name.Moto.Tantra }} and these are my friends {{ friends.Hazy.Lazy.Crazy }}! Come and join us for a {{ sour_drink.Whiskey }} or just a {{ random_drink }}' }
31
+ helpers do
32
+ def name first_name, last_name
33
+ [first_name, last_name].join ' '
34
+ end
35
+ def friends *friends
36
+ friends.join ' & '
37
+ end
38
+ def sour_drink type
39
+ "#{type} Sour"
40
+ end
41
+ def random_drink
42
+ "Beer"
43
+ end
44
+ end
45
+ mustache_helpers :name, :friends, :sour_drink, :random_drink
46
+ get('/foo') { mustache 'foo' }
47
+ }
48
+ end
49
+ after(:each) do
50
+ clean_helper_app
51
+ end
52
+ it "should include them and make them usable" do
53
+ get '/foo'
54
+ response.body.should == "Hello, I am Moto Tantra and these are my friends Hazy &amp; Lazy &amp; Crazy! Come and join us for a Whiskey Sour or just a Beer"
55
+ end
56
+ end
57
+
58
+ context "with a module of mustache template helpers" do
59
+ before(:each) do
60
+ @app = mock_helper_app {
61
+ register Sinatra::MustacheHelper
62
+ layout { 'Hello, I am {{ name.Moto.Tantra }} and these are my friends {{ friends.Hazy.Lazy.Crazy }}! Come and join us for a {{ sour_drink.Whiskey }} or just a {{ random_drink }}' }
63
+ helpers FakeTemplateHelper
64
+ mustache_helpers FakeTemplateHelper
65
+ get('/foo') { mustache 'foo' }
66
+ }
67
+ end
68
+ after(:each) do
69
+ clean_helper_app
70
+ end
71
+ it "should include them and make them usable" do
72
+ get '/foo'
73
+ response.body.should == "Hello, I am Moto Tantra and these are my friends Hazy &amp; Lazy &amp; Crazy! Come and join us for a Whiskey Sour or just a Beer"
74
+ end
75
+ end
25
76
 
26
77
  context 'inline mustache strings' do
27
78
  context 'without the :locals option' do
@@ -9,7 +9,7 @@ describe Tilt::MustacheTemplate do
9
9
  end
10
10
 
11
11
  describe '#render' do
12
- let(:template) { Tilt::MustacheTemplate.new { |t| 'Hello {{ name }}!'} }
12
+ let(:template) { Tilt::MustacheTemplate.new { |t| 'Hello {{ someone }}!'} }
13
13
 
14
14
  context 'without locals or a scope' do
15
15
  subject { template.render }
@@ -18,7 +18,7 @@ describe Tilt::MustacheTemplate do
18
18
  end
19
19
 
20
20
  context 'with locals' do
21
- subject { template.render(Object.new, :name => 'World') }
21
+ subject { template.render(Object.new, :someone => 'World') }
22
22
 
23
23
  it { should == 'Hello World!' }
24
24
  end
@@ -26,7 +26,7 @@ describe Tilt::MustacheTemplate do
26
26
  context 'with an objects scope' do
27
27
  let(:scope) do
28
28
  scope = Object.new
29
- scope.instance_variable_set(:@name, 'World')
29
+ scope.instance_variable_set(:@someone, 'World')
30
30
  scope
31
31
  end
32
32
 
@@ -35,6 +35,35 @@ describe Tilt::MustacheTemplate do
35
35
  it { should == 'Hello World!' }
36
36
  end
37
37
 
38
+ context 'methods of the scope' do
39
+ let(:template) do
40
+ Tilt::MustacheTemplate.new do |t|
41
+ 'Hello, I am {{ name.Moto.Tantra }} and these are my friends {{ friends.Hazy.Lazy.Crazy }}! Come and join us for a {{ sour_drink.Whiskey }} or just a {{ random_drink }}'
42
+ end
43
+ end
44
+
45
+ let(:scope) do
46
+ scope = Object.new
47
+ def scope.name first_name, last_name
48
+ [first_name, last_name].join ' '
49
+ end
50
+ def scope.friends *friends
51
+ friends.join ' & '
52
+ end
53
+ def scope.sour_drink type
54
+ "#{type} Sour"
55
+ end
56
+ def scope.random_drink
57
+ "Beer"
58
+ end
59
+ scope
60
+ end
61
+
62
+ subject { template.render(scope) }
63
+
64
+ it { should == "Hello, I am Moto Tantra and these are my friends Hazy &amp; Lazy &amp; Crazy! Come and join us for a Whiskey Sour or just a Beer" }
65
+ end
66
+
38
67
  context 'with both an object and locals' do
39
68
  let(:template) do
40
69
  Tilt::MustacheTemplate.new {
@@ -4,6 +4,22 @@ module RequestHelper
4
4
  def mock_app(base=Sinatra::Base, &block)
5
5
  @app = Sinatra.new(base, &block)
6
6
  end
7
+
8
+ def mock_helper_app &block
9
+ @helper_app = Sinatra::Base
10
+ @helper_app.class_eval &block
11
+ @helper_app
12
+ end
13
+
14
+ def clean_helper_app
15
+ Sinatra::Base.class_eval do
16
+ layout { "{{ yield }}" }
17
+ undef :name if instance_methods.include?(:name)
18
+ undef :friends if instance_methods.include?(:friends)
19
+ undef :sour_drink if instance_methods.include?(:sour_drink)
20
+ undef :random_drink if instance_methods.include?(:random_drink)
21
+ end
22
+ end
7
23
 
8
24
  def app
9
25
  Rack::Lint.new(@app)
@@ -11,6 +27,7 @@ module RequestHelper
11
27
 
12
28
  def mustache_app(&block)
13
29
  mock_app {
30
+ helpers Sinatra::MustacheHelper
14
31
  set :environment, :test
15
32
  set :views, File.dirname(__FILE__) + '/views'
16
33
  get '/', &block
@@ -4,6 +4,7 @@ require 'rack'
4
4
  require 'rack/test'
5
5
 
6
6
  require 'request_helper'
7
+ require 'fake_template_helper'
7
8
 
8
9
  RSpec.configure do |config|
9
10
  config.include RequestHelper, :type => :request
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra-mustache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-22 00:00:00.000000000 Z
13
+ date: 2013-03-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
@@ -19,10 +19,7 @@ dependencies:
19
19
  requirements:
20
20
  - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: '1.2'
23
- - - ~>
24
- - !ruby/object:Gem::Version
25
- version: '1.3'
22
+ version: '1'
26
23
  type: :runtime
27
24
  prerelease: false
28
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -30,10 +27,7 @@ dependencies:
30
27
  requirements:
31
28
  - - ~>
32
29
  - !ruby/object:Gem::Version
33
- version: '1.2'
34
- - - ~>
35
- - !ruby/object:Gem::Version
36
- version: '1.3'
30
+ version: '1'
37
31
  - !ruby/object:Gem::Dependency
38
32
  name: mustache
39
33
  requirement: !ruby/object:Gem::Requirement
@@ -118,10 +112,13 @@ files:
118
112
  - LISCENSE
119
113
  - README.md
120
114
  - Rakefile
115
+ - lib/proxies/currystache.rb
121
116
  - lib/sinatra-mustache/version.rb
117
+ - lib/sinatra/helpers/mustache.rb
122
118
  - lib/sinatra/mustache.rb
123
119
  - lib/tilt/mustache_template.rb
124
120
  - sinatra-mustache.gemspec
121
+ - spec/fake_template_helper.rb
125
122
  - spec/mustache_spec.rb
126
123
  - spec/mustache_template_spec.rb
127
124
  - spec/request_helper.rb
@@ -151,11 +148,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
148
  version: '0'
152
149
  requirements: []
153
150
  rubyforge_project: sinatra-mustache
154
- rubygems_version: 1.8.24
151
+ rubygems_version: 1.8.25
155
152
  signing_key:
156
153
  specification_version: 3
157
154
  summary: Use Mustache in your Sinatra app without the extra view classes
158
155
  test_files:
156
+ - spec/fake_template_helper.rb
159
157
  - spec/mustache_spec.rb
160
158
  - spec/mustache_template_spec.rb
161
159
  - spec/request_helper.rb