Choco
A delicious Javascript web framework made in Belgium!
Choco brings the MVC to the client side!
You
like Javascript and you want to develop rich internet applications? You
also know that HTML & CSS are powerful? Cappuccino & Sproutcore
don’t feel like web development anymore?
Thanks to Choco, you’ll
be able to easily develop maintainable web applications. A Choco app
consists of only one HTML page, all the interactions are managed by
Javascript. Your UI only uses HTML and CSS!
Choco is based on powerful libaries :
Sammy (github.com/quirkey/sammy)
js-model (github.com/benpickles/js-model)
Jim (github.com/quirkey/jim)
Huge thanks to Aaron Quint and Ben Pickles for their incredible work.
A sample project based on Rails 3 is available here : github.com/ahe/choco_demo
An awesome screencast with an awesome belgian accent is available here : www.2dconcept.com/images/choco.mov
Follow us on Twitter : twitter.com/choco_js
Installation
Choco is a Ruby gem, simply install it :
$ gem install choco
A new application
$ choco new my_project
This will generate your project structure.
You
can then install the required JS dependencies (jQuery, Sammy, …) by
executing the following command at the root of your project :
$ rake choco:js:install
Launch your local server :
$ choco server
Location
A Choco app is composed of static files (js, css, images, …), it must be directly accessible on your web server.
A local Rack web server can be launched directly using the ‘$ choco server’ command. You’ll have to install WEBRick or Mongrel.
If you use Rails, you can for example put your Choco app inside the public/javascripts folder.
Once
you’ve chosen the location where your application will reside, don’t
forget to configure the path to your view files. You can find the line
to edit in your application_controller (app/controllers).
Example for Rails :
this.project_path = '/javascripts/my_project';
Jim
Jim is mix of Ruby gems & Bundler but for Javascript libraries.
When
you install a JS library using the $ jim install command, it is stored
in your home folder (~/.jim/lib). All your projects can then use this
repository to load the required dependencies.
The $ rake choco:js:install command installs all the dependencies you need to run a Choco app.
A
Jimfile is located at the root of your project, it lists all these
dependencies. They can be libraries (jQuery, Sammy, …) but also local JS
files of your application (controllers, models, …).
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.
You can continuously track changes in your JS files by running the following command in your project root folder :
$ choco --watch
The
watch script will track your JS files (creation, edition, suppression)
and automatically update your Jimfile & bundled.js to reflect these
changes. You never have to worry about including your JS files inside
your HTML page, just include bundled.js!
Access your homepage
To
launch your application, just call the index.html page. I’m using
Rails, I will call the following URL in my web browser :
localhost:3000/javascripts/choco_app/index.html
Notice that when the app is launched, the URL changes to : localhost:3000/javascripts/choco_app/index.html#/main
#/main is a route in your Choco app (thanks to Sammy), it is defined in your ApplicationController.
this.get('#/main', function(cx) {
}); You have to include this # in every HTML link you add into your views.
List all the postsAdd a new post...
Project structure
A Choco project has the following structure :
Jimfile
This file list all the dependencies for your project (libraries & local files).
app
It
contains four sub-folders : controllers, helpers, models & views.
This is where you will spend most of your development time.
compressed
This
is where the bundled.js file is created, it bundles all your JS files
in one single file. It is highly recommended to compress this file
before going live (rake choco:deploy).
images
Store all the images used by your application in this folder.
index.html
This
is the file you have to open in your browser to launch your Choco
application. It includes your bundled.js file, your stylesheets and
defines the layout of your application.
The #choco div is very
important, this is where the HTML generated by your views will be
inserted. If you change his name, you must configure it into the
app/controllers/application_controller.js as well.
lib
Use
this folder to store your JS files which are specific to your project
but don’t have their place in the app folder. If this is a library that
can be used by other projects, you should use Jim instead.
script
This folder contains the choco script file. It brings you a few generators (model, controller, layout, scaffold, json, plugin).
spec
Test your application using Behavior Driven Development (BDD).
stylesheets
Store all the stylesheets used by your application in this folder.
A first resource (CRUD)
First of all, don’t forget to start the choco watcher ($ choco –watch) if you don’t want to update your Jimfile manually.
The
easiest way to get started is to generate a scaffold based on JSON. Use
your server side technology to create a web service that returns JSON
representing your resource.
For example, with Rails :
def index
render :json => Post.all
end
Once you have that, you can generate your scaffold very easily :
$ choco generate scaffold post localhost:3000/posts
This will create the PostsController with all the actions, the views and the model.
Notice that the Choco watcher automatically updated your Jimfile and your bundled.js.
It also updated your ApplicationController by adding the following line :
PostsController(this);
You can now call this new page with the following URL : localhost:3000/javascripts/choco_app/index.html#/posts
This
will send a GET request to the #/posts URL of your application. This
request will be handled by your PostsController and more precisely by
this action :
get('#/posts', function(cx) {
cx.posts = Post.all();
});
We
are using our model to get all the posts (locally) and store them in
the posts variable. Using cx will make this variable available in your
view.
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). In our case
app/views/posts/index.template will be rendered.
This is a simple HTML page with some Javascript tags.
We are iterating on our posts array to create a table row for each of them.
You will not see any post yet because you haven’t loaded the post from your server (JSON).
To do that, just update your ApplicationController by adding your Post model in the models array :
var models = [Post];
ChocoUtils.loadModels(models, function() {
app.run(‘#/main’);
});
All
your models will be loaded by calling the load() method on their class.
This action will send Ajax requests to your server. The Choco
application will then be launched when all the responses have been
received and treated.
To create, remove & update posts, you
have to create your REST controller on the server side. Have a look at
the sample demo for an example (github.com/ahe/choco_demo).
You
can also use fixtures instead. Fixtures are located in the /fixtures
folder, they use the jquery.mockjax plugin to mock Ajax requests and
return the JSON you defined in your fixtures.
Use the choco
generate fixture command to easily create your fixtures (e.g : $ choco
generate fixture post, will mock requests sent to the /posts URL).
Generators
The following code generators are available :
$ choco generate controller
$ choco generate model
$ choco generate scaffold [field1 field2 …]
$ choco generate scaffold
$ choco generate fixture
$ choco generate layout
$ choco generate plugin
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.
Controllers
To learn more about controllers, please read Sammy documentation : code.quirkey.com/sammy
You
may be wondering about the best solution to execute Javascript code
after rendering a template. 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 :
Hey, click me, I'm a simple test!I want to open a Javascript alert when it is clicked.
I can simply update my controller like this :
get('#/posts', function(cx) {
cx.posts = Post.all();
cx.render({ template: 'posts/index', event: 'posts_loaded', data: { size: cx.posts.length }});
});
bind('posts_loaded', function(e, data) {
$('#test_link').click(function() {
alert('Hey! We have ' + data['size'] + ' posts!');
return false;
});
});
I
call the render() method explicitly because I want to trigger an event
when the template is rendered. This event is named ‘posts_loaded’ and
when it is executed it simply add a Javascript behavior to my link.
The
render method supports various options like like layouts, events &
more. You can read the doc here :
github.com/ahe/choco.libs/blob/master/plugins/sammy/choco.plugins.sammy.smart_renderer.js
Views
By default, Choco uses simple template views where you can combine HTML and Javascript.
You can easily display values in your views :
<%= post.attr('title') %>
Or call helpers you defined :
<% myHelper(); %> // Don't forget the ;
You can also of course use conditions, iterators & more.
You
can easily switch to HAML or Mustache by configuring it in your
application controller. Have a look at Sammy documentation for more
information
Models
For more information about models, please read js-model documentation : github.com/benpickles/js-model
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. Have a look at the demo for an example :
github.com/ahe/choco_demo
js-model expects JSON without the ROOT element included. In Rails that means you have to disable this option :
ActiveRecord::Base.include_root_in_json = false
Logger
You can call the logger from anywhere in your application by simply calling :
app.logger('hello choco!');
Plugins
Models, views & controllers can easily be extended using plugins.
You can generate a new plugin using the following command :
$ choco generate plugin
Existing plugins & Choco libs are stored here : github.com/ahe/choco.libs
Deploy
When you deploy your application on live, don’t forget to compress your files :
$ rake choco:deploy
Then just copy the required files on your web server.
BDD
BDD
is currently being implemented, it will be soon very easy to test all
the parts of your Choco apps. A first solution can be found here :
github.com/ahe/sammy_demo/tree/master/test/javascript
Mailing list
groups.google.com/group/choco-js
Note on Patches/Pull Requests
Fork the project.
Make your feature addition or bug fix.
Add tests for it. This is important so I don’t break it in a future version unintentionally.
Commit, do not mess with rakefile, version, or history. (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)
Send me a pull request. Bonus points for topic branches.
Copyright
Copyright © 2010 Anthony Heukmes. See LICENSE for details.
2dconcept.com
intotheweb.be
twitter.com/2dc
twitter.com/intotheweb