Skip to content

Commit

Permalink
Docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
rstacruz committed Sep 11, 2011
1 parent addcf5f commit 9240cd0
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 230 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.db
/db
/doc
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ Done

### Heroku setup log

It was set up like this:

heroku create tinkerbin --stack bamboo-mri-1.9.2
heroku addons:add custom_domains
heroku domains:add tinkerbin.com
heroku config:add ANALYTICS_ID=UA-25603016-1
git push heroku master

DNS records: ([reference](http://devcenter.heroku.com/articles/custom-domains)
DNS records: ([reference](http://devcenter.heroku.com/articles/custom-domains))

@ A 75.101.163.44
@ A 75.101.145.87
Expand Down
40 changes: 3 additions & 37 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,8 @@ extend LogHelpers
Dir['./lib/tasks/**/*.rake'].each { |f| load f }
task :default => :help

# You may want to remove this crap, these have no use in production.

desc "Starts the server [Development]"
task(:start) {
system "ruby init.rb"
}

desc "Opens a console session [Development]"
task(:irb) {
irb = ENV['IRB_PATH'] || 'irb'
system "#{irb} -r./init.rb"
}

namespace :example do
desc "Lists available recipes [Examples]"
task :list do
puts "Available recipes:"
list = Dir['./**/*.example'].map { |f| File.basename(f).match(/([^\.]+)(.[^\.]+){2}$/) && $1 }.uniq
list.each { |item| puts " * rake recipes:load[#{item}]" }
end

desc "Clears all example files [Examples]"
task :clear do
Dir['./**/*.example'].each { |f| FileUtils.rm f }
end

desc "Loads a given recipe [Examples]"
task :load, :recipe do |t, args|
recipe = args[:recipe]
Dir["./**/*#{recipe}.*.example"].each { |from|
to = from.gsub(/(\.#{recipe})|(\.example)/, '')
puts "%40s -> %s" % [ from, to ]
FileUtils.mv from, to unless ENV['SIMULATE']
}
puts "Okay, now add the appropriate gems to your gemfile."
namespace :doc do
task :build do
system "reacco -a --api lib"
end
end

task :examples => :'example:list'
4 changes: 2 additions & 2 deletions app/init/js_css.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'sinatra/jstsupport'
require 'sinatra/jstpages'

class Main
register Sinatra::JstSupport
register Sinatra::JstPages
serve_jst '/js/jst.js'

register Sinatra::AssetPack
Expand Down
203 changes: 203 additions & 0 deletions lib/sinatra/jstpages.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
# ## Sinatra::JstPages [module]
# A Sinatra plugin that adds support for JST (JavaScript Server Templates).
#
# This serves all JST files found in `/views/**/*.jst.*` as `/jst.js`.
#
# #### Layout engines
# The extension of the file determines the layout engine to be used. For example,
# if you have `foo.jst.tpl`, it uses Underscore.js's `_.template` to work on it.
#
# #### Accessing in the browser
# First, you will need to link to the JST route in your page. Make a `<script>`
# tag where the `src='...'` attribute is the same path you provide to
# `serve_jst`.
#
# In the browser, you can use `JST['foo']` (which will be a function) to access it.
#
# require 'sinatra/jstpages'
# class App < Sinatra::Base
# register Sinatra::JstPages
# serve_jst '/jst.js'
# end
#
# #### Supported templates
# Currently supports the following templates:
#
# * [Jade][jade] (`.jst.jade`) -- Jade templates. This requires
# [jade.js][jade]. For older browsers, you will also need [json2.js][json2],
# and an implementation of [String.prototype.trim][trim].
#
# * [Underscore templates][under_tpl] (`.jst.tpl`) -- Simple templates by
# underscore. This requires [underscore.js][under], which Backbone also
# requires.
#
# * [Haml.js][haml] (`.jst.haml`) -- A JavaScript implementation of Haml.
# Requires [haml.js][haml].
#
# * [Eco][eco] (`.jst.eco`) -- Embedded CoffeeScript templates. Requires
# [eco.js][eco] and [coffee-script.js][cs].
#
# [jade]: http://github.com/visionmedia/jade
# [json2]: https://github.com/douglascrockford/JSON-js
# [trim]: http://snippets.dzone.com/posts/show/701
# [under_tpl]: http://documentcloud.github.com/underscore/#template
# [under]: http://documentcloud.github.com/underscore
# [haml]: https://github.com/creationix/haml-js
# [eco]: https://github.com/sstephenson/eco
# [cs]: http://coffeescript.org
#
# #### Basic example
# Say you have a JST view written in Jade, placed in `views/editor/edit.jst.jade`:
#
# # views/editor/edit.jst.jade
# h1= "Edit "+name
# form
# button Save
#
# And your app has JST files served in `/jst.js`:
#
# class App < Sinatra::Base
# register Sinatra::JstPages
# serve_jst '/jst.js'
# end
#
# Now in your layout, you will need to include it like so:
#
# <script type='text/javascript' src='/jst.js'></script>
# <!-- TIP: If you're using the sinatra-assetpack gem, just add `/jst.js` to a package. -->
#
# Now in your browser you may invoke `JST['templatename']`:
#
# // Renders the editor/edit template
# JST['editor/edit']();
#
# // Renders the editor/edit template with template parameters
# JST['editor/edit']({name: 'Item Name'});
#
# #### Adding more engines
# You can add more engines by subclassing `Sinatra::JstPages::Engine` to define
# how files should be precompiled (in the server) and compiled (in the
# browser). Then, use `register 'extension', EngineClass`.
#
module Sinatra
module JstPages
def self.registered(app)
app.extend ClassMethods
app.helpers Helpers
end

# Returns a hash to determine which engine is mapped onto a given extension.
def self.mappings
@mappings ||= Hash.new
end

def self.register(ext, engine)
mappings[ext] = engine
end

module Helpers
# Returns a list of JST files.
def jst_files
# Tuples of [ name, Engine instance ]
tuples = Dir.chdir(Main.views) {
Dir["**/*.jst.*"].map { |fn|
fn =~ %r{^(.*)\.jst\.([^\.]+)$}
name, ext = $1, $2
engine = JstPages.mappings[ext]

[ name, engine.new(File.join(Main.views, fn)) ] if engine
}.compact
}

Hash[*tuples.flatten]
end
end

module ClassMethods
# ### serve_jst(path, [options]) [class method]
# Serves JST files in given `path`.
#
def serve_jst(path, options={})
get path do
content_type :js
jsts = jst_files.map { |(name, engine)|
contents = engine.precompile
fn = engine.function

%{
JST[#{name.inspect}] = function() {
if (!c[#{name.inspect}]) c[#{name.inspect}] = (#{fn % [contents]});
return c[#{name.inspect}].apply(this, arguments);
};
}.strip.gsub(/^ {12}/, '')
}

%{
(function(){
var c = {};
if (!window.JST) window.JST = {};
#{jsts.join("\n ")}
})();
}.strip.gsub(/^ {12}/, '')
end
end
end
end
end


# ## Sinatra::JstPages::Engine [class]
# A template engine.
#
# #### Adding support for new template engines
# You will need to subclass `Engine`, override at least the `function` method,
# then use `JstPages.register`.
#
# This example will register `.jst.my` files to a new engine that uses
# `My.compile`.
#
# class MyEngine < Engine
# def function() "My.compile(%s)"; end
# end
#
# JstPages.register 'my', MyEngine
#
module Sinatra
module JstPages
class Engine
attr_reader :file
def initialize(file) @file = file; end
def contents() File.read(@file); end

# The pre-processing that happens before sending it to the compiled
# JST file. Override me if needed.
def precompile
contents.inspect
end

# The JavaScript function to invoke on the precompile'd object.
def function
"_.template(%s)"
end
end

class HamlEngine < Engine
def function() "Haml.compile(%s)"; end
end

class JadeEngine < Engine
def function() "require('jade').compile(%s)"; end
end

class EcoEngine < Engine
def function
"function() { var a = arguments.slice(); a.unshift(%s); return eco.compile.apply(eco, a); }"
end
end

register 'tpl', Engine
register 'jade', JadeEngine
register 'haml', HamlEngine
register 'eco', EcoEngine
end
end
Loading

0 comments on commit 9240cd0

Please sign in to comment.