ember-rails 0.2.4 → 0.3.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.
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # ember-rails [![Build Status](https://secure.travis-ci.org/keithpitt/ember-rails.png)](http://travis-ci.org/keithpitt/ember-rails)
1
+ # ember-rails [![Build Status](https://secure.travis-ci.org/keithpitt/ember-rails.png)](http://travis-ci.org/keithpitt/ember-rails) [![Dependency Status](https://gemnasium.com/emberjs/ember-rails.png)](https://gemnasium.com/emberjs/ember-rails)
2
2
 
3
- ember-rails allows you to include [Ember.JS](http://emberjs.com/) into your Rails 3.x application.
3
+ ember-rails allows you to include [Ember.JS](http://emberjs.com/) into your Rails 3.1+ application.
4
4
 
5
5
  The gem will also pre-compile your handlebars templates when building your asset pipeline. It includes development and production copies of Ember.
6
6
 
7
- You can see an example of how to use the gem [here](https://github.com/keithpitt/ember-rails-example)
7
+ You can see an example of how to use the gem [here](https://github.com/keithpitt/ember-rails-example). There is also a great tutorial by [Dan Gebhardt](https://twitter.com/#!/dgeb) called "[Beginning Ember.js on Rails](http://www.cerebris.com/blog/2012/01/24/beginning-ember-js-on-rails-part-1/)" which is a great read if your just starting out with Rails and Ember.js
8
8
 
9
9
  ## Getting started
10
10
 
@@ -12,23 +12,81 @@ Add the gem to your application Gemfile:
12
12
 
13
13
  gem "ember-rails"
14
14
 
15
- Run `bundle install` and add the following line to
16
- `app/assets/javascripts/application.js`:
15
+ Run `bundle install` and add the following line to `app/assets/javascripts/application.js`:
17
16
 
18
17
  //= require ember
19
18
 
20
19
  Ember-rails also provides a way to run Ember in development mode, you
21
- can switch out your require statements to use the dev copies like so:
20
+ can switch out your require statement `//= require ember` to use the
21
+ dev copies like so:
22
22
 
23
23
  //= require ember-dev
24
24
 
25
+ ## Architecture
26
+
27
+ Ember does not require an organized file structure. However, ember-rails allows you
28
+ to use `rails g ember:bootstrap` to create the following directory structure under `app/assets/javascripts/ember`:
29
+
30
+ controllers/
31
+ helpers/
32
+ models/
33
+ templates/
34
+ views/
35
+
36
+ Additionally, it will add the following lines to `app/assets/javascripts/application.js`.
37
+ By default, it uses the Rails Application's name and creates an `rails_app_name.js.coffee`
38
+ file to setup application namespace and initial requires:
39
+
40
+ //= require ember
41
+ //= require ember/app
42
+
43
+ *Example:*
44
+
45
+ rails g ember:bootstrap
46
+ insert app/assets/javascripts/application.js
47
+ create app/assets/javascripts/ember/models
48
+ create app/assets/javascripts/ember/models/.gitkeep
49
+ create app/assets/javascripts/ember/controllers
50
+ create app/assets/javascripts/ember/controllers/.gitkeep
51
+ create app/assets/javascripts/ember/views
52
+ create app/assets/javascripts/ember/views/.gitkeep
53
+ create app/assets/javascripts/ember/helpers
54
+ create app/assets/javascripts/ember/helpers/.gitkeep
55
+ create app/assets/javascripts/ember/templates
56
+ create app/assets/javascripts/ember/templates/.gitkeep
57
+ create app/assets/javascripts/ember/app.js.coffee
58
+
59
+ If you want to avoid `.gitkeep` files, use the `skip git` option like
60
+ this: `rails g ember:bootstrap -g`.
61
+
25
62
  Ask Rails to serve HandlebarsJS and pre-compile templates to Ember
26
- by putting each template in a dedicated ".js.hjs" or ".handlebars" file
63
+ by putting each template in a dedicated ".js.hjs", ".hbs" or ".handlebars" file
27
64
  (e.g. `app/assets/javascripts/templates/admin_panel.handlebars`)
28
65
  and including the assets in your layout:
29
66
 
30
67
  <%= javascript_include_tag "templates/admin_panel" %>
31
68
 
69
+ If you want to strip template root from template names, add `templates_root` option to your application configuration block :
70
+
71
+ config.handlebars.templates_root = 'templates'
72
+
73
+ The result will be like this :
74
+
75
+ Ember.TEMPLATES['admin_panel'] = "...";
76
+
77
+ If you want a different path separator in template names add `templates_path_separator` option to your application configuration block :
78
+
79
+ config.handlebars.templates_path_separator = '-'
80
+
81
+ The result will be like this :
82
+
83
+ Ember.TEMPLATES['templates-admin_panel'] = "...";
84
+
85
+ Default behavior for ember-rails is to precompile handlebars templates only in production environment.
86
+ If you don't want this behavior you can turn it off in your application configuration block :
87
+
88
+ config.handlebars.precompile = false
89
+
32
90
  Bundle all templates together thanks to Sprockets,
33
91
  e.g create `app/assets/javascripts/templates/all.js` with:
34
92
 
@@ -38,6 +96,17 @@ Now a single line in the layout loads everything:
38
96
 
39
97
  <%= javascript_include_tag "templates/all" %>
40
98
 
99
+ If you use Slim or Haml templates, you can use handlebars filter :
100
+
101
+ handlebars:
102
+ {{view Ember.Button}}OK{{/view}}
103
+
104
+ It will be translated as :
105
+
106
+ <script type="text/x-handlebars">
107
+ {{view Ember.Button}}OK{{/view}}
108
+ </script>
109
+
41
110
  ## Note on Patches/Pull Requests
42
111
 
43
112
  1. Fork the project.
data/lib/ember-rails.rb CHANGED
@@ -1,14 +1 @@
1
- require 'sprockets'
2
- require 'sprockets/engines'
3
- require 'ember-rails/hjs_template'
4
-
5
- module EmberRails
6
- class Engine < Rails::Engine
7
- end
8
-
9
- # Registers the HandlebarsJS template engine so that
10
- # an asset file having the extension ".hjs" is processed
11
- # by the asset pipeline and converted to javascript code.
12
- Sprockets.register_engine '.hjs', HjsTemplate
13
- Sprockets.register_engine '.handlebars', HjsTemplate
14
- end
1
+ require 'ember_rails'
@@ -0,0 +1,11 @@
1
+ module Haml
2
+ module Filters
3
+ module Handlebars
4
+ include Base
5
+ def render_with_options(text, options)
6
+ type = "type=#{options[:attr_wrapper]}text/x-handlebars#{options[:attr_wrapper]}"
7
+ "<script #{type}>\n#{text.rstrip}\n</script>"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module Slim
2
+ class EmbeddedEngine
3
+ register :handlebars, TagEngine, :tag => :script, :attributes => { :type => 'text/x-handlebars' }
4
+ end
5
+ end
@@ -15,7 +15,7 @@ console.log = console.info = console.warn = console.error = function(){};
15
15
  var jQuery = window.jQuery = function() { return jQuery };
16
16
  jQuery.ready = function() { return jQuery };
17
17
  jQuery.inArray = function() { return jQuery };
18
- jQuery.jquery = "1.7.1";
18
+ jQuery.jquery = "1.7.2";
19
19
  var $ = jQuery;
20
20
 
21
21
  // Precompiler
@@ -0,0 +1,48 @@
1
+ require 'execjs'
2
+
3
+ module Ember
4
+ module Handlebars
5
+ class Source
6
+ class << self
7
+ def precompiler_path
8
+ File.expand_path(File.join(__FILE__, '../assets/ember-precompiler.js'))
9
+ end
10
+
11
+ def vendor_path
12
+ path = ::Rails.root.nil? ? '' : ::Rails.root.join('vendor/assets/javascripts/ember.js')
13
+
14
+ if !File.exists?(path)
15
+ path = File.expand_path(File.join(__FILE__, '../../../../vendor/assets/javascripts/ember.js'))
16
+ end
17
+ end
18
+
19
+ def path
20
+ @path ||= ENV['EMBER_SOURCE_PATH'] || vendor_path
21
+ end
22
+
23
+ def contents
24
+ @contents ||= [File.read(precompiler_path), File.read(path)].join("\n")
25
+ end
26
+
27
+ def handlebars_version
28
+ @handlebars_version ||= contents[/^Handlebars.VERSION = "([^"]*)"/, 1]
29
+ end
30
+
31
+ def ember_version
32
+ @ember_version ||= contents[/^Ember.VERSION = '([^']*)'/, 1]
33
+ end
34
+
35
+ def context
36
+ @context ||= ExecJS.compile(contents)
37
+ end
38
+ end
39
+ end
40
+
41
+ class << self
42
+ def compile(template)
43
+ template = template.read if template.respond_to?(:read)
44
+ Source.context.call('EmberRails.precompile', template)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,54 @@
1
+ require 'ember/handlebars/source'
2
+
3
+ module Ember
4
+ module Handlebars
5
+ class Template < Tilt::Template
6
+ def self.default_mime_type
7
+ 'application/javascript'
8
+ end
9
+
10
+ def prepare; end
11
+
12
+ def evaluate(scope, locals, &block)
13
+ template = mustache_to_handlebars(scope, data)
14
+
15
+ if configuration.precompile
16
+ func = Ember::Handlebars.compile(template)
17
+ "Ember.TEMPLATES[#{template_path(scope.logical_path).inspect}] = Ember.Handlebars.template(#{func});\n"
18
+ else
19
+ "Ember.TEMPLATES[#{template_path(scope.logical_path).inspect}] = Ember.Handlebars.compile(#{indent(template).inspect});\n"
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def mustache_to_handlebars(scope, template)
26
+ if scope.pathname.to_s =~ /\.mustache\.(handlebars|hjs)/
27
+ template.gsub(/\{\{(\w[^\}\}]+)\}\}/){ |x| "{{unbound #{$1}}}" }
28
+ else
29
+ template
30
+ end
31
+ end
32
+
33
+ def template_path(path)
34
+ root = configuration.templates_root
35
+
36
+ unless root.blank?
37
+ path.gsub!(/^#{Regexp.quote(root)}\/?/, '')
38
+ end
39
+
40
+ path = path.split('/')
41
+
42
+ path.join(configuration.templates_path_separator)
43
+ end
44
+
45
+ def configuration
46
+ ::Rails.configuration.handlebars
47
+ end
48
+
49
+ def indent(string)
50
+ string.gsub(/$(.)/m, "\\1 ").strip
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,7 @@
1
+ require 'ember/handlebars/source'
2
+
3
+ module Ember
4
+ module Handlebars
5
+ VERSION = Ember::Handlebars::Source.handlebars_version
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ require 'ember/handlebars/template'
2
+
3
+ module Ember
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ config.handlebars = ActiveSupport::OrderedOptions.new
7
+ config.handlebars.precompile = ::Rails.env.production?
8
+ config.handlebars.templates_root = nil
9
+ config.handlebars.templates_path_separator = '/'
10
+
11
+ initializer :setup_ember_rails, :group => :all do |app|
12
+ app.assets.register_engine '.handlebars', Ember::Handlebars::Template
13
+ app.assets.register_engine '.hbs', Ember::Handlebars::Template
14
+ app.assets.register_engine '.hjs', Ember::Handlebars::Template
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Ember
2
+ module Rails
3
+ VERSION = '0.3.1'
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'ember/handlebars/source'
2
+
3
+ module Ember
4
+ VERSION = Ember::Handlebars::Source.ember_version
5
+ end
@@ -0,0 +1,10 @@
1
+ require 'sprockets'
2
+ require 'sprockets/engines'
3
+
4
+ require 'ember/rails/engine'
5
+
6
+ require 'ember/version'
7
+ require 'ember/handlebars/version'
8
+
9
+ require 'ember/filters/slim' if defined? Slim
10
+ require 'ember/filters/haml' if defined? Haml
@@ -0,0 +1,39 @@
1
+ require 'generators/ember/generator_helpers'
2
+
3
+ module Ember
4
+ module Generators
5
+ class BootstrapGenerator < ::Rails::Generators::Base
6
+ include Ember::Generators::GeneratorHelpers
7
+
8
+ source_root File.expand_path("../../templates", __FILE__)
9
+
10
+ desc "Creates a default Ember.js folder layout in app/assets/javascripts/ember"
11
+
12
+ class_option :skip_git, :type => :boolean, :aliases => "-g", :default => false, :desc => "Skip Git keeps"
13
+
14
+ def inject_ember
15
+ application_file = "app/assets/javascripts/application.js"
16
+ if File.exists? application_file
17
+ inject_into_file(application_file, :before => "//= require_tree") do
18
+ dependencies = [
19
+ "//= require ember",
20
+ "//= require ember/#{application_name.underscore}"
21
+ ]
22
+ dependencies.join("\n").concat("\n")
23
+ end
24
+ end
25
+ end
26
+
27
+ def create_dir_layout
28
+ %W{models controllers views helpers templates}.each do |dir|
29
+ empty_directory "#{ember_path}/#{dir}"
30
+ create_file "#{ember_path}/#{dir}/.gitkeep" unless options[:skip_git]
31
+ end
32
+ end
33
+
34
+ def create_app_file
35
+ template "app.js", "#{ember_path}/#{application_name.underscore}.js"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ require 'ember/version'
2
+
3
+ module Ember
4
+ module Generators
5
+ class ControllerGenerator < ::Rails::Generators::NamedBase
6
+ source_root File.expand_path("../../templates", __FILE__)
7
+
8
+ desc "Creates a new Ember.js controller"
9
+ class_option :array, :type => :boolean, :default => false, :desc => "Create an Ember.ArrayController to represent multiple objects"
10
+
11
+ def create_controller_files
12
+ file_path = File.join('app/assets/javascripts/ember/controllers', class_path, "#{file_name}_controller.js")
13
+ if options.array?
14
+ template 'array_controller.js', file_path
15
+ else
16
+ template 'controller.js', file_path
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module Ember
2
+ module Generators
3
+ module GeneratorHelpers
4
+
5
+ def ember_path
6
+ "app/assets/javascripts/ember"
7
+ end
8
+
9
+ def application_name
10
+ if defined?(::Rails) && ::Rails.application
11
+ ::Rails.application.class.name.split('::').first
12
+ else
13
+ "app"
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,92 @@
1
+ require 'ember/version'
2
+
3
+ module Ember
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+
7
+ EMBER_FILES = [ "ember.js", "ember-dev.js" ]
8
+ RUNTIME_FILES = [ "ember-runtime.js", "ember-runtime-dev.js" ]
9
+ ALL_FILES = [ *EMBER_FILES, *RUNTIME_FILES ]
10
+
11
+ desc "Install Ember.js into your vendor folder"
12
+ class_option :head, :type => :boolean, :default => false, :desc => "Download latest Ember.js from GitHub and copy it into your project"
13
+ class_option :runtime, :type => :boolean, :default => false, :desc => "Include the Ember.js runtime only"
14
+
15
+ def remove_ember
16
+ ALL_FILES.each do |name|
17
+ file = "vendor/assets/javascripts/#{name}"
18
+ remove_file file if File.exist?(file)
19
+ end
20
+ end
21
+
22
+ def copy_ember
23
+ if options.head?
24
+
25
+ git_root = File.expand_path "~/.ember"
26
+ gem_file = File.join git_root, "Gemfile"
27
+
28
+ # If it doesn't exist yet
29
+ unless File.exist?(git_root)
30
+ command = %{git clone git://github.com/emberjs/ember.js.git "#{git_root}"}
31
+ say_status("downloading", command, :green)
32
+
33
+ cmd command
34
+ else
35
+ Dir.chdir git_root do
36
+ command = "git fetch --force --quiet --tags && git reset HEAD --hard"
37
+ say_status("updating", command, :green)
38
+
39
+ cmd command
40
+ end
41
+ end
42
+
43
+ Dir.chdir git_root do
44
+ say_status("building", "bundle && bundle exec rake", :green)
45
+ Bundler.with_clean_env do
46
+ cmd "bundle --gemfile #{gem_file}"
47
+ cmd %{BUNDLE_GEMFILE="#{gem_file}" bundle exec rake}
48
+ end
49
+ end
50
+
51
+ self.class.source_root File.join(git_root, "dist")
52
+
53
+ ember_files.each do |name|
54
+ source_file = if name.match /-dev/
55
+ name.gsub /-dev/, '.debug'
56
+ else
57
+ name.gsub /.js/, '.prod.js'
58
+ end
59
+
60
+ copy_file source_file, "vendor/assets/javascripts/#{name}"
61
+ end
62
+
63
+ else
64
+
65
+ self.class.source_root File.expand_path('../../../../../vendor/assets/javascripts', __FILE__)
66
+ say_status("copying", "Ember.js (#{Ember::VERSION})", :green)
67
+
68
+ ember_files.each do |name|
69
+ copy_file name, "vendor/assets/javascripts/#{name}"
70
+ end
71
+
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def ember_files
78
+ options.runtime? ? RUNTIME_FILES : EMBER_FILES
79
+ end
80
+
81
+ def cmd(command)
82
+ out = `#{command}`
83
+
84
+ if $?.exitstatus != 0
85
+ raise "Command error: command `#{command}` in directory #{Dir.pwd} has failed."
86
+ end
87
+ out
88
+ end
89
+
90
+ end
91
+ end
92
+ end