Introduction to Sinatra

what is sinatra?

Sinatra just like RSpec is a ruby gem.Meaning it is an application written by someone to make your easy.Sinatra is a Domain Specific Language(DSL)for quickly creating web applications in Ruby with minimal effort.

creating hello world app

Hope that you now armed more than ever let’s get our hands dirty

Let’s create our first Sinatra App. First create a directory and name it Sinatra-App

Then create a file within the directory named ‘myapp’:

myapp.rb

1
2
3
4
5
require 'sinatra'

get '/' do
  'Hello world!'
end

And run with:

1
$ ruby myapp.rb

This will automatically open a server so you can view your app at: http://localhost:4567

Alternatively, you may start your server with the rackup command. First create a config.ru file in your app directory touch config.ru Navigate to the file and require your .rb file also add a class that will run:

1
2
require ./myapp
run Sinatra::Application

The "/" the routes or path which we follow in we try to reach our application.This case we hit the root of our application

Let us we wanted to signup.We would go to http://localhost:4567/signup

myapp.rb

1
2
3
4
5
6
...
...

get '/signup' do
    "I am trying to sign in "
end 

Params

Sometimes a web request contain dynamic data.That is whose content changes.Let use car name.When user send a request with name "volvo".Next time will she or she might send "Ferrari".These input which form part of request are what are known as params.

1
2
3
get '/cars:name' do
    "This car is #{params["name"]}"
end

visit

Exercise

  1. Give the above application ability to show your name,input(your name) being in lower case.Put should show uppercase when this route is visited

http://localhost:4567/myname/your name

  1. Add route which show current time when visited

Erb

This the embedded ruby it is used to embed ruby code into markup.checkout erb indocs.Markup are what are ussually used to display browser content.

Content to be displayed are put in <%= %> while logic which are not to be display are put in <% %>

In this example want to display our content there we use <%= %>

myapp.rb

1
2
3
4
5
get '/age_bracket:age' do

  age_sum =  "Hello you are :<%=  if params[:a].to_i >= 18; 'Over age' else 'Underage' end%>
  erb age_sum
end

Above is ruby code try to check if param give after over it to integer is equal or greater than 18 ouput "Over age" or "Under age" depending on conditions met.Note "Hello you are :" is not ruby code therefore will displayed without embedding.

Visit the url which w will visit this route giving vary interger values and observe your result.

The above code issued above is not common practise and template are ussally separated from logic and will see how to do that soon.But for now using above example try the exercise below.

Exercise

  1. Create a route which will url localhost:9292/2/2 and the sum of give interger in this case 4. Your display should like so:

"The sum of numbers 2 and 2 is 4". Display your results in a template(erb)

Templating

Has you have seen erb allow us to write ruby code inside the markup which get render(displayed) in browser.The templates also called the views are names lgiven to these markup being rendered.

Inline template

As its name suggest inline template entails a marked inside the logic application.The logic and view are not seperated.

Let us say we want to display template named index which will list of all users.We would do like so:

change the content your root route like so:

myapp.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
require 'sinatra'
get '/' do

 erb :index
end

// other routes you created
...

// add code below, below the routes
__END__
@@index
<h1>Users</h1>
<ul>
    <li>Jane</li>
    <li>John</li>
    <li>Doe</li>
</ul>

We can create as many template we deemed fit.On that spirit let us create template which allows us to sign up.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
require 'sinatra'

// other routes


get '/signup/:age' do
    age = params["age"]
    @age = age.to_i

  erb :signup
end



__END__
//index template

@@signup
<body>
<h1>Signup</h1>

<%if @age >= 18 %>
<p>Your are old enough to join us</p>
<%else%>
<p>Just wait for <%=18 - @age%> more years we are waiting<p>

<%end%>
</body>

Note the usage of instance variable.Remember it act as our memory therefore where block is invoke it's values will be remembered.

Note our html do not have <!DOCtype> and meta data. Such data belong to template known as layout.Layout is a template to display content which will be reused in other templates, other templated are injected into layout using yield.

myapp.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
require 'sinatra'
//routes


__END__

@@layout
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<%=yield%>
</body>
</html>

// other templates

EXERCISE

1.Given the following data, display the name, age and country of each person in a table using a templete called people_details assuming that the first name, age and country in the lists belong to one person. The table should columns Name, Country, Age

Add the content in myapp.rb file

1
2
3
4
5
{
     "name" => ["Alice", "Michael", "Jane", "Clare", "Mary", "John"],
     "age" => [20, 23, 43, 32, 23, 44],
     "country" => ["Kenya", "Tanzania", "Ghana", "Uganda", "Ethiopia", "Egypt"]
}

This is an example of the display

Name Country Age
Alice Kenya 20

2.List display all character available in your name is a list. modify content of block which had route dispalying your name to render myname_character(template).For instance if url is visited and name is Jane the display should be like so:

Name Characters

  • J

  • a

  • n
  • e

External Templating

After while you realise the template are getting much more polluting our logic.Well we can separate our concerns(the logic and templated ).We can do so by creating views directory and putting our templates.The directories is called views because it's contents(the templates) are to be viewed by the users.

The logic of template remain the same the only difference here we shipping our templates to views folder.

Create a directory views in the root of your application i.e myapp/views. Let us ship our templates into the views directory.

myapp.rb

1
2
3
4
// routes
...
// templates
// remove signup templates

When try visiting /signup in your browser get error like so:

sinatra error

Error is letting us know we need to create signup.erb inside views directory

Let us give it what it want

create a file signup.erb inside views that is myapp/views/sign.erb add content of signup template like so.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<body>
<h1>Signup</h1>

<%if @age >= 18 %>
<p>Your are old enough to join us</p>
<%else%>
<p>Just wait for <%=18 - @age%> more years we are waiting<p>

<%end%>
</body>

Exercise

Remove all template from your previous working replacing them with templates in the views directory.Kindly note remove the one at a time.

Other templating libraries

Erb comes with ruby inbuilt as a way of templating but also has other gem which can help in templating

Other templating libraries

Erb comes with ruby inbuilt as a way of templating but also has other gem which can help in templating