54
Sinatra

Sinatra

Embed Size (px)

DESCRIPTION

Charla brindada en Locos x Rails en Buenos Aires, Argentina, el 4 de abril de 2009 sobre el framework web Sinatra.Breve descripción del framework y sus capacidades, una muy breve introducción a Rack y cómo funciona, y una muestra rápida de los Rails Metals, y de cómo integrar aplicaciones sinatra a nuestras aplicaciones en Rails.

Citation preview

Page 1: Sinatra

Sinatra

Page 2: Sinatra

Nicolás Sanguinetti

foca

http://entp.com

Page 3: Sinatra

¿Qué es?

Page 4: Sinatra

Un ejemplo

y lo guardamos como hello.rb

require "rubygems"require "sinatra"

get "/hello" do "<h1>Hello World</h1>"end

Page 5: Sinatra

Un ejemplo

$ gem install sinatra$ ruby hello.rb== Sinatra has taken the stage ...>> Listening on 0.0.0.0:4567

Page 6: Sinatra

Un ejemplo

Page 7: Sinatra

Features

Page 8: Sinatra

URLs Parametrizablesget "/hello/:name" do |name| # también con params[:name] "<h1>Hello #{name}</h1>"end

Page 9: Sinatra

Vistas

y en views/hello.erb

get "/hello/:name" do |name| @name = name erb :helloend

<h1>Hello <%= @name %></h1>

Page 10: Sinatra

Layoutsponemos en views/layout.erb

y todas nuestras vistas se renderean “adentro” de esta (reemplazando al yield)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"><head> <title>Hello <%= @name || "World" %></head><body> <%= yield %></body></html>

Page 11: Sinatra

HTTP

get "/..." do "..."end

post "/..." do "..."end

put "/..." do "..."end

delete "/..." do "..."end

Page 12: Sinatra

Pero PUT y DELETE...

<form action="/put/action" method="post"> <input type="hidden" name="_method" value="put"> ...</form>

Page 13: Sinatra

Blog en 15 minutos*

* para valores relativos de 15

Page 14: Sinatra

require "dm-core"require "do_sqlite3"load "lib/models.rb"

configure do DataMapper.setup(:default, "sqlite3:blog.db")end

(por ejemplo, DataMapper)

Usando un ORM con Sinatranecesitamos guardar los posts en algún lado, así que...

Page 15: Sinatra

class Post include DataMapper::Resource property :id, Serial property :title, String, :nullable => false property :permalink, String, :nullable => false property :body, Text, :nullable => false before :valid?, :set_permalink has n, :comments private def set_permalink self.permalink = title.gsub(/\s+/, "-") endend

class Comment include DataMapper::Resource property :id, Serial property :post_id, Integer, :nullable => false property :author, String, :nullable => false property :body, Text, :nullable => false belongs_to :postend

lib/models.rb

Page 16: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 17: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 18: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 19: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 20: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 21: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 22: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 23: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 24: Sinatra

get "/" doend

get "/new" doend

post "/" doend

get "/:permalink" do |permalink|end

post "/:permalink/comments" do |permalink|end

delete "/:permalink" do |permalink|end

get "/:permalink/edit" do |permalink|end

put "/:permalink" do |permalink|end

Qué queremos en el blog?

Page 25: Sinatra

get "/new" do @post = Post.new erb :newend

post "/" do @post = Post.new(params[:post])

if @post.save redirect "/#{@post.permalink}" else erb :new endend

Creemos un Post entonces

Page 26: Sinatra

<form method="post" action="/"> <div><label for="post_title">Title</label> <input type="text" name="post[title]" id="post_title" value="<%= @post.title %>"></div> <div><label for="post_body">Your Article</label> <textarea id="post_body" name="post[body]" rows="20" cols="40"><%= @post.body %></textarea> </div> <div><button type="submit">Post new article</button> or <a href="/#{@post.permalink}">go back</a>.</div></form>

views/new.erb

Page 27: Sinatra

get "/" do @posts = Post.all erb :indexend

Listando posts

Page 28: Sinatra

views/index.erb

<h2>All Posts</h2>

<ul id="posts"><% for post in @posts %> <li class="post"> <h2> <a href="/<%= post.permalink %>"> <%= post.title %> </a> </h2>

<%= post.body %> </li><% end %></ul>

Page 29: Sinatra

Un paréntesis: helpers!

helpers do def post_path(post) "/#{post.permalink}" endend

Page 30: Sinatra

get "/:permalink" do |permalink| @post = Post.first(:permalink => permalink) erb :showend

Mostrando un post

Page 31: Sinatra

views/show.erb

<h2> <a href="<%= post_path(@post) %>"> <%= @post.title %> </a></h2>

<%= @post.body %>

<div><a href="/">Go back to the list</a></div>

Page 32: Sinatra

Parentesis: “partials”views/post.erb

views/post.erb<%= erb(:post, :layout => false, :locals => { :post => @post }) %><div><a href="/">Go back to the list</a></div>

<h2> <a href="<%= post_path(post) %>"> <%= post.title %> </a></h2>

<%= post.body %>

Page 33: Sinatra

Comentariosget "/:permalink" do |permalink| @post = Post.first(:permalink => permalink) @comment = Comment.new erb :showend

post "/:permalink/comments" do |permalink| @post = Post.first(:permalink => permalink) @comment = @post.comments.build(params[:comment]) if @comment.save redirect post_path(@post) else erb :show endend

Page 34: Sinatra

y en show.erb<div id="comments"> <ul> <% for comment in @post.comments %> <li><p><%= escape_html comment.body %></p> <address>&mdash;<%= escape_html comment.author %></address></li> <% end %> </ul> <form method="post" action="<%= post_path(@post) %>/comments"> <div><label for="comment_author">Name</label> <input type="text" name="comment[author]" id="comment_author" value="<%= @comment.author %>"></div> <div><label for="comment_body">Your Comment</label> <textarea id="comment_body" name="comment[body]" rows="6" cols="40"><%= @comment.body %></textarea></div> <div><button type="submit">Leave Comment</button></div> </form></div>

Page 35: Sinatra

Embelleciendo un poco...ponemos en views/layout.erb

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link href="/styles.css" rel="stylesheet" type="text/css"> <title><%= page_title %></title> </head> <body> <div id="header"> <h1><%= page_title %></h1> </div> <%= yield %> </body></html>

Page 36: Sinatra

Embelleciendo un poco...

helpers do def post_path(post) "/#{post.permalink}" end def page_title if @post && [email protected]_record? "Awesome Blog | #{@post.title}" else "Awesome Blog" end endend

Page 37: Sinatra

Embelleciendo un poco...ponemos en views/layout.erb

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link href="/styles.css" rel="stylesheet" type="text/css"> <title><%= page_title %></title> </head> <body> <div id="header"> <h1><%= page_title %></h1> </div> <%= yield %> </body></html>

Page 38: Sinatra

Embelleciendo un poco...

public/styles.css

Page 39: Sinatra

y editar y borrar...para la próxima

Page 40: Sinatra
Page 41: Sinatra

es una interfazentre servidores

y frameworks

Page 42: Sinatra

class RackIsEasy def initialize(app) @app = app end

def call(env) [200, {"Content-Type" => "text/html"}, ["Ok"]] endend

Page 43: Sinatra

class AndRackIsPotentiallyDumb def initialize(app) @app = app end

def call(env) @app.call(env) endend

Page 45: Sinatra

para qué sirve eso?

Page 46: Sinatra

class MightyCache def initialize(app) @app = app end

def call(env) if response = cache_hit?(env) response else cache_store(env, @app.call(env)) end end

# def cache_hit?, cache_store, etcend

por ejemplo, caching:

Page 47: Sinatra

Sinatra is on crack

Page 48: Sinatra

última cosa

Page 49: Sinatra

prometo que ya me voy

Page 50: Sinatra

\m/

Page 51: Sinatra

Rails Metalsen app/metal/api.rb

class Api def self.call(env) if env["PATH_INFO"] =~ /^\/stuff.json/ [200, {"Content-Type" => "application/json"}, "{}"] else [404, {"Content-Type" => "application/json"}, ""] end endend

Page 52: Sinatra

Sinatra on RailsHard Metal Frank Sinatra

Page 53: Sinatra

El ejemplo anterior:

class Api < Sinatra::Base get "/stuff", :provides => "application/json" do "{}" endend

y en config/environment.rb

config.gem "sinatra"

Page 54: Sinatra

Questions?Preguntas?

http://github.com/foca/[email protected]