handlebars-amd-rails 1.0.0.rc.3

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/.jshintrc ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ // default settings
3
+ "forin" : true,
4
+ "noarg" : true,
5
+ "noempty" : true,
6
+ "eqeqeq" : true,
7
+ "bitwise" : true,
8
+ "strict" : true,
9
+ "undef" : true,
10
+ "curly" : true,
11
+ "browser" : true,
12
+ "indent" : 4,
13
+ "maxerr" : 50,
14
+ "white" : true,
15
+ "newcap" : true,
16
+ "expr" : true,
17
+
18
+ // project specific
19
+ "browser" : true,
20
+
21
+ // globals
22
+ "predef": {
23
+ // vendor
24
+ "require" : true,
25
+ "define" : true,
26
+ }
27
+ }
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --order random
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in handlebars-amd-rails.gemspec
4
+ gemspec
5
+
6
+ gem 'rspec'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Steffen Leistner
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,169 @@
1
+ # Handlebars Amd Rails
2
+
3
+ Use Handlebars templates wrapped in a AMD define block, with the asset pipeline in Rails 3.1+ applications.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ group :assets do
11
+ gem 'handlebars-amd-rails'
12
+ end
13
+ ```
14
+
15
+ Update your bundle:
16
+
17
+ ```
18
+ $ bundle install
19
+ ```
20
+
21
+ Require handlebars.js in your AMD config file
22
+
23
+ ```javascript
24
+ {
25
+ paths: {
26
+ "handlebars": "handlebars-runtime"
27
+ }
28
+ }
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ Place individual Handlebars template file in their own file with template_name.{hbs, handlebars} extension.
34
+
35
+ ```
36
+ /* app/assets/javascripts/templates/demo.hbs */
37
+
38
+ Hello {{name}}! You have {{count}} new messages.
39
+ ```
40
+
41
+ Which will be compiled and rendered as:
42
+
43
+ ```javascript
44
+ define(['handlebars'], function(Handlebars) {
45
+ var templates = Handlebars.templates || (Handlebars.templates = {});
46
+ return templates['demo'] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
47
+ helpers = helpers || Handlebars.helpers; data = data || {};
48
+ return "Hello {{name}}! You have {{count}} new messages.";
49
+ });
50
+ });
51
+ ```
52
+
53
+ You can take advantage of the asset pipeline by chaining your template through other processors like haml:
54
+
55
+ ```
56
+ /* app/assets/javascripts/templates/demo.hbs.haml */
57
+
58
+ %p.welcome
59
+ Hello {{name}}! You have {{count}} new messages.
60
+ ```
61
+
62
+ Which will be compiled and rendered as:
63
+
64
+ ```javascript
65
+ define(['handlebars'], function(Handlebars) {
66
+ var templates = Handlebars.templates || (Handlebars.templates = {});
67
+ return templates['demo'] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
68
+ helpers = helpers || Handlebars.helpers; data = data || {};
69
+ return "<p class='welcome'>Hello {{name}}! You have {{count}} new messages.</p>";
70
+ });
71
+ });
72
+ ```
73
+
74
+ You may need to require the haml_assets gem:
75
+
76
+ ```ruby
77
+ group :assets do
78
+ gem 'haml_assets'
79
+ end
80
+ ```
81
+
82
+ Using templates:
83
+
84
+ ```javascript
85
+ require([
86
+ 'jquery',
87
+ 'template!demo'
88
+ ], function ($, template) {
89
+ $('body').html(template({
90
+ name: 'Joe', count: 10
91
+ }))
92
+ });
93
+ ```
94
+
95
+ If the template renders partials, partial files need to be required:
96
+
97
+ ```
98
+ /* app/assets/javascripts/templates/demo.hbs */
99
+
100
+ {{>_header}}
101
+
102
+ Hello {{name}}! You have {{count}} new messages.
103
+ ```
104
+
105
+ ```
106
+ /* app/assets/javascripts/templates/_header.hbs */
107
+
108
+ %header
109
+ Hola!
110
+ ```
111
+
112
+ ```javascript
113
+ require([
114
+ 'jquery',
115
+ 'template!demo',
116
+ 'partial!_header',
117
+ ], function ($, template) {
118
+ $('body').html(template({
119
+ name: 'Joe', count: 10
120
+ }))
121
+ });
122
+ ```
123
+
124
+ ## Sample Code
125
+
126
+ Find a demo application at [https://github.com/sleistner/handlebars-amd-rails-example](https://github.com/sleistner/handlebars-amd-rails-example)
127
+
128
+ ## Config
129
+
130
+ Handlebars-amd-rails resolves the name of the template out of relative path of each template file. Relative path starts from app/assets/javascripts/templates/ by default.
131
+
132
+ If you want to change the default root path of template files, add following configuration into application.rb:
133
+
134
+ ```ruby
135
+ # config/application.rb
136
+ module YourApp
137
+ class Application < Rails::Application
138
+ config.handlebars.template_root = 'app/assets/your_path_to_templates/'
139
+ end
140
+ end
141
+ ```
142
+
143
+ You can pass arbitrary option parameters to the handlebars compiler:
144
+
145
+ ```ruby
146
+ # config/application.rb
147
+ module YourApp
148
+ class Application < Rails::Application
149
+ config.handlebars.data = false
150
+ end
151
+ end
152
+ ```
153
+
154
+ ## Credits
155
+
156
+ I shamelessly borrowed code from the following sources:
157
+
158
+ * [https://github.com/thefron/dust-rails](https://github.com/thefron/dust-rails)
159
+ * [https://github.com/leshill/handlebars_assets](https://github.com/leshill/handlebars_assets)
160
+
161
+ Thanks guys!
162
+
163
+ ## Contributing
164
+
165
+ 1. Fork it
166
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
167
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
168
+ 4. Push to the branch (`git push origin my-new-feature`)
169
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'handlebars-amd-rails/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "handlebars-amd-rails"
8
+ gem.version = Handlebars::Amd::Rails::VERSION
9
+ gem.authors = ["Steffen Leistner"]
10
+ gem.email = ["sleistner@gmail.com"]
11
+ gem.summary = %q{Use Handlebars templates wrapped in a AMD define block with rails.}
12
+ gem.description = %q{Use Handlebars templates wrapped in a AMD define block, with the asset pipeline in Rails 3.1+ applications.}
13
+ gem.homepage = "https://github.com/sleistner/handlebars-amd-rails"
14
+
15
+ gem.rubyforge_project = "handlebars-amd-rails"
16
+
17
+ gem.add_dependency('rails', '> 3.1.0')
18
+ gem.add_dependency('tilt')
19
+ gem.add_dependency('execjs')
20
+
21
+ gem.files = `git ls-files`.split($/)
22
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
23
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
24
+ gem.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,14 @@
1
+ require "rails/engine"
2
+
3
+ module Handlebars
4
+ module Amd
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ initializer :register_handlebars do |app|
8
+ app.assets.register_engine '.hbs', Template
9
+ app.assets.register_engine '.handlebars', Template
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ require 'rails'
2
+
3
+ module Handlebars
4
+ module Amd
5
+ module Rails
6
+ class Railtie < ::Rails::Railtie
7
+
8
+ DEFAULT_TEMPLATE_ROOT = 'app/assets/javascripts/templates/'
9
+
10
+ config.handlebars = ActiveSupport::OrderedOptions.new
11
+
12
+ initializer "handlebars.configure" do |app|
13
+ Handlebars.configure do |config|
14
+ config.template_root = app.config.handlebars[:template_root] || DEFAULT_TEMPLATE_ROOT
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,68 @@
1
+ require 'tilt'
2
+ require 'execjs'
3
+
4
+ module Handlebars
5
+
6
+ module Unindent
7
+ def unindent(heredoc)
8
+ heredoc.gsub(/^#{heredoc[/\A\s*/]}/, '')
9
+ end
10
+ end
11
+
12
+ module Amd
13
+ module Rails
14
+
15
+ module Source
16
+
17
+ def self.path
18
+ @path ||= File.expand_path("../../../../vendor/assets/javascripts/handlebars.js", __FILE__)
19
+ end
20
+
21
+ def self.contents
22
+ @contents ||= File.read(path)
23
+ end
24
+
25
+ def self.context
26
+ @context ||= ExecJS.compile(contents)
27
+ end
28
+
29
+ end
30
+
31
+ class Template < ::Tilt::Template
32
+
33
+ include Unindent
34
+
35
+ def self.default_mime_type
36
+ 'application/javascript'
37
+ end
38
+
39
+ def prepare
40
+ end
41
+
42
+ def evaluate(scope, locals, &block)
43
+ template = Source.context.call("Handlebars.precompile", data, Handlebars.config.to_camelcase)
44
+ interpolate(template)
45
+ end
46
+
47
+ private
48
+
49
+ def interpolate(template)
50
+ unindent <<-JS
51
+ define(['handlebars'], function(Handlebars) {
52
+ var templates = Handlebars.templates || (Handlebars.templates = {});
53
+ return templates['#{template_name}'] = Handlebars.template(#{template});
54
+ });
55
+ JS
56
+ end
57
+
58
+ def template_name
59
+ @template_name ||= begin
60
+ template_root = Handlebars.config.template_root
61
+ file.split(template_root).last.split('.', 2).first
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,7 @@
1
+ module Handlebars
2
+ module Amd
3
+ module Rails
4
+ VERSION = "1.0.0.rc.3"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ require 'handlebars-amd-rails/version'
2
+ require 'handlebars-amd-rails/rails/template'
3
+ require 'handlebars-amd-rails/rails/engine'
4
+ require 'handlebars-amd-rails/rails/railtie'
5
+ require 'ostruct'
6
+
7
+ module Handlebars
8
+
9
+ class Config < OpenStruct
10
+
11
+ def to_camelcase
12
+ instance_variable_get(:@table).inject({}) do |memo, (key, value)|
13
+ memo[key.to_s.camelcase(:lower)] = value
14
+ memo
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ def self.config
21
+ @@config ||= Config.new
22
+ end
23
+
24
+ def self.configure
25
+ yield self.config
26
+ end
27
+ end
@@ -0,0 +1 @@
1
+ hello {name}!
@@ -0,0 +1,19 @@
1
+ require_relative './spec_helper'
2
+
3
+ describe Handlebars::Config do
4
+
5
+ it 'can receive arbitrary options' do
6
+ subject.foo = :bar
7
+ subject.foo.should == :bar
8
+ end
9
+
10
+ describe '#to_camelcase' do
11
+
12
+ it 'transforms keys to camelcase' do
13
+ subject.foo_bar = :baz
14
+ subject.to_camelcase.should == { 'fooBar' => :baz }
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,5 @@
1
+ Handlebars = {
2
+ precompile: function () {
3
+ return '"Precompiled!"';
4
+ }
5
+ };
@@ -0,0 +1,22 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'handlebars-amd-rails'
5
+
6
+ include Handlebars::Unindent
7
+
8
+ def fixtures_path
9
+ @fixtures_path ||= File.expand_path('../fixtures', __FILE__)
10
+ end
11
+
12
+ def fixture_path(name)
13
+ "#{fixtures_path}/#{name}"
14
+ end
15
+
16
+ def helper_path
17
+ @helper_path ||= File.expand_path('../helper', __FILE__)
18
+ end
19
+
20
+ def helper(name)
21
+ File.new("#{helper_path}/#{name}")
22
+ end
@@ -0,0 +1,28 @@
1
+ require_relative './spec_helper'
2
+
3
+ describe Handlebars::Amd::Rails::Template do
4
+
5
+ subject do
6
+ Handlebars::Amd::Rails::Template.new(fixture_path('demo.hbs'))
7
+ end
8
+
9
+ describe '#evaluate' do
10
+
11
+ before do
12
+ Handlebars.config.template_root = fixtures_path + '/'
13
+ Handlebars::Amd::Rails::Source.stub(:path).and_return(helper('handlebars.js'))
14
+ end
15
+
16
+ it 'compiles a template wrapped in a define block' do
17
+ expected = unindent <<-JS
18
+ define(['handlebars'], function(Handlebars) {
19
+ var templates = Handlebars.templates || (Handlebars.templates = {});
20
+ return templates['demo'] = Handlebars.template("Precompiled!");
21
+ });
22
+ JS
23
+ subject.evaluate(nil, nil).should == expected
24
+ end
25
+
26
+ end
27
+
28
+ end