backbonify 0.1.0
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/LICENSE +22 -0
- data/README.md +52 -0
- data/Rakefile +2 -0
- data/lib/assets/javascripts/backbone.filter.js +66 -0
- data/lib/assets/javascripts/backbone.grid.js +295 -0
- data/lib/assets/javascripts/backbone.js +1290 -0
- data/lib/assets/javascripts/backbone_datalink.js +21 -0
- data/lib/assets/javascripts/backbone_rails_sync.js +68 -0
- data/lib/assets/javascripts/jquery-ui.js +783 -0
- data/lib/assets/javascripts/jquery.js +9266 -0
- data/lib/assets/javascripts/jquery.notice.js +79 -0
- data/lib/assets/javascripts/json2.js +480 -0
- data/lib/assets/javascripts/underscore.js +999 -0
- data/lib/backbonify.rb +4 -0
- data/lib/backbonify/engine.rb +5 -0
- data/lib/backbonify/version.rb +3 -0
- data/lib/generators/backbonify/USAGE +8 -0
- data/lib/generators/backbonify/hbs/hbs_generator.rb +29 -0
- data/lib/generators/backbonify/hbs/templates/_form.haml +6 -0
- data/lib/generators/backbonify/hbs/templates/_row.haml +4 -0
- data/lib/generators/backbonify/hbs/templates/edit.haml +1 -0
- data/lib/generators/backbonify/hbs/templates/index.haml +13 -0
- data/lib/generators/backbonify/hbs/templates/new.haml +1 -0
- data/lib/generators/backbonify/hbs/templates/page.haml +6 -0
- data/lib/generators/backbonify/hbs/templates/show.haml +1 -0
- data/lib/generators/backbonify/install/install_generator.rb +57 -0
- data/lib/generators/backbonify/install/templates/app.js +47 -0
- data/lib/generators/backbonify/model/model_generator.rb +20 -0
- data/lib/generators/backbonify/model/templates/model.js +35 -0
- data/lib/generators/backbonify/resource_helpers.rb +63 -0
- data/lib/generators/backbonify/router/router_generator.rb +44 -0
- data/lib/generators/backbonify/router/templates/router.js +24 -0
- data/lib/generators/backbonify/router/templates/template.jst +2 -0
- data/lib/generators/backbonify/router/templates/view.coffee +8 -0
- data/lib/generators/backbonify/scaffold/scaffold_generator.rb +26 -0
- data/lib/generators/backbonify/views/templates/edit_view.js +34 -0
- data/lib/generators/backbonify/views/templates/filter_view.js +36 -0
- data/lib/generators/backbonify/views/templates/index_view.js +15 -0
- data/lib/generators/backbonify/views/templates/new_view.js +22 -0
- data/lib/generators/backbonify/views/templates/page_view.js +30 -0
- data/lib/generators/backbonify/views/templates/show_view.js +18 -0
- data/lib/generators/backbonify/views/views_generator.rb +21 -0
- metadata +122 -0
data/lib/backbonify.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'generators/backbonify/resource_helpers'
|
2
|
+
|
3
|
+
module Backbonify
|
4
|
+
module Generators
|
5
|
+
class HbsGenerator < Rails::Generators::NamedBase
|
6
|
+
include Backbonify::Generators::ResourceHelpers
|
7
|
+
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
desc "This generator creates a set of Handlebars templates for a model"
|
10
|
+
|
11
|
+
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
12
|
+
|
13
|
+
|
14
|
+
def create_templates
|
15
|
+
%w(page index show new edit).each do |view|
|
16
|
+
template "#{view}.haml", File.join(backbone_path, "templates", plural_name, "#{view}.jst.hbs.haml")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_partials
|
21
|
+
%w(_row _form).each do |view|
|
22
|
+
template "#{view}.haml", File.join(backbone_path, "templates", plural_name, "_#{singular_name}#{view}.jst.hbs.haml")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{{> <%= singular_name %>_row}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{{> <%= singular_name %>_form}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{{> <%= singular_name %>_row}}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'generators/backbonify/resource_helpers'
|
2
|
+
|
3
|
+
module Backbonify
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
include Backbonify::Generators::ResourceHelpers
|
7
|
+
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
desc "This generator installs backbone.js with a default folder layout in app/assets/javascripts/backbone"
|
10
|
+
class_option :skip_git, :type => :boolean, :aliases => "-G", :default => true,
|
11
|
+
:desc => "Skip Git ignores and keeps"
|
12
|
+
class_option :skip_require, :type => :boolean, :aliases => "-R", :default => true,
|
13
|
+
:desc => "Skip injection of requires in app.js (-R), useful for updates"
|
14
|
+
|
15
|
+
def copy_javascripts_libs_to_vendor
|
16
|
+
directory("../../../../../lib/assets/javascripts/", "vendor/assets/javascripts/", :recursive => true)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def inject_backbone
|
21
|
+
return if options[:skip_requires]
|
22
|
+
inject_into_file "app/assets/javascripts/application.js", :before => "//= require_tree" do
|
23
|
+
a = %{
|
24
|
+
//= require json2
|
25
|
+
//= require jquery
|
26
|
+
//= require jquery-ui
|
27
|
+
//= require jquery.notice
|
28
|
+
//= require handlebars.runtime
|
29
|
+
//= require underscore
|
30
|
+
//= require backbone
|
31
|
+
// require backbone_rails_sync
|
32
|
+
//= require backbone_datalink
|
33
|
+
//= require backbone.grid
|
34
|
+
//= require #{application_name.underscore}
|
35
|
+
|
36
|
+
$(function(){
|
37
|
+
window.app = #{application_name}.init()
|
38
|
+
});
|
39
|
+
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_dir_layout
|
45
|
+
%W{routers models views templates}.each do |dir|
|
46
|
+
empty_directory "app/assets/javascripts/#{dir}"
|
47
|
+
create_file "app/assets/javascripts/#{dir}/.gitkeep" unless options[:skip_git]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_app_file
|
52
|
+
template "app.js", "app/assets/javascripts/#{application_name.underscore}.js"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
//= require_self
|
2
|
+
//= require_tree ./templates
|
3
|
+
//= require_tree ./models
|
4
|
+
//= require_tree ./views
|
5
|
+
//= require_tree ./routers
|
6
|
+
|
7
|
+
var <%= js_app_name %> = (function(){
|
8
|
+
|
9
|
+
|
10
|
+
var initialize = function(){
|
11
|
+
initializeCollections();
|
12
|
+
startListening();
|
13
|
+
|
14
|
+
//new <%= js_app_name %>.Routers.SomeRouter;
|
15
|
+
Backbone.history.start();
|
16
|
+
}
|
17
|
+
|
18
|
+
var initializeCollections = function() {
|
19
|
+
//app.collection = new <%= js_app_name %>.Collections.SomeCollection;
|
20
|
+
}
|
21
|
+
|
22
|
+
var startListening = function() {
|
23
|
+
//app.collection.on("sync", notifySync)
|
24
|
+
//app.collection.on("error", notifyError)
|
25
|
+
}
|
26
|
+
|
27
|
+
var notifySync = function(collection) {
|
28
|
+
$.noticeAdd({text: "Succesfully saved, Yo!"})
|
29
|
+
}
|
30
|
+
|
31
|
+
var notifyError = function(collection) {
|
32
|
+
//_.delay(function() {self.$("input[type='submit']").prop("disabled", false)}, 3000)
|
33
|
+
$.noticeAdd({text: "Error yo, put a date or a film or something"})
|
34
|
+
}
|
35
|
+
|
36
|
+
var app = {
|
37
|
+
init : initialize,
|
38
|
+
Models: {},
|
39
|
+
Collections: {},
|
40
|
+
Routers: {},
|
41
|
+
Views: {}
|
42
|
+
};
|
43
|
+
|
44
|
+
|
45
|
+
return app;
|
46
|
+
|
47
|
+
})()
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'generators/backbonify/resource_helpers'
|
2
|
+
|
3
|
+
module Backbonify
|
4
|
+
module Generators
|
5
|
+
class ModelGenerator < Rails::Generators::NamedBase
|
6
|
+
include Backbonify::Generators::ResourceHelpers
|
7
|
+
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
desc "This generator creates a backbone model"
|
10
|
+
|
11
|
+
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
12
|
+
|
13
|
+
def create_backbone_model
|
14
|
+
template "model.js", "#{backbone_path}/models/#{file_name}.js"
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
//
|
2
|
+
// MODEL
|
3
|
+
//
|
4
|
+
<%= model_namespace %> = Backbone.Model.extend({
|
5
|
+
paramRoot: '<%= singular_table_name %>',
|
6
|
+
urlRoot: '<%= route_url %>',
|
7
|
+
|
8
|
+
defaults: {
|
9
|
+
<% attributes.each do |attribute| -%>
|
10
|
+
<%= attribute.name %>: null,
|
11
|
+
<% end -%>
|
12
|
+
noop:null
|
13
|
+
}
|
14
|
+
|
15
|
+
})
|
16
|
+
|
17
|
+
<%= collection_namespace %> = Backbone.Collection.extend({
|
18
|
+
model: <%= model_namespace %>,
|
19
|
+
url: '<%= route_url %>',
|
20
|
+
|
21
|
+
// A small decorator for 'fetch' to retain last data passed to it
|
22
|
+
fetch: function(options) {
|
23
|
+
this.fetchOptions = options || {};
|
24
|
+
Backbone.Collection.prototype.fetch.call(this, options);
|
25
|
+
},
|
26
|
+
|
27
|
+
// default_fetch uses the last data past to fetch to reload accordingly
|
28
|
+
default_fetch: function() {
|
29
|
+
this.fetch(this.fetchOptions)
|
30
|
+
}
|
31
|
+
|
32
|
+
})
|
33
|
+
|
34
|
+
_.extend(<%= collection_namespace %>.prototype, Filter);
|
35
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Backbonify
|
2
|
+
module Generators
|
3
|
+
module ResourceHelpers
|
4
|
+
|
5
|
+
def backbone_path
|
6
|
+
"app/assets/javascripts"
|
7
|
+
end
|
8
|
+
|
9
|
+
# => Perf.Models.Performance
|
10
|
+
def model_namespace
|
11
|
+
[js_app_name, "Models", class_name].join(".")
|
12
|
+
end
|
13
|
+
|
14
|
+
# => performance
|
15
|
+
def singular_model_name
|
16
|
+
uncapitalize singular_name.camelize
|
17
|
+
end
|
18
|
+
|
19
|
+
# => performances
|
20
|
+
def plural_model_name
|
21
|
+
uncapitalize(plural_name.camelize)
|
22
|
+
end
|
23
|
+
|
24
|
+
# => Perf.Collections.Performances
|
25
|
+
def collection_namespace
|
26
|
+
[js_app_name, "Collections", plural_name.camelize].join(".")
|
27
|
+
end
|
28
|
+
|
29
|
+
# => Perf.Views.Performances
|
30
|
+
def view_namespace
|
31
|
+
[js_app_name, "Views", plural_name.camelize].join(".")
|
32
|
+
end
|
33
|
+
|
34
|
+
# => Perf.Routers.Performances
|
35
|
+
def router_namespace
|
36
|
+
[js_app_name, "Routers", plural_name.camelize].join(".")
|
37
|
+
end
|
38
|
+
|
39
|
+
def jst(action)
|
40
|
+
"templates/#{plural_name}/#{action}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def js_app_name
|
44
|
+
application_name.camelize
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO : Add an option so "App" is default
|
48
|
+
def application_name
|
49
|
+
if defined?(Rails) && Rails.application
|
50
|
+
Rails.application.class.name.split('::').first
|
51
|
+
else
|
52
|
+
"application"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# uncapitalize("ABC") => aBC
|
57
|
+
def uncapitalize(str)
|
58
|
+
str[0, 1].downcase << str[1..-1]
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'generators/backbonify/resource_helpers'
|
2
|
+
|
3
|
+
module Backbonify
|
4
|
+
module Generators
|
5
|
+
class RouterGenerator < Rails::Generators::NamedBase
|
6
|
+
include Backbonify::Generators::ResourceHelpers
|
7
|
+
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
desc "This generator creates a backbone router (NOT with views and templates for the provided actions)"
|
10
|
+
|
11
|
+
argument :actions, :type => :array, :default => [], :banner => "action action"
|
12
|
+
|
13
|
+
RESERVED_JS_WORDS = %W{
|
14
|
+
break case catch continue debugger default delete do else finally for
|
15
|
+
function if in instanceof new return switch this throw try typeof var void while with
|
16
|
+
}
|
17
|
+
|
18
|
+
def validate_no_reserved_words
|
19
|
+
actions.each do |action|
|
20
|
+
if RESERVED_JS_WORDS.include? action
|
21
|
+
raise Thor::Error, "The name '#{action}' is reserved by javascript " <<
|
22
|
+
"Please choose an alternative action name and run this generator again."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_router_files
|
28
|
+
template 'router.js', File.join(backbone_path, "routers", class_path, "#{file_name}_router.js")
|
29
|
+
end
|
30
|
+
|
31
|
+
#def create_view_files
|
32
|
+
# actions.each do |action|
|
33
|
+
# @action = action
|
34
|
+
# @view_path = File.join(backbone_path, "views", plural_name, "#{action}_view.js.coffee")
|
35
|
+
# @jst_path = File.join(backbone_path,"templates", plural_name, "#{action}.jst.ejs")
|
36
|
+
#
|
37
|
+
# template "view.coffee", @view_path
|
38
|
+
# template "template.jst", @jst_path
|
39
|
+
# end
|
40
|
+
#end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
//
|
2
|
+
// Router
|
3
|
+
//
|
4
|
+
<%= router_namespace %>Router = Backbone.Router.extend({
|
5
|
+
routes : {
|
6
|
+
"<%= plural_name %>" : "index",
|
7
|
+
"<%= plural_name %>/:id" : "show"
|
8
|
+
},
|
9
|
+
|
10
|
+
page: null,
|
11
|
+
|
12
|
+
initialize : function() {
|
13
|
+
this.page = new <%= "#{view_namespace}.#{'page'.camelize}View()" %>
|
14
|
+
this.page.display();
|
15
|
+
},
|
16
|
+
|
17
|
+
index : function(){
|
18
|
+
$("#orchestraPage, #contractPage").hide()
|
19
|
+
this.page.slide()
|
20
|
+
},
|
21
|
+
|
22
|
+
show : function(id) {}
|
23
|
+
|
24
|
+
});
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'generators/backbonify/resource_helpers'
|
2
|
+
|
3
|
+
module Backbonify
|
4
|
+
module Generators
|
5
|
+
class ScaffoldGenerator < Rails::Generators::NamedBase
|
6
|
+
include Backbonify::Generators::ResourceHelpers
|
7
|
+
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
desc "This generator creates the client side crud scaffolding"
|
10
|
+
|
11
|
+
|
12
|
+
class_option :model, :default => true, :type => :string
|
13
|
+
hook_for :model
|
14
|
+
|
15
|
+
class_option :router, :default => true, :type => :string
|
16
|
+
hook_for :router
|
17
|
+
|
18
|
+
class_option :views, :default => true, :type => :string
|
19
|
+
hook_for :views
|
20
|
+
|
21
|
+
class_option :js_template, :default => "hbs", :type => :string
|
22
|
+
hook_for :js_template
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
//
|
2
|
+
// EDIT : <%= singular_name.capitalize %>
|
3
|
+
//
|
4
|
+
<%= view_namespace %> = <%= view_namespace %> || {};
|
5
|
+
|
6
|
+
<%= view_namespace %>.EditView = Grid.EditView.extend({
|
7
|
+
tagName : "tr",
|
8
|
+
className : "new_<%= singular_name %>",
|
9
|
+
template : JST["templates/<%= plural_name %>/show"],
|
10
|
+
cell : null,
|
11
|
+
attribute : null,
|
12
|
+
inputTag : null,
|
13
|
+
|
14
|
+
initialize : function() {
|
15
|
+
var self = this;
|
16
|
+
this.model.bind("sync", this.renderRow, this);
|
17
|
+
//this.slowSaving = _.debounce(function(){ self.model.save() }, 1100);
|
18
|
+
},
|
19
|
+
|
20
|
+
|
21
|
+
_createInputTemplate : function() {
|
22
|
+
if( this.cell.hasClass('address') ) {
|
23
|
+
return "<textarea style='height:25px' name='address'><%%="+ this.attribute+"%></textarea>"
|
24
|
+
} else {
|
25
|
+
return '<input id="<%= singular_name %>_' + this.attribute +
|
26
|
+
'" value="<%%=' + this.attribute +
|
27
|
+
'%>" name="' + this.attribute + '" />'
|
28
|
+
}
|
29
|
+
},
|
30
|
+
|
31
|
+
noop:null
|
32
|
+
});
|
33
|
+
|
34
|
+
//_.extend(<%= view_namespace %>.EditView.prototype, <%= js_app_name %>.FormHelpers);
|