Michael R. Cook Ruby and Golang Developer

Up and Going in Roda: Static Ruby Websites

Post image for Up and Going in Roda: Static Ruby Websites

Recently I started experimenting with the Roda framework to build web applications but as there are not many tutorials, or blog posts in general, about Roda, I thought I’d share my experiences here. Over the coming weeks I’ll be writing a number of articles on using Roda but rather than having to duplicate lots of setup code I think it’ll be easier to have a base app to work from. So, in the next two articles I’ll be building an extremely simple blog using Roda, Postgres, and the Sequel ORM. For this first part we’ll deliver static content, leaving User accounts and posts for part two.

For those who want to follow along, my system is Mac OSX 10.9, along with the following software versions;

  • Ruby 2.2.2
  • Postgres 9.4
  • Roda 2.2.0
  • Sequel 4.21.0

Your application may not work if you use a different version of Roda than what I specify here, but for the rest, you shouldn’t encounter any issues if your versions are a little older/newer.

Installation of Ruby and Postgres is left as an exercise for the reader.

Installing Roda

This is actually the simplest part of the whole procedure as Roda is just a regular GEM. We are however going to be using Bundler for our gem management so first you’ll want to install that, followed by Roda;

$ gem install bundler
$ gem install roda

Creating a New App

Unfortunately there are currently no site generators in Roda like there is in Ruby on Rails (rails new myapp). This means we’ll have to generate our application directory and file structure by hand. Here’s the outline that we’ll be using for our simple blog;

- myapp/
  - models/
  - public/
  - views/
  - config.ru
  - Gemfile
  - myapp.rb
  - models.rb

Go ahead, create the base app directory;

$ mkdir ~/myapp
$ cd ~/myapp

I always like to use Bundler for the gem management so we’ll need to create a Gemfile in which we’ll specify the basic gems requirements for delivering static content;

# ./Gemfile

source "https://rubygems.org"

gem "roda", "~> 2.1.0"
gem "tilt", "~> 2.0.1"
gem "erubis", "~> 2.7.0"

Remember to run bundle install now, and each time you make a change to this file.

At present we have just three dependencies; the first is Roda itself, but we’re also including tilt and erubis so that we can use ERB templates in all our views.

Like all Ruby web frameworks, Roda is built on top of Rack, so we’re going to need a config.ru so that when we start the server (with rackup), our application will be loaded;

# ./config.ru

require File.expand_path("../myapp",  __FILE__)
run Myapp.app

The final part of our setup procedure is to create the main application class and inherit from Roda;

# ./myapp.rb

require "roda"

class Myapp < Roda
  route do |r|
    r.root do
      "Hello!"
    end
  end
end

Inside our class we use Roda’s route, which is where we define all the routing for our website. For the moment I’ve just set root to show a simple welcome message. Let’s boot up our application to make sure everything is working as expected;

$ rackup

Check the output of that command to make sure you use the correct port when viewing the site in your web browser. Mine says, WEBrick::HTTPServer#start: pid=46685 port=9292. Open your web browser and type in the url; localhost:9292. If all is well you should see the message: Hello!

Layouts and View Templates

Now that everything is setup and working, it’s time to start fleshing out the application. Like the good developer we are, we’re going to want to make use of templates so as to make sure we’re using standard styling across all pages. We’ll create a layout template using Ruby’s built in ERB, along with using Twitter’s Bootstrap framework so we get all their styling goodness for free.

All “views” will be placed in a views directory, while additional CSS/JS and images should go in a directory labelled public;

$ mkdir ~/myapp/public
$ mkdir ~/myapp/public/css
$ mkdir ~/myapp/public/images
$ mkdir ~/myapp/public/js

$ mkdir ~/myapp/views

All menu items, stylesheet references, page headers/footers and sidebars, will all go a layout.erb. As we’ll be using Bootstrap I’m going to copy their example layout pretty much as-is. Copy the follow into a new file named layout.erb, and place it in the views directory;

# ./views/layout.erb

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>My Roda Website</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="container">
      <div class="page-header">My Roda App</div>
      <%= yield %>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
  </body>
</html>

Notice the yield in that code? That is where our individual page content with be inserted. For now we’ll just add some stand-in text;

# ./views/homepage.erb

<p>Welcome to my new website!</p>

Note the use of the .erb extension. Any view file that uses the .erb extension informs Roda to use tilt/erubis when processing.

Roda needs to be told to use our views, images, css, and js files, which can be done via two plugins; render and static. These will be added to the main application class as follows, and while we’re there, we’ll also tell Roda to use that homepage.erb view we created when the web browser points to the homepage url.

# ./myapp.rb

class Myapp < Roda
  plugin :static, ["/images", "/css", "/js"]
  plugin :render
  plugin :head

  route do |r|
    r.root do
      view("homepage")
    end
  end
end

You may also notice that I’ve added the :head plugin. If we don’t then any client that just checks headers will see a 404 response, which could have a negative impact with Search Engine bots.

That’s it! Restart your server (CTRL-C then run rackup again). If all is well then you should be seeing the sites’ banner message (My Roda Website) from the layout file, along with the welcome message we placed in the homepage view.

More Static Pages

Our final task for this part of the tutorial is to create a couple of new web pages. Pretty much any site you visit will have both an about page and contact page. All our previous work makes this bit of the tutorial a breeze. Let’s start by creating some new views for these pages;

# ./views/about.erb

<h1>About Me</h1>
<p>I am currently building my first Roda application!</p>

and the contacts page;

# ./views/contact.erb

<h1>Contact</h1>
<p>You can send me an email or connect with me on Twitter/Facebook/Google/etc.</p>

These pages won’t be accessible until we have some routes for them. Open up the main app class and add the following;

# ./myapp.rb

route do |r|
  # ...

  r.get "about" do
    view("about")
  end

  r.get "contact" do
    view("contact")
  end
end

Pretty simple huh? We have two GET verbs, each with a call to their respective view templates. When you visit localhost:9292/about Roda will call up the about.erb template, which is then rendered inside of layout.erb.

To aid our visitors in accessing these pages we’re going to add a navigation bar to the top of the site layout. Directly after the opening body tag add this Bootstrap navbar markup;

# ./views/layout.erb

<body>
  <nav class="navbar navbar-default navbar-inverse">
    <div class="container">
      <ul class="nav navbar-nav">
        <li><a href="/">Home</a></li>
        <li><a href="/about">About</a></li>
        <li><a href="/contact">Contact</a></li>
      </ul>
    </div>
  </nav>

  # ...
</body>

Restart the server and start exploring your new site.

In under 100 lines of code we have a fully functioning website. Sure, there’s a lot more that can, and probably needs to be done, but you can go a long way just with this simple code.

Be sure to check out the Roda pages to learn more about this routing tree framework. You’ll also find lots of additional plugins which certainly take the pain out of web development.

PART 2: Up and Going in Roda: A Simple Blog

2 Comments

\/|(

Jan 17, 2017 at 1:44 am

Line 10 and 14 are missing from the second myapp.rb code source.

# ./myapp.rb

require "roda"

class Myapp < Roda
  plugin :static, ["/images", "/css", "/js"]
  plugin :render
  plugin :head

  route do |r|
    r.root do
      view("homepage")
    end
  end
end

Michael Cook

Jan 17, 2017 at 7:01 pm

Many thanks for the fix, I’ve updated the post.


About Me

Hi, my name is Michael and this is my personal blog. Here I’ll be posting my coding thoughts and experiments, specifically in regards to building websites in Ruby (Rails, Roda, Sinatra, etc). This site is powered by Thunderaxe, a blogging platform I’m building using the Roda Ruby framework, which I hope to be open sourcing in the near future.