tilt-handlebars 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tilt-handlebars.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jim Cushing
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Tilt::Handlebars
2
+
3
+ Adds support for [Handlebars.rb](https://github.com/cowboyd/handlebars.rb) template
4
+ engine to [Tilt](https://github.com/rtomayko/tilt).
5
+
6
+ See the [Handlebars.js](http://handlebarsjs.com) site for syntax.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'tilt-handlebars'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install tilt-handlebars
21
+
22
+ ## Usage
23
+
24
+ Create a Handlebars template file with either a `.hbs` or `.handlebars` extension.
25
+
26
+ Example, in `hello.hbs`:
27
+
28
+ ```
29
+ Hello, {{name}}. I'm {{emotion}} to meet you.
30
+ ```
31
+
32
+ Then, render the template with Ruby:
33
+
34
+ ```ruby
35
+ require 'tilt/handlebars'
36
+
37
+ template = Tilt.new('hello.hbs')
38
+ puts template.render(nil, name: "Joe", emotion: "happy")
39
+ ```
40
+
41
+ Output:
42
+
43
+ Hello, Joe. I'm happy to meet you.
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ desc 'Run tests (default)'
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.ruby_opts = ['-Itest']
8
+ t.ruby_opts << '-rubygems' if defined? Gem
9
+ end
@@ -0,0 +1,67 @@
1
+ require 'tilt' unless defined? Tilt
2
+ require 'handlebars'
3
+
4
+ module Tilt
5
+
6
+ # Handlebars.rb template implementation. See:
7
+ # https://github.com/cowboyd/handlebars.rb
8
+ # and http://handlebarsjs.com
9
+ #
10
+ # Handlebars is a logic-less template rendered with JavaScript.
11
+ # Handlebars.rb is a Ruby wrapper around Handlebars, that allows
12
+ # Handlebars templates to be rendered server side.
13
+ #
14
+ class HandlebarsTemplate < Template
15
+ def initialize_engine
16
+ @context = ::Handlebars::Context.new
17
+ end
18
+
19
+ def self.engine_initialized?
20
+ true
21
+ end
22
+
23
+ def prepare
24
+ @context = ::Handlebars::Context.new
25
+ @template = @context.compile(data)
26
+ end
27
+
28
+ def evaluate(scope, locals = {}, &block)
29
+ # Based on LiquidTemplate
30
+ locals = locals.inject({}){ |h,(k,v)| h[k.to_s] = v ; h }
31
+ if scope.respond_to?(:to_h)
32
+ scope = scope.to_h.inject({}){ |h,(k,v)| h[k.to_s] = v ; h }
33
+ locals = scope.merge(locals)
34
+ else
35
+ scope.instance_variables.each do |var|
36
+ key = var.to_s.delete("@")
37
+ locals[key] = scope.instance_variable_get(var) unless locals.has_key? key
38
+ end
39
+ end
40
+
41
+ locals['yield'] = block.nil? ? '' : yield
42
+ locals['content'] = locals['yield']
43
+
44
+ @template.call(locals);
45
+ end
46
+
47
+ def register_helper(name, &fn)
48
+ @context.register_helper(name, &fn)
49
+ end
50
+
51
+ def register_partial(*args)
52
+ @context.register_partial(*args)
53
+ end
54
+
55
+ def partial_missing(&fn)
56
+ @context.partial_missing(&fn)
57
+ end
58
+
59
+ def allows_script?
60
+ false
61
+ end
62
+ end
63
+
64
+ register HandlebarsTemplate, 'handlebars', 'hbs'
65
+ end
66
+
67
+
data/test/hello.hbs ADDED
@@ -0,0 +1 @@
1
+ Hello, {{ name }}. I'm {{ emotion }} to meet you.
@@ -0,0 +1,222 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+
4
+ require 'minitest/autorun'
5
+ require 'minitest/spec'
6
+
7
+ require 'tilt'
8
+ require 'tilt/handlebars'
9
+
10
+ def make_template(text)
11
+ Tilt::HandlebarsTemplate.new { |t| text }
12
+ end
13
+
14
+ describe Tilt::HandlebarsTemplate do
15
+ it 'renders from file' do
16
+ template = Tilt.new('test/hello.hbs')
17
+ template.render(nil, name: 'Joe', emotion: 'happy').must_equal "Hello, Joe. I'm happy to meet you.\n"
18
+ end
19
+
20
+ it 'is registered for .hbs files' do
21
+ Tilt['test.hbs'].must_equal Tilt::HandlebarsTemplate
22
+ end
23
+
24
+ it 'is registered for .handlebars files' do
25
+ Tilt['test.handlebars'].must_equal Tilt::HandlebarsTemplate
26
+ end
27
+
28
+ it 'renders static template' do
29
+ template = make_template "Hello World!"
30
+ template.render.must_equal "Hello World!"
31
+ end
32
+
33
+ it "can be rendered more than once" do
34
+ template = make_template "Hello World!"
35
+ 3.times { template.render.must_equal "Hello World!" }
36
+ end
37
+
38
+ it "substitutes locals in template" do
39
+ template = make_template "Hey {{ name }}!"
40
+ template.render(nil, :name => 'Joe').must_equal "Hey Joe!"
41
+ end
42
+
43
+ it "displays nested properties" do
44
+ template = make_template "Hey {{ person.name }}!"
45
+ template.render(nil, :person => { :name => 'Joe' }).must_equal "Hey Joe!"
46
+ end
47
+
48
+ it "displays text from block" do
49
+ template = make_template "Deck the halls. Fa {{ yield }}."
50
+ rendered = template.render(nil) { "la la la la"}
51
+ rendered.must_equal "Deck the halls. Fa la la la la."
52
+ end
53
+
54
+
55
+ describe "arrays" do
56
+ shopping_list = %w[milk eggs flour sugar]
57
+
58
+ it "displays element from array" do
59
+ template = make_template "Don't forget the {{ shopping_list.[1] }}!"
60
+ template.render(nil, :shopping_list => shopping_list).must_equal "Don't forget the eggs!"
61
+ end
62
+
63
+ it "displays elements in an array in a loop" do
64
+ template = make_template 'Items to buy:{{#each shopping_list}} {{ this }}{{/each}}'
65
+ template.render(nil, :shopping_list => shopping_list).must_equal "Items to buy: milk eggs flour sugar"
66
+ end
67
+
68
+ it "displays alternate text when array is empty" do
69
+ template = make_template 'Items to buy:{{#each shopping_list}} {{ this }}{{else}} All done!{{/each}}'
70
+ template.render(nil, :shopping_list => []).must_equal "Items to buy: All done!"
71
+ end
72
+ end
73
+
74
+ describe "conditionals" do
75
+ template = make_template '{{#if morning}}Good morning{{else}}Hello{{/if}}, {{ name }}'
76
+
77
+ it "displays text if value is true" do
78
+ template.render(nil, :name => 'Joe', :morning => true).must_equal "Good morning, Joe"
79
+ end
80
+
81
+ it "displays alternate text if value is false" do
82
+ template.render(nil, :name => 'Joe', :morning => false).must_equal "Hello, Joe"
83
+ end
84
+
85
+ it "displays alternate text if value is missing" do
86
+ template.render(nil, :name => 'Joe').must_equal "Hello, Joe"
87
+ end
88
+ end
89
+
90
+ describe "unless expressions" do
91
+ template = make_template 'Hello, {{ name }}.{{#unless weekend}} Time to go to work.{{/unless}}'
92
+
93
+ it "displays text if value is false" do
94
+ template.render(nil, :name => 'Joe', :weekend => false).must_equal "Hello, Joe. Time to go to work."
95
+ end
96
+
97
+ it "does not display text if value is true" do
98
+ template.render(nil, :name => 'Joe', :weekend => true).must_equal "Hello, Joe."
99
+ end
100
+
101
+ it "displays text if value is missing" do
102
+ template.render(nil, :name => 'Joe').must_equal "Hello, Joe. Time to go to work."
103
+ end
104
+ end
105
+
106
+ describe "escape HTML" do
107
+ it "escapes HTML characters" do
108
+ template = make_template "Hey {{ name }}!"
109
+ template.render(nil, :name => '<b>Joe</b>' ).must_equal "Hey &lt;b&gt;Joe&lt;/b&gt;!"
110
+ end
111
+
112
+ it "does not escape HTML characters in triple-stash" do
113
+ template = make_template "Hey {{{ name }}}!"
114
+ template.render(nil, :name => '<b>Joe</b>' ).must_equal "Hey <b>Joe</b>!"
115
+ end
116
+ end
117
+
118
+ describe "helpers" do
119
+ it "applies helper to static text" do
120
+ template = make_template '{{#upper}}Hello, World.{{/upper}}'
121
+ template.register_helper(:upper) do |this, block|
122
+ block.fn(this).upcase
123
+ end
124
+
125
+ template.render.must_equal "HELLO, WORLD."
126
+ end
127
+
128
+ it "applies helper to nested values" do
129
+ template = make_template '{{#upper}}Hey {{name}}{{/upper}}!'
130
+ template.register_helper(:upper) do |this, block|
131
+ block.fn(this).upcase
132
+ end
133
+
134
+ template.render(nil, :name => 'Joe').must_equal "HEY JOE!"
135
+ end
136
+
137
+ it "displays properties from object using 'with' helper" do
138
+ template = make_template '{{#with person}}Hello, {{ first_name }} {{ last_name }}{{/with}}'
139
+ joe = Person.new "Joe", "Blow"
140
+ template.render(nil, :person => joe).must_equal "Hello, Joe Blow"
141
+ end
142
+
143
+ end
144
+
145
+ describe "using scope object to render template" do
146
+ class Person
147
+ attr_reader :first_name, :last_name
148
+
149
+ def initialize(first_name, last_name)
150
+ @first_name = first_name
151
+ @last_name = last_name
152
+ end
153
+ end
154
+
155
+ class HashPerson
156
+ attr_reader :first_name, :last_name
157
+
158
+ def initialize(first_name, last_name)
159
+ @first_name = first_name
160
+ @last_name = last_name
161
+ end
162
+
163
+ def to_h
164
+ { first_name: @first_name, last_name: @last_name }
165
+ end
166
+ end
167
+
168
+ joe = Person.new "John", "Doe"
169
+
170
+ it "displays properties of object passed as scope" do
171
+ template = make_template "Hello, {{ first_name }} {{ last_name }}."
172
+ template.render(joe).must_equal "Hello, John Doe."
173
+ end
174
+
175
+ it "merges scope object properties with locals" do
176
+ template = make_template "{{ greeting }}, {{ first_name }} {{ last_name }}."
177
+ template.render(joe, :greeting => "Salut").must_equal "Salut, John Doe."
178
+ end
179
+
180
+ it "prefers locals over scope object properties with same name" do
181
+ template = make_template "Hello, {{ first_name }} {{ last_name }}."
182
+ template.render(joe, :first_name => "Jane").must_equal "Hello, Jane Doe."
183
+ end
184
+
185
+ it "prefers locals over scope object properties with same name when object defines to_h" do
186
+ joe_hash = HashPerson.new "John", "Doe"
187
+
188
+ template = make_template "Hello, {{ first_name }} {{ last_name }}."
189
+ template.render(joe_hash, :first_name => "Jane").must_equal "Hello, Jane Doe."
190
+ end
191
+ end
192
+
193
+ describe "comments" do
194
+ it "does not render comments" do
195
+ template = make_template "Hello world{{! what a wonderful world }}"
196
+ template.render.must_equal "Hello world"
197
+ end
198
+
199
+ it "does not render comments, alternative syntax" do
200
+ template = make_template "Hello world{{!-- what a wonderful world --}}"
201
+ template.render.must_equal "Hello world"
202
+ end
203
+ end
204
+
205
+ describe "partials" do
206
+ it "displays content of partial" do
207
+ template = make_template "{{> greeting}}. Nice to meet you."
208
+ template.register_partial :greeting, "Hey, {{name}}"
209
+ template.render(nil, :name => "Joe").must_equal "Hey, Joe. Nice to meet you."
210
+ end
211
+
212
+ it "calls registeded method if partial is missing" do
213
+ template = make_template "{{> where}} I've been looking for you."
214
+ template.partial_missing do |partial_name|
215
+ "Where have you been, {{name}}?" if partial_name == 'where'
216
+ end
217
+ template.render(nil, :name => "Joe").must_equal "Where have you been, Joe? I've been looking for you."
218
+ end
219
+ end
220
+ end
221
+
222
+
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "tilt-handlebars"
7
+ spec.version = "1.0"
8
+ spec.authors = ["Jim Cushing"]
9
+ spec.email = ["jimothy@mac.com"]
10
+ spec.description = "Use Handlebars.rb with Tilt"
11
+ spec.summary = spec.description
12
+ spec.homepage = "https://github.com/jimothyGator/tilt-handlebars"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "minitest", "~> 5.0"
23
+ spec.add_dependency "tilt", "~> 1.4"
24
+ spec.add_dependency "handlebars", "~> 0.4"
25
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tilt-handlebars
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jim Cushing
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: minitest
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '5.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: tilt
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '1.4'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.4'
78
+ - !ruby/object:Gem::Dependency
79
+ name: handlebars
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '0.4'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '0.4'
94
+ description: Use Handlebars.rb with Tilt
95
+ email:
96
+ - jimothy@mac.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - Gemfile
103
+ - LICENSE.txt
104
+ - README.md
105
+ - Rakefile
106
+ - lib/tilt/handlebars.rb
107
+ - test/hello.hbs
108
+ - test/tilt_handlebarstemplate_test.rb
109
+ - tilt-handlebars.gemspec
110
+ homepage: https://github.com/jimothyGator/tilt-handlebars
111
+ licenses:
112
+ - MIT
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ segments:
124
+ - 0
125
+ hash: -129076644092719377
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ segments:
133
+ - 0
134
+ hash: -129076644092719377
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 1.8.25
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Use Handlebars.rb with Tilt
141
+ test_files:
142
+ - test/hello.hbs
143
+ - test/tilt_handlebarstemplate_test.rb