Browse files

Turn Serenade for Rails into Serenade for Ruby

- Allows usage with Ruby on Rails asset pipeline (serenade/rails)
- Allows usage with Sprockets-based apps e.g. sinatra, middleman (serenade/sprockets)
- Allows usage of the Serenade renderer from any Ruby library
  • Loading branch information...
1 parent 221deeb commit 6fa421be468e9abf7eb2576e94a1a7a09b33383f @Burgestrand Burgestrand committed Oct 4, 2012
View
2 .rspec
@@ -0,0 +1,2 @@
+-fp
+--colour
View
3 Gemfile
@@ -1,4 +1,3 @@
-source 'http://rubygems.org'
+source "https://rubygems.org"
-# Specify your gem's dependencies in serenade_rails.gemspec
gemspec
View
80 README.md
@@ -1,54 +1,83 @@
-# Serenade.js for Ruby on Rails
+# Serenade.js for Ruby
-[Serenade.js] is a JavaScript client side MVC framework. This gem makes it
-easy to use Serenade.js with the Ruby on Rails Asset Pipeline in Rails
-3.1 and later.
+[Serenade.js] is a JavaScript client side MVC framework. This gem makes Serenade.js
+available for usage with [Sprockets], or the asset pipeline in Ruby on Rails version
+3.1 or later.
-Add it to the assets group in your Gemfile:
+[serenade.js]: https://github.com/elabs/serenade.js
+[sprockets]: http://rubygems.org/gems/sprockets
+
+## Installation
+
+To use Serenade with Rails, add Serenade to the assets group in your Gemfile:
-``` ruby
+```
group :assets do
- gem 'serenade_rails'
+ gem "serenade", :require => "serenade/rails"
end
```
-You can now require Serenade in your `application.js` file, or wherever
-you prefer:
+You can now require Serenade in your `app/assets/javascripts/application.js` file:
-``` javascript
+```
//= require serenade
```
-Serenade should now be loaded and ready. See the [Serenade README][readme] for
-examples.
+Serenade should now be loaded and ready. See the [Serenade README] for examples.
+
+[Serenade README]: https://github.com/elabs/serenade.js/blob/master/README.md
-## Views
+### Using Serenade with Sprockets
-You can also easily use views from the asset pipeline. Just use the extension
-`.serenade` on your views, for example, place something like this in
-`app/assets/javascripts/test.serenade`:
+If you are not using Rails, you can still use Serenade with just Sprockets:
```
-h1 "Hello world"
+gem "serenade", :require => "serenade/sprockets"
+```
+
+You’ll also need to register the Serenade asset path with your Sprockets environment.
+
+```
+sprockets.append_path Serenade::ASSET_PATH
+```
+
+## Serenade.js views and the asset pipeline
+
+Serenade.js allows Sprockets or the Rails asset pipeline to compile your Serenade
+views for you, just use the extension `.serenade` on any asset file. Your views
+will be precompiled server-side before being served to the client.
+
+For example, if you create the following view in `app/assets/javascripts/test.serenade`:
+
+```
+h1 "Hello " @name
```
Now you can render this view:
-``` javascript
-document.appendChild(Serenade.render('test'));
+```
+var model = new Serenade.Model({ name: "Vega" })
+document.body.appendChild(Serenade.render('test', model));
```
-Couldn't be simpler!
+And, like in all Serenade.js views, you can change your model and see the DOM
+update itself accordingly:
-If the path to your view starts with `views`, that initial part is stripped
-off, so you could have placed the above view in
-`app/assets/javascripts/views/test.serenade` without changing the code.
+```
+model.name = "Mercedes" // HTML now says <h1>Hello Mercedes</h1>
+```
+
+### A note about the view path
+
+If the path to your view starts with `views`, that initial part is stripped off,
+so you could have placed the above view in `app/assets/javascripts/views/test.serenade`
+without changing the code.
## License
(The MIT License)
-Copyright (c) 2012 Jonas Nicklas
+Copyright (c) 2012 Jonas Nicklas, Kim Burgestrand
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -68,6 +97,3 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-[readme]: https://github.com/elabs/serenade.js/blob/master/README.md
-[serenade.js]: https://github.com/elabs/serenade.js
View
14 Rakefile
@@ -1,2 +1,12 @@
-#!/usr/bin/env rake
-require "bundler/gem_tasks"
+begin
+ require "bundler/gem_tasks"
+rescue LoadError
+ # Only gem pushers need bundler tasks.
+end
+
+require "rspec/core/rake_task"
+RSpec::Core::RakeTask.new("spec") do |task|
+ task.ruby_opts = "-W2"
+end
+
+task :default => :spec
View
0 lib/assets/javascripts/serenade.js → assets/javascripts/serenade.js
File renamed without changes.
View
2 lib/serenade.rb
@@ -0,0 +1,2 @@
+require "serenade/version"
+require "serenade/renderer"
View
7 lib/serenade/rails.rb
@@ -0,0 +1,7 @@
+require "serenade/sprockets"
+require "rails/engine"
+
+module Serenade
+ class Engine < ::Rails::Engine
+ end
+end
View
26 lib/serenade/renderer.rb
@@ -0,0 +1,26 @@
+require "execjs"
+require "multi_json"
+
+module Serenade
+ ASSET_PATH = File.expand_path("../../assets/javascripts", File.dirname(__FILE__))
+ SERENADEJS_PATH = File.join(ASSET_PATH, "serenade.js")
+
+ class Renderer
+ attr_reader :name, :content
+
+ def initialize(name, content)
+ @name = name
+ @content = content
+ end
+
+ def parse
+ context = ExecJS.compile(File.read(SERENADEJS_PATH))
+ code = "Serenade.view(#{MultiJson.dump(content)}).parse()"
+ context.eval(code)
+ end
+
+ def render
+ "Serenade.view(#{MultiJson.dump(name)}, #{MultiJson.dump(parse)});"
+ end
+ end
+end
View
4 lib/serenade/sprockets.rb
@@ -0,0 +1,4 @@
+require "serenade/template"
+require "sprockets"
+
+Sprockets.register_engine(".serenade", Serenade::Template)
View
18 lib/serenade/template.rb
@@ -0,0 +1,18 @@
+require "serenade"
+require "tilt"
+
+module Serenade
+ class Template < Tilt::Template
+ def self.default_mime_type
+ "application/javascript"
+ end
+
+ def prepare
+ end
+
+ def evaluate(scope, locals, &block)
+ name = scope.logical_path.gsub(/^views\//, "")
+ Serenade::Renderer.new(name, data.dup).render
+ end
+ end
+end
View
3 lib/serenade/version.rb
@@ -0,0 +1,3 @@
+module Serenade
+ VERSION = "0.1.0"
+end
View
7 lib/serenade_rails.rb
@@ -1,7 +0,0 @@
-require 'serenade_rails/version'
-require 'serenade_rails/processor'
-require 'serenade_rails/engine'
-require 'serenade_rails/template'
-
-module SerenadeRails
-end
View
4 lib/serenade_rails/engine.rb
@@ -1,4 +0,0 @@
-module SerenadeRails
- class Engine < ::Rails::Engine
- end
-end
View
21 lib/serenade_rails/processor.rb
@@ -1,21 +0,0 @@
-require 'sprockets'
-require 'sprockets/engines'
-require 'tilt'
-
-module SerenadeRails
- class Processor < Tilt::Template
- def self.default_mime_type
- 'application/javascript'
- end
-
- def prepare
- end
-
- def evaluate(scope, locals, &block)
- name = scope.logical_path.gsub(/^views\//, "")
- SerenadeRails::Template.new(name, data.dup).render
- end
- end
-end
-
-Sprockets.register_engine '.serenade', SerenadeRails::Processor
View
25 lib/serenade_rails/template.rb
@@ -1,25 +0,0 @@
-require 'execjs'
-require 'active_support/json'
-
-module SerenadeRails
- SERENADE_PATH = File.expand_path('../assets/javascripts/serenade.js', File.dirname(__FILE__))
-
- class Template
- attr_reader :name, :content
-
- def initialize(name, content)
- @name = name
- @content = content
- end
-
- def parse
- context = ExecJS.compile(File.read(SERENADE_PATH))
- code = "Serenade.view(#{content.to_json}).parse()"
- context.eval(code)
- end
-
- def render
- "Serenade.view(#{name.to_json}, #{parse.to_json});"
- end
- end
-end
View
3 lib/serenade_rails/version.rb
@@ -1,3 +0,0 @@
-module SerenadeRails
- VERSION = "0.2.1"
-end
View
27 serenade.gemspec
@@ -0,0 +1,27 @@
+# -*- encoding: utf-8 -*-
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require "serenade/version"
+
+Gem::Specification.new do |gem|
+ gem.name = "serenade"
+ gem.version = Serenade::VERSION
+
+ gem.authors = ["Jonas Nicklas", "Kim Burgestrand"]
+ gem.email = ["jnicklas@gmail.com", "kim@burgestrand.se"]
+ gem.license = "MIT License"
+
+ gem.summary = "Serenade.js for Ruby, Rails, and Sprockets"
+ gem.homepage = "https://github.com/elabs/serenade"
+ gem.description = <<-TEXT
+- Use serenade.js with the Rails asset pipeline.
+- Use serenade.js with any sprockets application (middlemanapp, sinatra).
+- Prerender serenade.js views server-side, before it even reaches the client.
+TEXT
+
+ gem.add_dependency "execjs", ">= 0.3.0"
+ gem.add_dependency "multi_json"
+ gem.add_development_dependency "rspec", "~> 2.0"
+ gem.add_development_dependency "sprockets", "~> 2.0"
+ gem.add_development_dependency "rails", "~> 3.1"
+end
View
21 serenade_rails.gemspec
@@ -1,21 +0,0 @@
-# -*- encoding: utf-8 -*-
-require File.expand_path('../lib/serenade_rails/version', __FILE__)
-
-Gem::Specification.new do |gem|
- gem.authors = ["Jonas Nicklas"]
- gem.email = ["jonas.nicklas@gmail.com"]
- gem.description = %q{Use Serenade.js within the Rails asset pipeline}
- gem.summary = %q{Serenade.js for Rails}
- gem.homepage = ""
-
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
- gem.files = `git ls-files`.split("\n")
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
- gem.name = "serenade_rails"
- gem.require_paths = ["lib"]
- gem.version = SerenadeRails::VERSION
-
- gem.add_dependency "rails", "~> 3.1"
- gem.add_dependency "execjs", ">= 0.3.0"
- gem.add_development_dependency "rspec", "~> 2.0"
-end
View
16 spec/serenade_spec.rb
@@ -0,0 +1,16 @@
+require "serenade"
+
+describe Serenade do
+ specify { defined?(Serenade::VERSION).should_not be_nil }
+
+ describe Serenade::Renderer do
+ describe "#parse" do
+ it "returns a parsed Sereande template" do
+ result = Serenade::Renderer.new("foo", 'h1 "Hello world"').parse
+ result["name"].should eq "h1"
+ result["children"][0]["type"].should eq "text"
+ result["children"][0]["value"].should eq "Hello world"
+ end
+ end
+ end
+end
View
14 spec/sprockets_spec.rb
@@ -0,0 +1,14 @@
+require "serenade/sprockets"
+
+describe "Serenade sprockets integration" do
+ it "registers the .serenade template engine" do
+ Sprockets.engines[".serenade"].should eq Serenade::Template
+ end
+
+ it "allows you to require serenade in your assets" do
+ env = Sprockets::Environment.new
+ env.append_path Serenade::ASSET_PATH
+
+ File.exists?(env.resolve "serenade").should be_true
+ end
+end
View
12 spec/template_spec.rb
@@ -1,12 +0,0 @@
-require "serenade_rails/template"
-
-describe SerenadeRails::Template do
- describe "#parse" do
- it "returns a parsed Sereande template" do
- result = SerenadeRails::Template.new("foo", 'h1 "Hello world"').parse
- result["name"].should == "h1"
- result["children"][0]["type"].should == "text"
- result["children"][0]["value"].should == "Hello world"
- end
- end
-end

0 comments on commit 6fa421b

Please sign in to comment.