backbone-handlebars 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. data/.document +5 -0
  2. data/Gemfile +16 -0
  3. data/Guardfile +18 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.markdown +58 -0
  6. data/Rakefile +67 -0
  7. data/VERSION +1 -0
  8. data/generators/backbone_view/backbone_view_generator.rb +9 -0
  9. data/generators/backbone_view/templates/view.coffee.erb +2 -0
  10. data/generators/backbone_view/templates/view_template.html.handlebars +2 -0
  11. data/lib/assets/javascripts/handlebars_helpers.coffee +46 -0
  12. data/lib/assets/javascripts/handlebars_view.coffee +26 -0
  13. data/lib/backbone-handlebars.rb +5 -0
  14. data/lib/backbone-handlebars/engine.rb +9 -0
  15. data/lib/backbone-handlebars/helper.rb +13 -0
  16. data/lib/generators/backbone/USAGE +8 -0
  17. data/lib/generators/backbone/backbone_generator.rb +6 -0
  18. data/rakelib/coffeescript.rake +30 -0
  19. data/spec/javascripts/fixtures/child_view.handlebars.html +4 -0
  20. data/spec/javascripts/fixtures/multiple_child_parent_view.handlebars.html +7 -0
  21. data/spec/javascripts/fixtures/parent_view.handlebars.html +6 -0
  22. data/spec/javascripts/fixtures/simple_view.handlebars.html +4 -0
  23. data/spec/javascripts/handlebars_view_spec.coffee +55 -0
  24. data/spec/javascripts/helpers/SpecHelper.js +9 -0
  25. data/spec/javascripts/helpers/loadTemplateHelper.js +17 -0
  26. data/spec/javascripts/jasmine-jquery-1.1.3.js +205 -0
  27. data/spec/javascripts/jquery.js +167 -0
  28. data/spec/javascripts/support/jasmine.yml +78 -0
  29. data/spec/javascripts/support/jasmine_config.rb +23 -0
  30. data/spec/javascripts/support/jasmine_runner.rb +32 -0
  31. data/test/helper.rb +18 -0
  32. data/test/test_backbone-handlebars.rb +7 -0
  33. data/vendor/assets/javascripts/backbone.js +1066 -0
  34. data/vendor/assets/javascripts/handlebars.js +1417 -0
  35. data/vendor/assets/javascripts/underscore.js +748 -0
  36. metadata +164 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.6.0"
12
+ gem "rcov", ">= 0"
13
+ gem "jasmine"
14
+ gem "coffee-script"
15
+ gem "guard-coffeescript"
16
+ end
data/Guardfile ADDED
@@ -0,0 +1,18 @@
1
+ # A sample Guardfile
2
+ # More info at http://github.com/guard/guard#readme
3
+ #
4
+ # Guard is a tool to respond to local filesystem events and take action. As such, it works better using native filesystem event libraries
5
+ #
6
+ # 1. Setup an RVM 1.9.2 environment to run guard
7
+ # 2. gem install guard-coffeescript growl rb-fsevent
8
+ # 3. run the 'guard' command; this fires up a server to monitor the coffescript as shown below
9
+ # 4. C-\ will force guard to recompile everything it knows about
10
+ # 5. Install the Gowl "Extras" growlnotify
11
+
12
+ guard 'coffeescript', :output => 'javascripts/compiled' do
13
+ watch(%r{lib/assets/javascripts/.+\.coffee})
14
+ end
15
+
16
+ guard 'coffeescript', :output => 'spec/javascripts/compiled', :bare => true do
17
+ watch(%r{spec/javascripts/.*_spec\.coffee})
18
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Chris Nelson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,58 @@
1
+ handlebone
2
+ ===================
3
+
4
+ This gem is extracted out of a backbone project where we are using handlebars
5
+ templates. It contains:
6
+
7
+ * handlebars.js
8
+ * A HandlebarsView superclass
9
+ * a rails helper module for rendering all your handlebars templates into your rails view
10
+ * Some handlebars helpers to make things easier
11
+
12
+ Usage
13
+ =====
14
+
15
+ This gem is designed to integrate with the asset pipeline of rails 3.1+. Somewhere in your
16
+ coffeescript or javascript code you'll need to require it:
17
+
18
+ #= require handlebars_view
19
+
20
+ This will bring in handlebars and the view superclass. To use it, write a view like so:
21
+
22
+ class FooView extends HandlebarsView
23
+
24
+ name: "foo_view"
25
+
26
+ This will cause the view to look for a template in an element with id "foo_view_template" and use
27
+ handlebars to render this view, passing in the view's model as the template
28
+ context. You can change this by overriding the templateContext function in your view.
29
+
30
+ HandlebarsHelpers
31
+ =================
32
+
33
+ Some helper methods to make writing those templates easier.
34
+
35
+ {{get "property"}}
36
+
37
+ This will grab a property from the model that is the current context
38
+
39
+ {{#eachProperty "children"}}hi!{{/eachProperty}}
40
+
41
+ A block helper that iterates over a property that contains an array.
42
+
43
+ Somewhere in your DOM ready, you'll need to call registerHelpers. Like so:
44
+
45
+ $ -> Backbone.HandlebarsHelpers.registerHelpers()
46
+
47
+ Also, you can register your own helpers by passing an object where each propery is a method that will
48
+ become a helper
49
+
50
+ Backbone.HandlebarsHelpers.registerHelpers(new MyHelpers())
51
+
52
+ RenderTemplatesHelper
53
+ ======================
54
+
55
+ We've found it best practice to keep our handlebars templates in separate files so our rails
56
+ views don't get all noisy. This all let's use the same HandleBars view on more than one rails
57
+ view and in our jasmine specs. This gem also includes a rails helper module RenderTemplatesHelper.
58
+ Best to just look at the code to see what it does for now, it's super simple.
data/Rakefile ADDED
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "backbone-handlebars"
18
+ gem.homepage = "http://github.com/superchris/backbone-handlebars"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Backbone views with handlebars templates}
21
+ gem.description = %Q{That's all folks}
22
+ gem.email = "superchrisnelson@gmail.com"
23
+ gem.authors = ["Chris Nelson"]
24
+ gem.files.include "vendor/assets/**/*"
25
+ gem.files.include "lib/**/*"
26
+ # dependencies defined in Gemfile
27
+ end
28
+ Jeweler::RubygemsDotOrgTasks.new
29
+
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+
37
+ require 'rcov/rcovtask'
38
+ Rcov::RcovTask.new do |test|
39
+ test.libs << 'test'
40
+ test.pattern = 'test/**/test_*.rb'
41
+ test.verbose = true
42
+ test.rcov_opts << '--exclude "gems/*"'
43
+ end
44
+
45
+ task :default => :test
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "backbone-handlebars #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
57
+ begin
58
+ require 'jasmine'
59
+ load 'jasmine/tasks/jasmine.rake'
60
+ rescue LoadError
61
+ task :jasmine do
62
+ abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine"
63
+ end
64
+ end
65
+
66
+
67
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,9 @@
1
+ class BackboneViewGenerator < Rails::Generator::NamedBase
2
+
3
+ def manifest
4
+ record do |m|
5
+ m.template "view.coffee.erb", "backbone/views/#{name}.coffee", :assigns => {:name => name}
6
+ m.template "view_template.html.handlebars", "backbone/templates/#{name}.html.handlebars", :assigns => {:name => name}
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,2 @@
1
+ class <%= name.camelize %> extends TemplateView
2
+ name: "<%= name %>"
@@ -0,0 +1,2 @@
1
+ <script id="<%=name%>_template" type="text/html">
2
+ </script>
@@ -0,0 +1,46 @@
1
+ class Backbone.HandlebarsHelpers
2
+
3
+ is: (block) ->
4
+ hash = block.hash
5
+ block() if this[hash.property] == hash.value
6
+
7
+ stripe: (collection, block) ->
8
+ item_contents = for index in [0...collection.length]
9
+ collection[index].stripeClass = if ((index % 2) == 0) then "even" else "odd"
10
+ block collection[index]
11
+ item_contents.join("\n")
12
+
13
+ formatNumber: (number) ->
14
+ $.formatNumber number, {format: "#,###"}
15
+
16
+ formatCurrency: (number) ->
17
+ $.formatNumber number, {format: "$#,###.00"}
18
+
19
+ formatPercentage: (number) ->
20
+ formatted = $.formatNumber number, {format: "#,###.0000"}
21
+ "#{formatted}%"
22
+
23
+ get: (property)->
24
+ @get(property)
25
+
26
+ helperMissing: -> ""
27
+
28
+ eachProperty: (property, block)->
29
+ block(object) for object in @get(property)
30
+
31
+ view: (block) ->
32
+ params = block.hash
33
+ view = block.data.view
34
+ viewClass = eval(params.viewClass)
35
+ if params.modelClass
36
+ modelClass = eval(params.modelClass)
37
+ model = new modelClass(this)
38
+ else
39
+ model = this
40
+ childView = new viewClass(model: model, parent: view)
41
+ view.subViews.push childView
42
+ block(model)
43
+
44
+ @registerHelpers: (helpers)->
45
+ helpers or= new HandlebarsHelpers()
46
+ Handlebars.registerHelper name, helper for name, helper of helpers
@@ -0,0 +1,26 @@
1
+ #= require handlebars
2
+ class Backbone.HandlebarsView extends Backbone.View
3
+ constructor: (options = {})->
4
+ @el = $("##{@name}") unless options.el
5
+ @subViews = []
6
+ @parent = options.parent
7
+ super
8
+ templateEl = $("##{@name}_template")
9
+ console.log "Did you include the template for #{@name}, putz?" if console? && templateEl.size() == 0
10
+ @template = if templateEl.size() > 0 then Handlebars.compile(templateEl.html(), true) else -> ""
11
+
12
+ templateContext: ->
13
+ @model
14
+
15
+ render: ->
16
+ @subViews = []
17
+ @el.html @template @templateContext(), Handlebars.helpers, Handlebars.partials, {view: this}
18
+ @renderSubView(subView) for subView in @subViews
19
+
20
+ findEl: ->
21
+ @el = $("[data-id='#{@model.id}']")
22
+
23
+ renderSubView: (subView) ->
24
+ subView.findEl()
25
+ subView.delegateEvents()
26
+ subView.render()
@@ -0,0 +1,5 @@
1
+ if Rails.version =~ /^3/
2
+ require 'rails'
3
+ require 'backbone-handlebars/engine'
4
+ require 'backbone-handlebars/helper'
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'rails'
2
+
3
+ module BackboneHandlebars
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,13 @@
1
+ module BackboneHandlebars
2
+ module RenderTemplatesHelper
3
+ def render_backbone_template(template)
4
+ raw File.read(::Rails.root.join "app", "assets", "templates", "#{template}.handlebars.html")
5
+ end
6
+
7
+ def render_backbone_templates
8
+ template_directory = ::Rails.root.join "app", "assets", "templates", "*.handlebars.html"
9
+ templates = Dir.glob(template_directory).collect { |t| File.read t }
10
+ raw templates.join("\n")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate backbone Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,6 @@
1
+ class BackboneGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path('../templates', __FILE__)
3
+ def create_backbone_directories
4
+ empty_directory "backbone"
5
+ end
6
+ end
@@ -0,0 +1,30 @@
1
+ namespace :coffeescript do
2
+
3
+ def compile_files(files, output_dir)
4
+ require 'coffee-script'
5
+ files.each do |f|
6
+ new_f = File.join(output_dir, f.pathmap("%n").match(/^([^.]+)/).to_s + ".js")
7
+ File.open(new_f, "w") do |out|
8
+ puts "compiling #{f} to #{new_f}"
9
+ out.puts CoffeeScript.compile File.read(f)
10
+ end
11
+ end
12
+ end
13
+
14
+ namespace :compile do
15
+ desc "re-compile the coffeescript into javascript"
16
+ task :assets do
17
+ coffee_files = FileList["lib/assets/javascripts/*.coffee" ]
18
+ mkdir_p "javascripts/compiled"
19
+ compile_files(coffee_files, "javascripts/compiled")
20
+ end
21
+
22
+ desc "re-compile the spec coffeescript into javascript"
23
+ task :specs do
24
+ mkdir_p "spec/javascripts/compiled"
25
+ compile_files(FileList["spec/javascripts/*.coffee"], "spec/javascripts/compiled")
26
+ end
27
+ end
28
+
29
+ task :compile => ["compile:assets", "compile:specs"]
30
+ end
@@ -0,0 +1,4 @@
1
+ <script id="child_view_template" type="text/x-handlebars-template">
2
+ Foo!
3
+ </script>
4
+
@@ -0,0 +1,7 @@
1
+ <script id="multiple_child_parent_view_template" type="text/x-handlebars-template">
2
+ {{#eachProperty "children"}}
3
+ {{#view viewClass="SimpleView"}}
4
+ <div data-id="{{id}}"></div>
5
+ {{/view}}
6
+ {{/eachProperty}}
7
+ </script>
@@ -0,0 +1,6 @@
1
+ <script id="parent_view_template" type="text/x-handlebars-template">
2
+ {{#view viewClass="ChildView"}}
3
+ <div id="child"></div>
4
+ {{/view}}
5
+ </script>
6
+
@@ -0,0 +1,4 @@
1
+ <script id="simple_view_template" type="text/x-handlebars-template">
2
+ <h1>{{get "foo"}}</h1>
3
+ </script>
4
+
@@ -0,0 +1,55 @@
1
+
2
+ class SimpleView extends Backbone.HandlebarsView
3
+ name: "simple_view"
4
+
5
+ class window.ParentView extends Backbone.HandlebarsView
6
+ name: "parent_view"
7
+
8
+ class window.ChildView extends Backbone.HandlebarsView
9
+ name: "child_view"
10
+ findEl: -> @el = $("#child")
11
+
12
+ class window.MultipleChildParentView extends Backbone.HandlebarsView
13
+ name: "multiple_child_parent_view"
14
+
15
+ class window.SimpleModel extends Backbone.Model
16
+
17
+ describe "HandlebarsView", ->
18
+ beforeEach ->
19
+ Backbone.HandlebarsHelpers.registerHelpers()
20
+ describe "SimpleView", ->
21
+ beforeEach ->
22
+ setFixtures "<div id='simple_view'></div>"
23
+ loadTemplate "simple_view.handlebars.html"
24
+ @simpleView = new SimpleView(model: new SimpleModel(foo: "bar"))
25
+ @simpleView.render()
26
+ it "finds it's el", ->
27
+ expect(@simpleView.el).toExist()
28
+ it "can render model data", ->
29
+ expect(@simpleView.el.html()).toMatch /bar/
30
+
31
+ describe "subviews", ->
32
+ beforeEach ->
33
+ setFixtures "<div id='parent_view'></div>"
34
+ loadTemplate "parent_view.handlebars.html"
35
+ loadTemplate "child_view.handlebars.html"
36
+ @parentView = new ParentView(model: new SimpleModel(id: 1))
37
+ @parentView.render()
38
+ it "renders the child template too", ->
39
+ expect(@parentView.el.html()).toMatch /Foo/
40
+ it "has a child view as a subviews", ->
41
+ expect(@parentView.subViews.length).toEqual(1)
42
+
43
+ describe "multiple child views", ->
44
+ beforeEach ->
45
+ setFixtures "<div id='multiple_child_parent_view'></div>"
46
+ loadTemplate "multiple_child_parent_view.handlebars.html"
47
+ loadTemplate "simple_view.handlebars.html"
48
+ children = [new SimpleModel(id: 1, foo: "baz"), new SimpleModel(id: 2, foo: "bing")]
49
+ @multipleChildParentView = new MultipleChildParentView(model: new SimpleModel(children: children))
50
+ @multipleChildParentView.render()
51
+ it "renders children views", ->
52
+ expect(@multipleChildParentView.el.html()).toMatch /baz/
53
+ expect(@multipleChildParentView.el.html()).toMatch /bing/
54
+
55
+