Sinatra (Cl|S)assy Web Development Corey Donohoe(
[email protected])
Thursday, May 14, 2009
Corey Donohoe
[email protected] / http://atmos.org
Thursday, May 14, 2009
Open Source Participant
Thursday, May 14, 2009
2001
Thursday, May 14, 2009
Writing Rails since 2004
Thursday, May 14, 2009
Engine Yard in March 2007
Thursday, May 14, 2009
ran support for a while
Thursday, May 14, 2009
“integration” team
Thursday, May 14, 2009
It’s Take Your Breath Away Awesome Thursday, May 14, 2009
http://github.com/sinatra Thursday, May 14, 2009
Micro Framework
Thursday, May 14, 2009
powered by rack
Thursday, May 14, 2009
history
Thursday, May 14, 2009
advances
Thursday, May 14, 2009
fulfilling
Thursday, May 14, 2009
Classic Applications get(‘/’) { “Hello World” }
Thursday, May 14, 2009
http://sinatrarb.com Thursday, May 14, 2009
require 'rubygems' require 'sinatra' helpers do def greeting haml :greeting end end template :greeting do "%h2 Hello World" end get('/') do greeting end
Hello World Thursday, May 14, 2009
throw that in a file
Thursday, May 14, 2009
run it
Thursday, May 14, 2009
Where’s my config file?
Thursday, May 14, 2009
where’s my database.yml
Thursday, May 14, 2009
There isn’t one(there isn’t even a db)
Thursday, May 14, 2009
Wonderful for One Offs
Thursday, May 14, 2009
HTTP Verbs
Thursday, May 14, 2009
["/foo", "/bar", "/baz"].each do |path| get path do "You've reached me at #{request.path_info}" end end
Thursday, May 14, 2009
Block Syntax
Thursday, May 14, 2009
get '/hello/:name' do |n| "Hello #{n}!" end
Thursday, May 14, 2009
params hash
Thursday, May 14, 2009
templates
Thursday, May 14, 2009
template :foo do <<-HAML %h2 Greetings %p Lorem Ipsum HAML end
Thursday, May 14, 2009
set :views, ‘views’
Thursday, May 14, 2009
views/foo.haml
Thursday, May 14, 2009
helpers do; end
Thursday, May 14, 2009
helpers do include Rack::Utils alias_method :h, :escape_html def localhost(suffix) port_part = case request.scheme when "http" request.port == 80 ? "" : ":#{request.port}" when "https" request.port == 443 ? "" : ":#{request.port}" end "#{request.scheme}://#{request.host}#{port_part}#{suffix}" end end
Thursday, May 14, 2009
Configuration Options
Thursday, May 14, 2009
enable :sessions
Thursday, May 14, 2009
set :public, ‘public’
Thursday, May 14, 2009
set :foo, 'bar' set :baz, Proc.new { "Hello " + foo } get '/baz' do "baz is set to " + options.baz end
Thursday, May 14, 2009
enable/disable
Thursday, May 14, 2009
Check the FAQ
Thursday, May 14, 2009
Modular Style class MyApp < Sinatra::Default; end
Thursday, May 14, 2009
remove global scope
Thursday, May 14, 2009
instances
Thursday, May 14, 2009
reusable instances
Thursday, May 14, 2009
module Hancock class ConfigurationError < StandardError; end class App < Sinatra::Default enable :sessions set :sreg_params, [:email, :first_name, :last_name, :internal] set :provider_name, 'Hancock SSO Provider!' set :do_not_reply, nil register register register register end end
Thursday, May 14, 2009
Sinatra::Hancock::Defaults Sinatra::Hancock::Sessions Sinatra::Hancock::Users Sinatra::Hancock::OpenIDServer
global scope moved inside my class
Thursday, May 14, 2009
as class methods
Thursday, May 14, 2009
pretty much works the same
Thursday, May 14, 2009
register class method nice modular pieces of sinatra apps
Thursday, May 14, 2009
module Sinatra module Hancock module Sessions def self.sessions_template(file) template = File.expand_path(File.dirname(__FILE__)+'/views/sessions') File.read("#{template}/#{file}.haml") end module Helpers def session_user session['user_id'].nil? ? nil : ::Hancock::User.get(session['user_id']) end end def self.registered(app) app.helpers(Sinatra::Hancock::Sessions::Helpers) app.template(:unauthenticated) { sessions_template ('unauthenticated') } app.get '/sso/login' do ensure_authenticated end app.post '/sso/login' do @user = ::Hancock::User.authenticate(params['email'], params['password']) if @user session['user_id'] = @user.id end ensure_authenticated redirect session['return_to'] || '/' end app.get '/sso/logout' do session.clear redirect '/' end end end end end
Thursday, May 14, 2009
Sinatra::Hancock::Sessions
Thursday, May 14, 2009
lib/sinatra/hancock/sessions.rb
Thursday, May 14, 2009
Thursday, May 14, 2009
auto register by requiring
Thursday, May 14, 2009
no one is really using this
Thursday, May 14, 2009
module Hancock class ConfigurationError < StandardError; end class App < Sinatra::Default enable :sessions set :sreg_params, [:email, :first_name, :last_name, :internal] set :provider_name, 'Hancock SSO Provider!' set :do_not_reply, nil register register register register end end
Sinatra::Hancock::Defaults Sinatra::Hancock::Sessions Sinatra::Hancock::Users Sinatra::Hancock::OpenIDServer
OMG LOOK WHAT I MADE! you can share it with your buddies
Thursday, May 14, 2009
be responsible
Thursday, May 14, 2009
under the hood yo dawg, i heard you were into rack
Thursday, May 14, 2009
http://github.com/chneukirchen/rack Thursday, May 14, 2009
bacon
Thursday, May 14, 2009
i don’t use it
Thursday, May 14, 2009
made up the tumblelog
Thursday, May 14, 2009
rackup
Thursday, May 14, 2009
specifies the app to run
Thursday, May 14, 2009
configurable stuff, ports, hostnames etc
Thursday, May 14, 2009
middleware to run also
Thursday, May 14, 2009
use
Thursday, May 14, 2009
specific middleware
Thursday, May 14, 2009
initialize method
Thursday, May 14, 2009
block syntax
Thursday, May 14, 2009
#!/usr/bin/env rackup use EySso do |sso| sso.only_staff! end # vim:filetype=ruby
Thursday, May 14, 2009
use in Sinatra
Thursday, May 14, 2009
initialize arity
Thursday, May 14, 2009
first parameter is the app
Thursday, May 14, 2009
it’s implied
Thursday, May 14, 2009
use Rack::HoptoadNotifier,‘10c4cc2f6aa6b9e1104a921c5fdae4b0846d4475’
Thursday, May 14, 2009
Rack::HoptoadNotifier.new(app,‘10c4cc2f6aa6b9e1104a921c5fdae4b0846d4475’)
Thursday, May 14, 2009
initialize w/ a block
Thursday, May 14, 2009
use in Rails
Thursday, May 14, 2009
config.middleware.use
Thursday, May 14, 2009
it’s a string
Thursday, May 14, 2009
script/generate metal
Thursday, May 14, 2009
works with Sinatra::Default
Thursday, May 14, 2009
just inherit from them
Thursday, May 14, 2009
use in merb
Thursday, May 14, 2009
no rack.session
Thursday, May 14, 2009
config/rack.rb
Thursday, May 14, 2009
who still writes merb apps?
Thursday, May 14, 2009
use in ramaze
Thursday, May 14, 2009
no rack.session
Thursday, May 14, 2009
not becoming rails
Thursday, May 14, 2009
map
Thursday, May 14, 2009
russian doll
Thursday, May 14, 2009
#!/usr/bin/env rackup require File.dirname(__FILE__) + '/lib/setup' require 'gateway/app' require 'migration/app' use Rack::Static, :urls => ["/css", "/img", "/js"], :root => "public" map "/gateway/" do use EySso run Gateway::App end map "/migration/" do use Rack::ShowExceptions if ENV["RACK_ENV"] == "production" use EySso do |sso| sso.only_staff! end end run Migration::App end map "/" do app = lambda do |env| [404, {"Content-Type" => "text/plain", "Content-Length" => "9"}, ["Not found"]] end run app end
Thursday, May 14, 2009
with a url helper hack
Thursday, May 14, 2009
helpers do def url(path) request.script_name + path end end
Thursday, May 14, 2009
#!/usr/bin/env rackup require File.dirname(__FILE__) + '/lib/setup' require 'gateway/app' require 'migration/app' use Rack::Static, :urls => ["/css", "/img", "/js"], :root => "public" map "/gateway/" do use EySso run Gateway::App end map "/migration/" do use Rack::ShowExceptions if ENV["RACK_ENV"] == "production" use EySso do |sso| sso.only_staff! end end run Migration::App end map "/" do app = lambda do |env| [404, {"Content-Type" => "text/plain", "Content-Length" => "9"}, ["Not found"]] end run app end
Thursday, May 14, 2009
every day kinda stuff
Thursday, May 14, 2009
so back to sinatra
Thursday, May 14, 2009
Sinatra::Base
Thursday, May 14, 2009
this is middleware
Thursday, May 14, 2009
you should really read the docs
Thursday, May 14, 2009
straight rack, no sinatra
Thursday, May 14, 2009
major frameworks integrate ok
Thursday, May 14, 2009
Sinatra::Default
Thursday, May 14, 2009
this is a sinatra application
Thursday, May 14, 2009
these are FUN
Thursday, May 14, 2009
your rackup files invoke these
Thursday, May 14, 2009
so you got all that, right?
Thursday, May 14, 2009
Deployment Thursday, May 14, 2009
easy
Thursday, May 14, 2009
Passenger Thursday, May 14, 2009
nginx
Thursday, May 14, 2009
nginx config http { ... server { listen 80; server_name hancock.atmos.org root /data/hancock; passenger_enabled on; # <--- These lines passenger_base_uri /hancock; # <--- added. } ... }
Thursday, May 14, 2009
apache
Thursday, May 14, 2009
Apache 2 Vhost Config
ServerName hancock.atmos.org DocumentRoot /data/hancock/current/public RackEnv 'production' Options FollowSymLinks AllowOverride None Order allow,deny Allow from all
Thursday, May 14, 2009
script/
Thursday, May 14, 2009
script/console #!/usr/bin/env ruby require "irb" require 'rubygems' require 'twitrsvp' DataMapper.setup(:default, "mysql://atmos:s3cr3t@localhost/twitrsvp_production") ENV['TWIT_RSVP_READKEY'] = '4the' ENV['TWIT_RSVP_READSECRET'] = 'lulz' include ::TwitRSVP if __FILE__ == $0 IRB.start(__FILE__) else # check -e option if /^-e$/ =~ $0 IRB.start(__FILE__) else IRB.setup(__FILE__) end end
Thursday, May 14, 2009
crons, whatever
Thursday, May 14, 2009
gnu screen
Thursday, May 14, 2009
Testing Fleshing things out
Thursday, May 14, 2009
i’m a huge fan
Thursday, May 14, 2009
TATFT
Thursday, May 14, 2009
acceptance testing
Thursday, May 14, 2009
TDD as a design tool
Thursday, May 14, 2009
Sinatra::Test
Thursday, May 14, 2009
is Deprecated
Thursday, May 14, 2009
Sticky Sessions Inside Your Tests
Thursday, May 14, 2009
rack-test http://github.com/brynary/rack-test/tree/master
Thursday, May 14, 2009
require "rack/test" class HomepageTest < Test::Unit::TestCase include Rack::Test::Methods def app MyApp.new end def test_redirect_logged_in_users_to_dashboard authorize "bryan", "secret" get "/" follow_redirect! assert_equal "http://example.org/redirected", last_request.url assert last_response.ok? end end
Thursday, May 14, 2009
Webrat Matchers
Thursday, May 14, 2009
What You Should Be Doing
Thursday, May 14, 2009
Webrat http://github.com/brynary/webrat
Thursday, May 14, 2009
have_selector
Thursday, May 14, 2009
have_selector("#zendesk_organization_2 .name:contains('Zondervan’)”)
Thursday, May 14, 2009
Cucumber http://github.com/aslakhellesoy/cucumber/tree/master
Thursday, May 14, 2009
Combination of the previous two
Thursday, May 14, 2009
rack-test verbs instead of visit
Thursday, May 14, 2009
webrat selectors for validations
Thursday, May 14, 2009
drive browsers
Thursday, May 14, 2009
safariwatir and selenium-rc
Thursday, May 14, 2009
acceptance testing is wonderful
Thursday, May 14, 2009
reflection Thursday, May 14, 2009
simple
Thursday, May 14, 2009
reusable
Thursday, May 14, 2009
nice performance
Thursday, May 14, 2009
not fighting my framework
Thursday, May 14, 2009
leverage all the ruby libs
Thursday, May 14, 2009
develop like a pro
Thursday, May 14, 2009
not overwhelmed with choices
Thursday, May 14, 2009
future is known
Thursday, May 14, 2009
merb
Thursday, May 14, 2009
rails 3
Thursday, May 14, 2009
think UNIX
Thursday, May 14, 2009
FUN
Thursday, May 14, 2009
creative juices flowing
Thursday, May 14, 2009
hack out something fun
Thursday, May 14, 2009
solve something annoying
Thursday, May 14, 2009
That’s it! :D ✤
http://github.com/sinatra/sinatra
✤
http://github.com/chneukirchen/rack
✤
http://github.com/atmos/hancock
✤
http://github.com/atmos/hancock-client
✤
http://github.com/atmos/hancock-client-rails
✤
http://github.com/brynary/rack-bug
✤
http://github.com/foca/integrity
Thursday, May 14, 2009
Hancock Thursday, May 14, 2009
Like Your John Hancock
Thursday, May 14, 2009
Single Sign On
Thursday, May 14, 2009
gem 'hancock', '~>0.0.1' require 'hancock' DataMapper.setup(:default, "sqlite3:///#{Dir.pwd}/development.db") Hancock::App.set :views, 'views' Hancock::App.set :public, 'public' Hancock::App.set :environment, :production Hancock::App.set :provider_name, 'Example SSO Provider' Hancock::App.set :do_not_reply, '
[email protected]' Sinatra::Mailer.config = { :host => 'smtp.example.com', :port => '25', :user => 'sso', :pass => 'lolerskates', :auth => :plain # :plain, :login, :cram_md5, the default is no auth :domain => "example.com" # the HELO domain provided by the client to the server } run Hancock::App
config.ru Thursday, May 14, 2009
Example
Thursday, May 14, 2009
Hancock-Client Thursday, May 14, 2009
Sinatra App
Thursday, May 14, 2009
Rack App
Thursday, May 14, 2009
Hancock-Client-Rails
Thursday, May 14, 2009
metal
Thursday, May 14, 2009
\m/
Thursday, May 14, 2009
Rails 2.3.x
Thursday, May 14, 2009
config/environment.rb require File.join(File.dirname(__FILE__), 'boot') require 'hancock' Rails::Initializer.run do |config| config.gem 'hancock', :lib => 'hancock' config.middleware.use 'Hancock::Client' # all your other normal stuff end
Thursday, May 14, 2009