SlideShare a Scribd company logo
1 of 54
Download to read offline
Sinatra
Nicolás Sanguinetti

    foca

   http://entp.com
¿Qué es?
Un ejemplo
require quot;rubygemsquot;
require quot;sinatraquot;

get quot;/helloquot; do
  quot;<h1>Hello World</h1>quot;
end

y lo guardamos como hello.rb
Un ejemplo

$ gem install sinatra
$ ruby hello.rb
== Sinatra has taken the stage ...
>> Listening on 0.0.0.0:4567
Un ejemplo
Features
URLs Parametrizables
  get quot;/hello/:namequot; do |name|
    # también con params[:name]
    quot;<h1>Hello #{name}</h1>quot;
  end
Vistas
get quot;/hello/:namequot; do |name|
  @name = name
  erb :hello
end


       y en views/hello.erb

<h1>Hello <%= @name %></h1>
Layouts
     ponemos en views/layout.erb
<!DOCTYPE HTML PUBLIC quot;-//W3C//DTD HTML 4.01//ENquot;
  quot;http://www.w3.org/TR/html4/strict.dtdquot;>
<html lang=quot;enquot;>
<head>
  <title>Hello <%= @name || quot;Worldquot; %>
</head>
<body>
  <%= yield %>
</body>
</html>


     y todas nuestras vistas se renderean
 “adentro” de esta (reemplazando al yield)
HTTP
get quot;/...quot; do      put quot;/...quot; do
  quot;...quot;              quot;...quot;
end                end

post quot;/...quot; do     delete quot;/...quot; do
  quot;...quot;              quot;...quot;
end                end
Pero PUT y DELETE...
<form action=quot;/put/actionquot; method=quot;postquot;>
  <input type=quot;hiddenquot;
         name=quot;_methodquot;
         value=quot;putquot;>
  ...
</form>
Blog en 15 minutos    *




* para valores relativos de 15
necesitamos guardar los posts en algún lado, así que...

 Usando un ORM con Sinatra
              (por ejemplo, DataMapper)


require quot;dm-corequot;
require quot;do_sqlite3quot;
load quot;lib/models.rbquot;

configure do
  DataMapper.setup(:default, quot;sqlite3:blog.dbquot;)
end
lib/models.rb
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+/, quot;-quot;)
  end
end

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 :post
end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Qué queremos en el blog?
 get quot;/quot; do         get quot;/:permalink/editquot; do |permalink|
 end                end

 get quot;/newquot; do      put quot;/:permalinkquot; do |permalink|
 end                end

 post quot;/quot; do
 end

 get quot;/:permalinkquot; do |permalink|
 end

 post quot;/:permalink/commentsquot; do |permalink|
 end

 delete quot;/:permalinkquot; do |permalink|
 end
Creemos un Post entonces
     get quot;/newquot; do
       @post = Post.new
       erb :new
     end

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

       if @post.save
         redirect quot;/#{@post.permalink}quot;
       else
         erb :new
       end
     end
views/new.erb

<form method=quot;postquot; action=quot;/quot;>
  <div><label for=quot;post_titlequot;>Title</label>
    <input type=quot;textquot;
           name=quot;post[title]quot;
           id=quot;post_titlequot;
           value=quot;<%= @post.title %>quot;></div>
  <div><label for=quot;post_bodyquot;>Your Article</label>
    <textarea id=quot;post_bodyquot;
              name=quot;post[body]quot;
              rows=quot;20quot;
              cols=quot;40quot;><%= @post.body %></textarea>
  </div>
  <div><button type=quot;submitquot;>Post new article</button> or
    <a href=quot;/#{@post.permalink}quot;>go back</a>.</div>
</form>
Listando posts

get quot;/quot; do
  @posts = Post.all
  erb :index
end
views/index.erb
<h2>All Posts</h2>

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

    <%= post.body %>
  </li>
<% end %>
</ul>
Un paréntesis: helpers!

      helpers do
        def post_path(post)
          quot;/#{post.permalink}quot;
        end
      end
Mostrando un post

get quot;/:permalinkquot; do |permalink|
  @post = Post.first(:permalink => permalink)
  erb :show
end
views/show.erb

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

<%= @post.body %>

<div><a href=quot;/quot;>Go back to the list</a></div>
Parentesis: “partials”
                        views/post.erb
     <h2>
       <a href=quot;<%= post_path(post) %>quot;>
          <%= post.title %>
       </a>
     </h2>

     <%= post.body %>



                        views/post.erb
<%= erb(:post, :layout => false, :locals => { :post => @post }) %>
<div><a href=quot;/quot;>Go back to the list</a></div>
Comentarios
get quot;/:permalinkquot; do |permalink|
  @post = Post.first(:permalink => permalink)
  @comment = Comment.new
  erb :show
end

post quot;/:permalink/commentsquot; do |permalink|
  @post = Post.first(:permalink => permalink)
  @comment = @post.comments.build(params[:comment])

  if @comment.save
    redirect post_path(@post)
  else
    erb :show
  end
end
y en show.erb
<div id=quot;commentsquot;>
  <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=quot;postquot; action=quot;<%= post_path(@post) %>/commentsquot;>
    <div><label for=quot;comment_authorquot;>Name</label>
       <input type=quot;textquot;
              name=quot;comment[author]quot;
              id=quot;comment_authorquot;
              value=quot;<%= @comment.author %>quot;></div>
    <div><label for=quot;comment_bodyquot;>Your Comment</label>
       <textarea id=quot;comment_bodyquot;
                 name=quot;comment[body]quot;
                 rows=quot;6quot;
                 cols=quot;40quot;><%= @comment.body %></textarea></div>
    <div><button type=quot;submitquot;>Leave Comment</button></div>
  </form>
</div>
Embelleciendo un poco...
          ponemos en views/layout.erb
<!DOCTYPE HTML PUBLIC quot;-//W3C//DTD HTML 4.01//ENquot;
  quot;http://www.w3.org/TR/html4/strict.dtdquot;>
<html lang=quot;enquot;>
  <head>
    <meta http-equiv=quot;Content-Typequot;
          content=quot;text/html; charset=utf-8quot;>
    <link href=quot;/styles.cssquot; rel=quot;stylesheetquot; type=quot;text/cssquot;>
    <title><%= page_title %></title>
  </head>
  <body>
    <div id=quot;headerquot;>
      <h1><%= page_title %></h1>
    </div>
    <%= yield %>
  </body>
</html>
Embelleciendo un poco...
    helpers do
      def post_path(post)
        quot;/#{post.permalink}quot;
      end

      def page_title
        if @post && !@post.new_record?
          quot;Awesome Blog | #{@post.title}quot;
        else
          quot;Awesome Blogquot;
        end
      end
    end
Embelleciendo un poco...
          ponemos en views/layout.erb
<!DOCTYPE HTML PUBLIC quot;-//W3C//DTD HTML 4.01//ENquot;
  quot;http://www.w3.org/TR/html4/strict.dtdquot;>
<html lang=quot;enquot;>
  <head>
    <meta http-equiv=quot;Content-Typequot;
          content=quot;text/html; charset=utf-8quot;>
    <link href=quot;/styles.cssquot; rel=quot;stylesheetquot; type=quot;text/cssquot;>
    <title><%= page_title %></title>
  </head>
  <body>
    <div id=quot;headerquot;>
      <h1><%= page_title %></h1>
    </div>
    <%= yield %>
  </body>
</html>
Embelleciendo un poco...


       public/styles.css
y editar y borrar...
 para la próxima
es una interfaz
entre servidores
 y frameworks
class RackIsEasy
  def initialize(app)
    @app = app
  end

  def call(env)
    [200, {quot;Content-Typequot; => quot;text/htmlquot;}, [quot;Okquot;]]
  end
end
class AndRackIsPotentiallyDumb
  def initialize(app)
    @app = app
  end

  def call(env)
    @app.call(env)
  end
end
HTTP
                   app_1




                            Middlewares
                   app_2


                   app_3



                            App
                   app_4




http://mwrc2009.confreaks.com/ – Jon Crosby
para qué sirve eso?
por ejemplo, caching:
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, etc
end
Sinatra is on crack
última cosa
prometo que ya me voy
m/
Rails Metals
              en app/metal/api.rb
class Api
  def self.call(env)
    if env[quot;PATH_INFOquot;] =~ /^/stuff.json/
      [200, {quot;Content-Typequot; => quot;application/jsonquot;}, quot;{}quot;]
    else
      [404, {quot;Content-Typequot; => quot;application/jsonquot;}, quot;quot;]
    end
  end
end
Hard Metal Frank Sinatra
   Sinatra on Rails
El ejemplo anterior:
class Api < Sinatra::Base
  get quot;/stuffquot;, :provides => quot;application/jsonquot; do
    quot;{}quot;
  end
end



          y en config/environment.rb
               config.gem quot;sinatraquot;
Preguntas?
         Questions?

http://github.com/foca/sinatra-example-blog
      contacto@nicolassanguinetti.info

More Related Content

What's hot

Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlinintelliyole
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentationritika1
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
HTML5 Form Validation
HTML5 Form ValidationHTML5 Form Validation
HTML5 Form ValidationIan Oxley
 
Binary exploitation - AIS3
Binary exploitation - AIS3Binary exploitation - AIS3
Binary exploitation - AIS3Angel Boy
 
React workshop presentation
React workshop presentationReact workshop presentation
React workshop presentationBojan Golubović
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programmingScott Wlaschin
 
Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Scott Wlaschin
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1Dave Cross
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 formsEyal Vardi
 
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...Mario Heiderich
 
Chap 4 PHP.pdf
Chap 4 PHP.pdfChap 4 PHP.pdf
Chap 4 PHP.pdfHASENSEID
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to JavascriptAmit Tyagi
 
React Router: React Meetup XXL
React Router: React Meetup XXLReact Router: React Meetup XXL
React Router: React Meetup XXLRob Gietema
 
Elasticsearch for Data Engineers
Elasticsearch for Data EngineersElasticsearch for Data Engineers
Elasticsearch for Data EngineersDuy Do
 
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
 JavaScript - Chapter 9 - TypeConversion and Regular Expressions  JavaScript - Chapter 9 - TypeConversion and Regular Expressions
JavaScript - Chapter 9 - TypeConversion and Regular Expressions WebStackAcademy
 

What's hot (20)

Json
JsonJson
Json
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Object Oriented Javascript
Object Oriented JavascriptObject Oriented Javascript
Object Oriented Javascript
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentation
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
HTML5 Form Validation
HTML5 Form ValidationHTML5 Form Validation
HTML5 Form Validation
 
Binary exploitation - AIS3
Binary exploitation - AIS3Binary exploitation - AIS3
Binary exploitation - AIS3
 
React workshop presentation
React workshop presentationReact workshop presentation
React workshop presentation
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programming
 
Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 forms
 
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
 
Chap 4 PHP.pdf
Chap 4 PHP.pdfChap 4 PHP.pdf
Chap 4 PHP.pdf
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascript
 
React Router: React Meetup XXL
React Router: React Meetup XXLReact Router: React Meetup XXL
React Router: React Meetup XXL
 
Elasticsearch for Data Engineers
Elasticsearch for Data EngineersElasticsearch for Data Engineers
Elasticsearch for Data Engineers
 
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
 JavaScript - Chapter 9 - TypeConversion and Regular Expressions  JavaScript - Chapter 9 - TypeConversion and Regular Expressions
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
 

Similar to Sinatra

merb.intro
merb.intromerb.intro
merb.intropjb3
 
Merb Pluming - The Router
Merb Pluming - The RouterMerb Pluming - The Router
Merb Pluming - The Routercarllerche
 
What's new in Rails 2?
What's new in Rails 2?What's new in Rails 2?
What's new in Rails 2?brynary
 
Rails 3 And The Real Secret To High Productivity Presentation
Rails 3 And The Real Secret To High Productivity PresentationRails 3 And The Real Secret To High Productivity Presentation
Rails 3 And The Real Secret To High Productivity Presentationrailsconf
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentationbryanbibat
 
We9 Struts 2.0
We9 Struts 2.0We9 Struts 2.0
We9 Struts 2.0wangjiaz
 
Ajax On S2 Odp
Ajax On S2 OdpAjax On S2 Odp
Ajax On S2 Odpghessler
 
Page Caching Resurrected
Page Caching ResurrectedPage Caching Resurrected
Page Caching ResurrectedBen Scofield
 
Lecture 6 - Comm Lab: Web @ ITP
Lecture 6 - Comm Lab: Web @ ITPLecture 6 - Comm Lab: Web @ ITP
Lecture 6 - Comm Lab: Web @ ITPyucefmerhi
 
Optimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesOptimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesSugree Phatanapherom
 
Building Web Interface On Rails
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On RailsWen-Tien Chang
 
Lecture 3 - Comm Lab: Web @ ITP
Lecture 3 - Comm Lab: Web @ ITP Lecture 3 - Comm Lab: Web @ ITP
Lecture 3 - Comm Lab: Web @ ITP yucefmerhi
 
YL Intro html
YL Intro htmlYL Intro html
YL Intro htmldilom1986
 
Doctype htmlcodigioooooo
Doctype htmlcodigiooooooDoctype htmlcodigioooooo
Doctype htmlcodigiooooooANDERSON FABIAN
 
User Experience is dead. Long live the user experience!
User Experience is dead. Long live the user experience!User Experience is dead. Long live the user experience!
User Experience is dead. Long live the user experience!Greg Bell
 
Schenker - DSL for quickly creating web applications in Perl
Schenker - DSL for quickly creating web applications in PerlSchenker - DSL for quickly creating web applications in Perl
Schenker - DSL for quickly creating web applications in PerlJiro Nishiguchi
 

Similar to Sinatra (20)

merb.intro
merb.intromerb.intro
merb.intro
 
Merb Pluming - The Router
Merb Pluming - The RouterMerb Pluming - The Router
Merb Pluming - The Router
 
What's new in Rails 2?
What's new in Rails 2?What's new in Rails 2?
What's new in Rails 2?
 
Rails 3 And The Real Secret To High Productivity Presentation
Rails 3 And The Real Secret To High Productivity PresentationRails 3 And The Real Secret To High Productivity Presentation
Rails 3 And The Real Secret To High Productivity Presentation
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentation
 
We9 Struts 2.0
We9 Struts 2.0We9 Struts 2.0
We9 Struts 2.0
 
Ajax On S2 Odp
Ajax On S2 OdpAjax On S2 Odp
Ajax On S2 Odp
 
Page Caching Resurrected
Page Caching ResurrectedPage Caching Resurrected
Page Caching Resurrected
 
Php 3 1
Php 3 1Php 3 1
Php 3 1
 
Lecture 6 - Comm Lab: Web @ ITP
Lecture 6 - Comm Lab: Web @ ITPLecture 6 - Comm Lab: Web @ ITP
Lecture 6 - Comm Lab: Web @ ITP
 
Merb jQuery
Merb jQueryMerb jQuery
Merb jQuery
 
Optimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesOptimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile Devices
 
Building Web Interface On Rails
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On Rails
 
Lecture 3 - Comm Lab: Web @ ITP
Lecture 3 - Comm Lab: Web @ ITP Lecture 3 - Comm Lab: Web @ ITP
Lecture 3 - Comm Lab: Web @ ITP
 
YL Intro html
YL Intro htmlYL Intro html
YL Intro html
 
Doctype htmlcodigioooooo
Doctype htmlcodigiooooooDoctype htmlcodigioooooo
Doctype htmlcodigioooooo
 
Front End on Rails
Front End on RailsFront End on Rails
Front End on Rails
 
User Experience is dead. Long live the user experience!
User Experience is dead. Long live the user experience!User Experience is dead. Long live the user experience!
User Experience is dead. Long live the user experience!
 
Intro Html
Intro HtmlIntro Html
Intro Html
 
Schenker - DSL for quickly creating web applications in Perl
Schenker - DSL for quickly creating web applications in PerlSchenker - DSL for quickly creating web applications in Perl
Schenker - DSL for quickly creating web applications in Perl
 

Sinatra

  • 2. Nicolás Sanguinetti foca http://entp.com
  • 4. Un ejemplo require quot;rubygemsquot; require quot;sinatraquot; get quot;/helloquot; do quot;<h1>Hello World</h1>quot; end y lo guardamos como hello.rb
  • 5. Un ejemplo $ gem install sinatra $ ruby hello.rb == Sinatra has taken the stage ... >> Listening on 0.0.0.0:4567
  • 8. URLs Parametrizables get quot;/hello/:namequot; do |name| # también con params[:name] quot;<h1>Hello #{name}</h1>quot; end
  • 9. Vistas get quot;/hello/:namequot; do |name| @name = name erb :hello end y en views/hello.erb <h1>Hello <%= @name %></h1>
  • 10. Layouts ponemos en views/layout.erb <!DOCTYPE HTML PUBLIC quot;-//W3C//DTD HTML 4.01//ENquot; quot;http://www.w3.org/TR/html4/strict.dtdquot;> <html lang=quot;enquot;> <head> <title>Hello <%= @name || quot;Worldquot; %> </head> <body> <%= yield %> </body> </html> y todas nuestras vistas se renderean “adentro” de esta (reemplazando al yield)
  • 11. HTTP get quot;/...quot; do put quot;/...quot; do quot;...quot; quot;...quot; end end post quot;/...quot; do delete quot;/...quot; do quot;...quot; quot;...quot; end end
  • 12. Pero PUT y DELETE... <form action=quot;/put/actionquot; method=quot;postquot;> <input type=quot;hiddenquot; name=quot;_methodquot; value=quot;putquot;> ... </form>
  • 13. Blog en 15 minutos * * para valores relativos de 15
  • 14. necesitamos guardar los posts en algún lado, así que... Usando un ORM con Sinatra (por ejemplo, DataMapper) require quot;dm-corequot; require quot;do_sqlite3quot; load quot;lib/models.rbquot; configure do DataMapper.setup(:default, quot;sqlite3:blog.dbquot;) end
  • 15. lib/models.rb 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+/, quot;-quot;) end end 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 :post end
  • 16. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 17. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 18. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 19. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 20. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 21. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 22. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 23. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 24. Qué queremos en el blog? get quot;/quot; do get quot;/:permalink/editquot; do |permalink| end end get quot;/newquot; do put quot;/:permalinkquot; do |permalink| end end post quot;/quot; do end get quot;/:permalinkquot; do |permalink| end post quot;/:permalink/commentsquot; do |permalink| end delete quot;/:permalinkquot; do |permalink| end
  • 25. Creemos un Post entonces get quot;/newquot; do @post = Post.new erb :new end post quot;/quot; do @post = Post.new(params[:post]) if @post.save redirect quot;/#{@post.permalink}quot; else erb :new end end
  • 26. views/new.erb <form method=quot;postquot; action=quot;/quot;> <div><label for=quot;post_titlequot;>Title</label> <input type=quot;textquot; name=quot;post[title]quot; id=quot;post_titlequot; value=quot;<%= @post.title %>quot;></div> <div><label for=quot;post_bodyquot;>Your Article</label> <textarea id=quot;post_bodyquot; name=quot;post[body]quot; rows=quot;20quot; cols=quot;40quot;><%= @post.body %></textarea> </div> <div><button type=quot;submitquot;>Post new article</button> or <a href=quot;/#{@post.permalink}quot;>go back</a>.</div> </form>
  • 27. Listando posts get quot;/quot; do @posts = Post.all erb :index end
  • 28. views/index.erb <h2>All Posts</h2> <ul id=quot;postsquot;> <% for post in @posts %> <li class=quot;postquot;> <h2> <a href=quot;/<%= post.permalink %>quot;> <%= post.title %> </a> </h2> <%= post.body %> </li> <% end %> </ul>
  • 29. Un paréntesis: helpers! helpers do def post_path(post) quot;/#{post.permalink}quot; end end
  • 30. Mostrando un post get quot;/:permalinkquot; do |permalink| @post = Post.first(:permalink => permalink) erb :show end
  • 31. views/show.erb <h2> <a href=quot;<%= post_path(@post) %>quot;> <%= @post.title %> </a> </h2> <%= @post.body %> <div><a href=quot;/quot;>Go back to the list</a></div>
  • 32. Parentesis: “partials” views/post.erb <h2> <a href=quot;<%= post_path(post) %>quot;> <%= post.title %> </a> </h2> <%= post.body %> views/post.erb <%= erb(:post, :layout => false, :locals => { :post => @post }) %> <div><a href=quot;/quot;>Go back to the list</a></div>
  • 33. Comentarios get quot;/:permalinkquot; do |permalink| @post = Post.first(:permalink => permalink) @comment = Comment.new erb :show end post quot;/:permalink/commentsquot; do |permalink| @post = Post.first(:permalink => permalink) @comment = @post.comments.build(params[:comment]) if @comment.save redirect post_path(@post) else erb :show end end
  • 34. y en show.erb <div id=quot;commentsquot;> <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=quot;postquot; action=quot;<%= post_path(@post) %>/commentsquot;> <div><label for=quot;comment_authorquot;>Name</label> <input type=quot;textquot; name=quot;comment[author]quot; id=quot;comment_authorquot; value=quot;<%= @comment.author %>quot;></div> <div><label for=quot;comment_bodyquot;>Your Comment</label> <textarea id=quot;comment_bodyquot; name=quot;comment[body]quot; rows=quot;6quot; cols=quot;40quot;><%= @comment.body %></textarea></div> <div><button type=quot;submitquot;>Leave Comment</button></div> </form> </div>
  • 35. Embelleciendo un poco... ponemos en views/layout.erb <!DOCTYPE HTML PUBLIC quot;-//W3C//DTD HTML 4.01//ENquot; quot;http://www.w3.org/TR/html4/strict.dtdquot;> <html lang=quot;enquot;> <head> <meta http-equiv=quot;Content-Typequot; content=quot;text/html; charset=utf-8quot;> <link href=quot;/styles.cssquot; rel=quot;stylesheetquot; type=quot;text/cssquot;> <title><%= page_title %></title> </head> <body> <div id=quot;headerquot;> <h1><%= page_title %></h1> </div> <%= yield %> </body> </html>
  • 36. Embelleciendo un poco... helpers do def post_path(post) quot;/#{post.permalink}quot; end def page_title if @post && !@post.new_record? quot;Awesome Blog | #{@post.title}quot; else quot;Awesome Blogquot; end end end
  • 37. Embelleciendo un poco... ponemos en views/layout.erb <!DOCTYPE HTML PUBLIC quot;-//W3C//DTD HTML 4.01//ENquot; quot;http://www.w3.org/TR/html4/strict.dtdquot;> <html lang=quot;enquot;> <head> <meta http-equiv=quot;Content-Typequot; content=quot;text/html; charset=utf-8quot;> <link href=quot;/styles.cssquot; rel=quot;stylesheetquot; type=quot;text/cssquot;> <title><%= page_title %></title> </head> <body> <div id=quot;headerquot;> <h1><%= page_title %></h1> </div> <%= yield %> </body> </html>
  • 38. Embelleciendo un poco... public/styles.css
  • 39. y editar y borrar... para la próxima
  • 40.
  • 41. es una interfaz entre servidores y frameworks
  • 42. class RackIsEasy def initialize(app) @app = app end def call(env) [200, {quot;Content-Typequot; => quot;text/htmlquot;}, [quot;Okquot;]] end end
  • 43. class AndRackIsPotentiallyDumb def initialize(app) @app = app end def call(env) @app.call(env) end end
  • 44. HTTP app_1 Middlewares app_2 app_3 App app_4 http://mwrc2009.confreaks.com/ – Jon Crosby
  • 46. por ejemplo, caching: 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, etc end
  • 47. Sinatra is on crack
  • 49. prometo que ya me voy
  • 50. m/
  • 51. Rails Metals en app/metal/api.rb class Api def self.call(env) if env[quot;PATH_INFOquot;] =~ /^/stuff.json/ [200, {quot;Content-Typequot; => quot;application/jsonquot;}, quot;{}quot;] else [404, {quot;Content-Typequot; => quot;application/jsonquot;}, quot;quot;] end end end
  • 52. Hard Metal Frank Sinatra Sinatra on Rails
  • 53. El ejemplo anterior: class Api < Sinatra::Base get quot;/stuffquot;, :provides => quot;application/jsonquot; do quot;{}quot; end end y en config/environment.rb config.gem quot;sinatraquot;
  • 54. Preguntas? Questions? http://github.com/foca/sinatra-example-blog contacto@nicolassanguinetti.info