choco 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/HISTORY +3 -0
  4. data/LICENSE +20 -0
  5. data/README.rdoc +326 -0
  6. data/Rakefile +55 -0
  7. data/bin/choco +45 -0
  8. data/choco.gemspec +98 -0
  9. data/lib/choco.rb +16 -0
  10. data/lib/choco/cli.rb +75 -0
  11. data/lib/choco/dependency_manager.rb +92 -0
  12. data/lib/choco/generators/app_generator.rb +72 -0
  13. data/lib/choco/generators/controller_generator.rb +21 -0
  14. data/lib/choco/generators/layout_generator.rb +19 -0
  15. data/lib/choco/generators/model_generator.rb +20 -0
  16. data/lib/choco/generators/plugin_generator.rb +20 -0
  17. data/lib/choco/generators/scaffold_generator.rb +65 -0
  18. data/lib/choco/generators/templates/Jimfile +24 -0
  19. data/lib/choco/generators/templates/README.rdoc +3 -0
  20. data/lib/choco/generators/templates/Rakefile +25 -0
  21. data/lib/choco/generators/templates/application.css +1 -0
  22. data/lib/choco/generators/templates/choco +7 -0
  23. data/lib/choco/generators/templates/controllers/application_controller.js +33 -0
  24. data/lib/choco/generators/templates/controllers/base_controller.js +6 -0
  25. data/lib/choco/generators/templates/controllers/rest_controller.js +53 -0
  26. data/lib/choco/generators/templates/help/commands +12 -0
  27. data/lib/choco/generators/templates/help/generators +33 -0
  28. data/lib/choco/generators/templates/helpers/application_helper.js +7 -0
  29. data/lib/choco/generators/templates/index.html +16 -0
  30. data/lib/choco/generators/templates/lib/plugin.js +40 -0
  31. data/lib/choco/generators/templates/models/base.js +7 -0
  32. data/lib/choco/generators/templates/views/edit.template +14 -0
  33. data/lib/choco/generators/templates/views/index.template +32 -0
  34. data/lib/choco/generators/templates/views/layout.js +4 -0
  35. data/lib/choco/generators/templates/views/main/index.template +1 -0
  36. data/lib/choco/generators/templates/views/new.template +14 -0
  37. data/lib/choco/generators/templates/views/show.template +10 -0
  38. data/spec/choco_spec.rb +7 -0
  39. data/spec/spec.opts +1 -0
  40. data/spec/spec_helper.rb +9 -0
  41. metadata +164 -0
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/HISTORY ADDED
@@ -0,0 +1,3 @@
1
+ == 0.1.0 [07-22-10]
2
+
3
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Anthony Heukmes
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.
@@ -0,0 +1,326 @@
1
+ = Choco
2
+
3
+ A delicious Javascript web framework made in Belgium!
4
+
5
+ Choco brings the MVC to the client side!
6
+
7
+ You like Javascript and you want to develop rich internet applications?
8
+ You also know that HTML & CSS are powerful?
9
+ Cappuccino & Sproutcore don't feel like web development anymore?
10
+
11
+ Thanks to Choco, you'll be able to easily develop maintainable web applications.
12
+ A Choco app consists of only one HTML page, all the interactions are managed by Javascript.
13
+ Your UI only uses HTML and CSS!
14
+
15
+ Choco is based on powerful libaries :
16
+
17
+ * Sammy (http://github.com/quirkey/sammy)
18
+ * js-model (http://github.com/benpickles/js-model)
19
+ * Jim (http://github.com/quirkey/jim)
20
+
21
+ Huge thanks to Aaron Quint and Ben Pickles for their incredible work.
22
+
23
+ == Installation
24
+
25
+ Choco is a Ruby gem, simply install it :
26
+
27
+ $ gem install choco
28
+
29
+ == A new application
30
+
31
+ $ choco new my_project
32
+
33
+ This will generate your project structure.
34
+
35
+ You can then install the required JS dependencies (jQuery, Sammy, ...) by executing the following command at the root of your project :
36
+
37
+ $ rake choco:js:install
38
+
39
+ == Location
40
+
41
+ A Choco app is composed of static files (js, css, images, ...), it must be directly accessible on your web server.
42
+ If you use Rails, you can for example put your Choco app inside the public/javascripts folder.
43
+
44
+ Once you've chosen the location where your application will reside, don't forget to configure the path to your view files.
45
+ You can find the line to edit in your application_controller (app/controllers).
46
+
47
+ Example for Rails :
48
+
49
+ this.use(Sammy.SmartRenderer, '/javascripts/my_project/app/views/');
50
+
51
+ == Jim
52
+
53
+ Jim is mix of Ruby gems & Bundler but for Javascript libraries.
54
+
55
+ When you install a JS library using the $ jim install command, it is stored in your home folder (~/.jim/lib).
56
+ All your projects can then use this repository to load the required dependencies.
57
+
58
+ The $ rake choco:js:install command installs all the dependencies you need to run a Choco app.
59
+
60
+ A Jimfile is located at the root of your project, it lists all these dependencies.
61
+ They can be libraries (jQuery, Sammy, ...) but also local JS files of your application (controllers, models, ...).
62
+
63
+ All these files are bundled into the compressed/bundled.js file, so you only have to include this file in your HTML page and all your Choco app will be loaded.
64
+
65
+ You can continuously track changes in your JS files by running the following command in your project root folder :
66
+
67
+ $ choco --watch
68
+
69
+ The watch script will track your JS files (creation, edition, suppression) and automatically update your Jimfile & bundled.js to reflect these changes.
70
+ You never have to worry about including your JS files inside your HTML page, just include bundled.js!
71
+
72
+ == Access your homepage
73
+
74
+ To launch your application, just call the index.html page.
75
+ I'm using Rails, I will call the following URL in my web browser :
76
+ http://localhost:3000/javascripts/choco_app/index.html
77
+
78
+ Notice that when the app is launched, the URL changes to :
79
+ http://localhost:3000/javascripts/choco_app/index.html#/main
80
+
81
+ #/main is a route in your Choco app (thanks to Sammy), it is defined in your ApplicationController.
82
+
83
+ this.get('#/main', function(cx) {
84
+ });
85
+
86
+ You have to include this # in every HTML link you add into your views.
87
+
88
+ <a href="#/posts">List all the posts</a>
89
+ <a href="#/posts/new">Add a new post</a>
90
+ ...
91
+
92
+ = Project structure
93
+
94
+ A Choco project has the following structure :
95
+
96
+ == Jimfile
97
+ This file list all the dependencies for your project (libraries & local files).
98
+
99
+ == app
100
+ It contains four sub-folders : controllers, helpers, models & views.
101
+ This is where you will spend most of your development time.
102
+
103
+ == compressed
104
+ This is where the bundled.js file is created, it bundles all your JS files in one single file.
105
+ It is highly recommended to compress this file before going live (rake choco:deploy).
106
+
107
+ == images
108
+ Store all the images used by your application in this folder.
109
+
110
+ == index.html
111
+ This is the file you have to open in your browser to launch your Choco application.
112
+ It includes your bundled.js file, your stylesheets and defines the layout of your application.
113
+
114
+ The #choco div is very important, this is where the HTML generated by your views will be inserted.
115
+ If you change his name, you must configure it into the app/controllers/application_controller.js as well.
116
+
117
+ == lib
118
+ Use this folder to store your JS files which are specific to your project but don't have their place in the app folder.
119
+ If this is a library that can be used by other projects, you should use Jim instead.
120
+
121
+ == script
122
+ This folder contains the choco script file.
123
+ It brings you a few generators (model, controller, layout, scaffold, json, plugin).
124
+
125
+ == spec
126
+ Test your application using Behavior Driven Development (BDD).
127
+
128
+ == stylesheets
129
+ Store all the stylesheets used by your application in this folder.
130
+
131
+ = A first resource (CRUD)
132
+
133
+ First of all, don't forget to start the choco watcher ($ choco --watch) if you don't want to update your Jimfile manually.
134
+
135
+ The easiest way to get started is to generate a scaffold based on JSON.
136
+ Use your server side technology to create a web service that returns JSON representing your resource.
137
+
138
+ For example, with Rails :
139
+
140
+ def index
141
+ render :json => Post.all
142
+ end
143
+
144
+ Once you have that, you can generate your scaffold very easily :
145
+
146
+ $ choco generate scaffold post http://localhost:3000/posts
147
+
148
+ This will create the PostsController with all the actions, the views and the model.
149
+
150
+ Notice that the Choco watcher automatically updated your Jimfile and your bundled.js.
151
+
152
+ It also updated your ApplicationController by adding the following line :
153
+
154
+ PostsController(this);
155
+
156
+ You can now call this new page with the following URL :
157
+ http://localhost:3000/javascripts/choco_app/index.html#/posts
158
+
159
+ This will send a GET request to the #/posts URL of your application.
160
+ This request will be handled by your PostsController and more precisely by this action :
161
+
162
+ get('#/posts', function(cx) {
163
+ cx.posts = Post.all();
164
+ });
165
+
166
+ We are using our model to get all the posts (locally) and store them in the posts variable.
167
+ Using cx will make this variable available in your view.
168
+
169
+ Like Rails, Choco will automatically render the view with the same name as the current action (located in the view folder with the same name as the current controller).
170
+ In our case app/views/posts/index.template will be rendered.
171
+
172
+ This is a simple HTML page with some Javascript tags.
173
+
174
+ Here is a part of it :
175
+
176
+ <% $.each(posts, function(i, post) { %>
177
+ <tr id="post_<%= post.id() %>">
178
+ <td>
179
+ <%= post.attr('created_at') %>
180
+ </td>
181
+ <td>
182
+ <%= post.attr('author') %>
183
+ </td>
184
+ ...
185
+
186
+ We are iterating on our posts array to create a table row for each of them.
187
+
188
+ You will not see any post yet because you haven't loaded the post from your server (JSON).
189
+
190
+ To do that, just update your ApplicationController by adding your Post model in the models array :
191
+
192
+ var models = [Post];
193
+ ChocoUtils.loadModels(models, function() {
194
+ app.run('#/main');
195
+ });
196
+
197
+ All your models will be loaded by calling the load() method on their class.
198
+ This action will send Ajax requests to your server.
199
+ The Choco application will then be launched when all the responses have been received and treated.
200
+
201
+ To create, remove & update posts, you have to create your REST controller on the server side.
202
+ Have a look at the sample demo for an example (http://github.com/ahe/choco_demo).
203
+
204
+ = Generators
205
+
206
+ The following code generators are available :
207
+
208
+ * $ choco generate controller <controller_name>
209
+ * $ choco generate model <model_name>
210
+ * $ choco generate scaffold <name> [field1 field2 ...]
211
+ * $ choco generate scaffold <name> <url>
212
+ * $ choco generate layout <layout_name>
213
+ * $ choco generate plugin <plugin_name>
214
+
215
+ Don't forget to start the choco --watch command before executing any generator. Otherwise you'll have to update manually your Jimfile, bundled.js & application_controller.js.
216
+
217
+ = Controllers
218
+
219
+ To learn more about controllers, please read Sammy documentation : http://code.quirkey.com/sammy
220
+
221
+ You may be wondering about the best solution to execute Javascript code after rendering a template.
222
+ Let's say we want to add a specific behavior to one of our link, in the app/views/posts/index.template view, I add this simple link :
223
+
224
+ <a href="#" id="test_link">Hey, click me, I'm a simple test!</a>
225
+
226
+ I want to open a Javascript alert when it is clicked.
227
+
228
+ I can simply update my controller like this :
229
+
230
+ get('#/posts', function(cx) {
231
+ cx.posts = Post.all();
232
+ cx.render({ template: 'posts/index', event: 'posts_loaded', data: { size: cx.posts.length }});
233
+ });
234
+
235
+ bind('posts_loaded', function(e, data) {
236
+ $('#test_link').click(function() {
237
+ alert('Hey! We have ' + data['size'] + ' posts!');
238
+ return false;
239
+ });
240
+ });
241
+
242
+ I call the render() method explicitly because I want to trigger an event when the template is rendered.
243
+ This event is named 'posts_loaded' and when it is executed it simply add a Javascript behavior to my link.
244
+
245
+ The render method supports various options like like layouts, events & more.
246
+ You can read the doc here : http://github.com/ahe/choco.libs/blob/master/plugins/sammy/choco.plugins.sammy.smart_renderer.js
247
+
248
+ = Views
249
+
250
+ By default, Choco uses simple template views where you can combine HTML and Javascript.
251
+
252
+ You can easily display values in your views :
253
+
254
+ <%= post.attr('title') %>
255
+
256
+ Or call helpers you defined :
257
+
258
+ <% myHelper(); %> // Don't forget the ;
259
+
260
+ You can also of course use conditions, iterators & more.
261
+
262
+ You can easily switch to HAML or Mustache by configuring it in your application controller.
263
+ Have a look at Sammy documentation for more information.
264
+
265
+ To create a DELETE link, just use the following attributes :
266
+
267
+ <a href="#/posts/<%= post.id() %>" verb="delete" confirm="Are you sure?">Delete</a>
268
+
269
+ = Models
270
+
271
+ For more information about models, please read js-model documentation : http://github.com/benpickles/js-model
272
+
273
+ js-model stores all the data locally. You can persist your models to the server using methods like save() but don't forget to implement your REST controller on the server side.
274
+ Have a look at the demo for an example : http://github.com/ahe/choco_demo
275
+
276
+ js-model expects JSON without the ROOT element included. In Rails that means you have to disable this option :
277
+
278
+ ActiveRecord::Base.include_root_in_json = false
279
+
280
+ = Logger
281
+
282
+ You can call the logger from anywhere in your application by simply calling :
283
+
284
+ app.logger('hello choco!');
285
+
286
+ = Plugins
287
+
288
+ Models, views & controllers can easily be extended using plugins.
289
+
290
+ You can generate a new plugin using the following command :
291
+
292
+ $ choco generate plugin <plugin_name>
293
+
294
+ Existing plugins & Choco libs are stored here : http://github.com/ahe/choco.libs
295
+
296
+ = Deploy
297
+
298
+ When you deploy your application on live, don't forget to compress your files :
299
+
300
+ $ rake choco:deploy
301
+
302
+ Then just copy the required files on your web server.
303
+
304
+ = BDD
305
+
306
+ BDD is currently being implemented, it will be soon very easy to test all the parts of your Choco apps.
307
+ A first solution can be found here : http://github.com/ahe/sammy_demo/tree/master/test/javascript
308
+
309
+ = Note on Patches/Pull Requests
310
+
311
+ * Fork the project.
312
+ * Make your feature addition or bug fix.
313
+ * Add tests for it. This is important so I don't break it in a
314
+ future version unintentionally.
315
+ * Commit, do not mess with rakefile, version, or history.
316
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
317
+ * Send me a pull request. Bonus points for topic branches.
318
+
319
+ == Copyright
320
+
321
+ Copyright (c) 2010 Anthony Heukmes. See LICENSE for details.
322
+
323
+ * http://2dconcept.com
324
+ * http://intotheweb.be
325
+ * http://twitter.com/2dc
326
+ * http://twitter.com/intotheweb
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
5
+
6
+ require 'choco'
7
+
8
+ begin
9
+ require 'jeweler'
10
+ Jeweler::Tasks.new do |gem|
11
+ gem.name = "choco"
12
+ gem.version = Choco::VERSION
13
+ gem.summary = %Q{A delicious Javascript web framework made in Belgium!}
14
+ gem.description = %Q{Choco brings the MVC to the client side! It allows you to easily develop maintainable Rich Internet Applications using Javascript.}
15
+ gem.email = "anthony.heukmes@skynet.be"
16
+ gem.homepage = "http://github.com/ahe/choco"
17
+ gem.authors = ["Anthony Heukmes"]
18
+
19
+ gem.add_dependency "jim"
20
+ gem.add_dependency "fssm"
21
+ gem.add_dependency "thor"
22
+ gem.add_dependency "activesupport"
23
+
24
+ gem.add_development_dependency "rspec", ">= 1.2.9"
25
+ end
26
+ Jeweler::GemcutterTasks.new
27
+ rescue LoadError
28
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
29
+ end
30
+
31
+ require 'spec/rake/spectask'
32
+ Spec::Rake::SpecTask.new(:spec) do |spec|
33
+ spec.libs << 'lib' << 'spec'
34
+ spec.spec_files = FileList['spec/**/*_spec.rb']
35
+ end
36
+
37
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
38
+ spec.libs << 'lib' << 'spec'
39
+ spec.pattern = 'spec/**/*_spec.rb'
40
+ spec.rcov = true
41
+ end
42
+
43
+ task :spec => :check_dependencies
44
+
45
+ task :default => :spec
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 = "choco #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'choco'
4
+ require 'pathname'
5
+
6
+ module Choco
7
+ module ScriptChocoLoader
8
+ SCRIPT_CHOCO = File.join('script', 'choco')
9
+
10
+ def self.exec_script_choco!
11
+ cwd = Dir.pwd
12
+ exec 'ruby', SCRIPT_CHOCO, *ARGV if in_choco_application?
13
+
14
+ Dir.chdir("..") do
15
+ # Recurse in a chdir block: if the search fails we want to be sure
16
+ # the application is generated in the original working directory.
17
+ exec_script_choco! unless cwd == Dir.pwd
18
+ end
19
+ rescue SystemCallError
20
+ # could not chdir, no problem just return
21
+ end
22
+
23
+ def self.in_choco_application?
24
+ File.exists?(SCRIPT_CHOCO) || in_choco_application_subdirectory?
25
+ end
26
+
27
+ def self.in_choco_application_subdirectory?(path = Pathname.new(Dir.pwd))
28
+ File.exists?(File.join(path, SCRIPT_CHOCO)) || !path.root? && in_choco_application_subdirectory?(path.parent)
29
+ end
30
+ end
31
+ end
32
+
33
+ Choco::ScriptChocoLoader.exec_script_choco!
34
+
35
+ ARGV << '--help' if ARGV.empty?
36
+ command = ARGV.shift
37
+
38
+ case command
39
+ when 'new'
40
+ Choco::AppGenerator.start ARGV
41
+ when '-v'
42
+ puts "Choco version #{Choco::VERSION}"
43
+ else
44
+ puts "\nWelcome to Choco!\nA delicious Javascript web framework made in Belgium!\n\nUsage:\n\n$ choco new <project_name>\n-> Generates a new Choco project\n\n$ choco -v\n-> Displays current version\n"
45
+ end