Hi, my name is Caitlin and I love Ruby. It’s simple, it’s eloquent, it actually seems to be able to do everything I want it to do. But if, like me, you started your coding journey with front-end HTML, CSS and JavaScript, you might be frustrated with the fact that all your wonderful Ruby code, your classes and methods and RSPEC tests, all seems to be stuck firmly in the back end. As much as I love opening up my terminal, or running my debugger in RubyMine, I was a bit stumped as to how to connect my code with a front end so that I could share it with people.

Then came Sinatra – and ol’ Blue Eyes certainly sings a beautiful song. Sinatra is a Ruby framework that helps bridge the gap between front and back ends of programming. It’s a much more lightweight framework when compared to Rails, which means not only is it faster but you’ll actually be able to understand more of what it’s doing! For this tutorial I assume you have Ruby and a text editor installed on your computer.

So let’s have a look at how we can set up a very simple Sinatra app – I’ll expand on this app in another post to make it a bit more substantial, and to show how you can add some interactive JavaScript into your Sinatra app. To get started, create a folder with the name of your project – I’m going to call mine Sinatra for now! Inside this folder create a subfolder called views.

First of all, I’ll talk you through the files you’ll need to set up – a Gemfile and a controller (app.rb). A bit later on we’ll need a default.erb file inside your views folder – feel free to create this now but we won’t be using it just yet. Your folder should look like mine below. Note – you don’t create the Gemfile.lock yourself, Ruby will do this for you!

The Gemfile (no file extension, just Gemfile) is where you tell your app which Gems it needs to use.  The contents should look like this:

source 'https://rubygems.org'

ruby '2.4.0'

gem 'sinatra'
gem 'sinatra-contrib'

The source is simply saying where to find the gems, we are then telling the program which version of ruby to use (if you have a different version of Ruby installed, feel free to change it to that) and that we need to use Sinatra and Sinatra-contrib.

The app.rb file is one you’ll be spending a lot of time in if you’re making a more complicated app, but we’ll keep things simple. Let’s put the following into your app.rb file to start with*.

require 'sinatra'
require 'sinatra/reloader'

get '/' do
  "Hello Frank"
end

And that’s all you need for a running website – crazy, isn’t it? Let’s have a look at what we have made! To run your app, simply make sure you’re in your project folder (in my case in ‘Sinatra’) in your terminal/command prompt and enter the command “ruby app.rb”. You’ll see something like this:

The last two lines are most important for us – if you want to stop your server, you’ll need to use CTRL + C. ‘Listening on tcp://localhost:4567’ means that we can type “localhost:4567” into the address bar of your browser and see our app! Let’s do this now:

It’s not exactly the Sistine Chapel of apps, but it’s running! Have a look back in your app.rb file to figure out what’s happening.  The get ‘/’ do part of the code is very important. GET and POST are two of the methods your server uses to talk to the client (in this case, the client is whatever browser you’re using to view the app.  GET is asking the server to ‘get’ some information to show the client/browser. POST is sending some information from the client/browser back to the server – for example, submitting a form and sending the information back to be stored in the server.

So our “get ‘/’ do” method is telling us what to do when we get a slash – or, more specifically, if there is no specified path in the URL after ‘localhost:4567/’. If you try going to ‘localhost:4567/index’ you’ll get an error message from Sinatra with a handy little hint, telling you what’s missing.

To fix this, we’ll put this into our app.rb file, under our get ‘/’ route. Your app.rb file should now look like this…

require 'sinatra'
require 'sinatra/reloader'

get '/' do
  "Hello Frank"
end

get '/index' do
  "Hello World"
end

…and now when you go to ‘localhost:4567/index’ you’ll see ‘Hello World’ instead of ‘Hello Frank’ or an error message. How splendid!

Now just to add another little trick in for you – we’re going to change our “get ‘/’ do” route to the following:

get '/' do
  redirect to('/index')
end

Before you load your page, have a think about what ‘redirect to’ might do, and what you expect to see when you go to ‘localhost:4567’. Once you’ve had a think, try going there – you’ll find that instead of being at just ‘localhost:4567’ you’ve been automatically sent, or redirected, to our index page – and that we see the contents of our index page too. You can use ‘redirect’ to move your users anywhere around your website that you like – it can come in very handy!

Alright, I think it’s about time we made out website do something a bit more exciting. In this example I’m going to create a list of my favourite Sinatra songs with a link to a video. First I’ll change my “get ‘/index’ do” route to the following (feel free to copy and paste):

get '/index' do
  @songs = [{title: 'Fly Me To The Moon', url: "https://www.youtube.com/watch?v=mQR0bXO_yI8"},
            {title: 'New York, New York', url: "https://www.youtube.com/watch?v=btFfXgUdIzY"},
            {title: 'My Way', url: 'https://www.youtube.com/watch?v=6E2hYDIFDIU'},
            {title: 'The Way You Look Tonight', url: 'https://www.youtube.com/watch?v=h9ZGKALMMuc'},
            {title: 'I Get A Kick Out Of You', url: 'https://www.youtube.com/watch?v=wSrHvNr8QQQ'}]
  erb :default
end

If you’re familiar with Ruby you should recognise @songs as an array of hashes. If not – the [square brackets] create an array, or a list, that we can easily iterate through. Each item in our @songs array is called a hash and is denoted by {curly brackets}. In a hash items come in key/value pairs and so you can access a value by its key. The last line in  our route is one of the very handy things about Sinatra. It is essentially redirecting to an ERB file (an Embedded RuBy file) – it automatically looks for a file called default.erb in our views folder. If you didn’t create this earlier, go and do so now.

Embedded Ruby is a file type that allows us to write HTML and embed Ruby code in it. Embedded Ruby tags go inside the html tags – we use <% %> tags to execute Ruby code or <%=  %> to print something to HTML.  Our default.erb file should look like this:

<head>
<title>Sinatra Songs</title>
</head>
<body>
<h1>Sinatra Songs</h1>
<% @songs.each do |song| %>
    <h3> <%= song[:title] %></h3>
    <p> <a href="<%=song[:url]%>"> Video </a></p>
<% end %>
</body>

Inside the first erb tags (<% %>) we are calling the ‘each’ method on our @songs array. That means we are going to go through ‘each’ item in the array, and then inside the pipes we say we are going to refer to each item as |song|.

The next line we create a header (<h3> tag) for each song and inside the header we put the the song title. Because each song is actually a hash we can refer to each value by its key eg. song[:title] or song[:url].

After this we create a paragraph (<p> tag), and enclose a link or anchor tag (<a>). The href property of the anchor tag tells it where to direct the link, and we want it to go to the url of the song, so we’ll use another set of erb tags to get that information out of our @songs array and song hash.

And that’s it! Go have a look at your beautiful Sinatra app – it should look something similar to below.

If so – you’re done! Congratulations. Feel free to play around with it and make it your own – you can find all the files in my Sinatra repo on github here. In my next Sinatra tutorial I’ll show you how to add a bit of styling with a CSS file, and some interactivity to our app. Thanks for reading, see you next time 🙂

*If you’ve seen other Sinatra tutorials you may notice that including the Sinatra-contrib gem and requiring ‘sinatra/reloader’ are less common, but they’re super helpful. It means you won’t need to start and stop your server every time you make changes. Brilliant!