The Happy Book of Happy

Welcome to the Happy Book of Happy, an introduction on how to develop web applications using Happy, a cute little web application toolkit for Ruby! Let’s get straight to it, shall we?

The Basics

“Hello World” with Happy

So, without further ado, here’s the Happy version of “Hello World”:

``` ruby # require ‘happy’

class MyApp < Happy::Controller def route “Hello World” end end

run MyApp ```

You can run this example (assuming it’s inside a file called by simply issuing the rackup command. Try rackup --help for available options.

Happy Controllers

So, the previous chapter’s “Hello World” example isn’t terribly exciting, but there’s a couple of interesting things to note here.

First of all, note how you’re creating a subclass of Happy::Controller. That class is central to how Happy works; pretty much everything you do in Happy revolves around controllers.

Unlike your may know it from frameworks like Ruby on Rails, controllers are really self-contained applications that describe behaviour. They can be very simple (simply rendering a string, like the example above), but also very complex (for example, they could provide a complete blog engine, or admin backend.)

So here’s some of the things a Happy controller can do:

  • serve a simple string-like response
  • render a template
  • process URL paths
  • pass control over the request to another controller (or Rack app)

Note for friends of Rack: Happy is a very Rack-friendly framework. Happy controllers are also just Rack apps, so you can mount them anywhere that you can mount Rack apps (like inside another Rails application). Happy also happily mounts non-Happy Rack apps, so it works both ways. Life is good.

The route method

Pretty much the most important part of any Happy controller is the route method. In your own controller classes, you’re expected to override this method to implement your controller’s request handling logic.

And this is where Happy is very different from most other web frameworks: instead of dispatching incoming requests among a set of controller classes or actions, Happy will route each and every request – no exceptions – through your application controller’s route method. It is then up to this method to decide on how to deal with the request.

Let’s take a look at some examples in the following chapters.

Handling paths

In most web applications, you will probably want to serve different responses depending on the URL accessed. In Happy, you use the on method to define the behavior for specific URL paths. Here’s a simple example:

``` ruby class MyApp < Happy::Controller def route # When /foo is accessed, respond with ‘bar!’ on ‘foo’ do ‘bar!’ end

# Paths can be nested, of course:
on 'one' do
  on 'two' do
    'one and two!'

  'just one!'

'Try /foo, /one or /one/two!'   end end ```

In other words, on lets you provide code blocks that are only executed when a certain path has been requested. Note that on calls can be nested; also note that if one of these blocks returns just a string value, it will be rendered as the response.

Structuring Happy controllers

Since controllers are just normal Ruby classes, you can use all the tools you know from Ruby to structure your application. For example, it is recommended to move the actual logic of your actions to separate methods, and just call those methods from within the on blocks. This makes your controllers easier to maintain and test. Here’s an example:

``` ruby class MyApp < Happy::Controller def route on(‘users’) { list_users } on(‘images’) { list_images } homepage end

def homepage render ‘home.erb’ end

def list_users @users = User.all render ‘users.erb’ end

def list_images @images = Image.all render ‘images.erb’ end end ```

Reacting on specific HTTP verbs

While the on command doesn’t care about the HTTP verb being used to make the request, there’s also on_get, on_post, on_put and on_delete. Note that these can also be called without a path argument. Here’s an example:

``` ruby class MyApp < Happy::Controller def route on ‘resource’ do on_get { ‘You accessed /resource using GET!’ } on_post { ‘You accessed /resource using POST!’ } on_put { ‘You accessed /resource using PUT!’ } on_delete { ‘You accessed /resource using DELETE!’ } end

'Try /resource with any HTTP verb!'   end end ```

Setting headers

You can use the header method to set any type of HTTP header for your response. Example:

ruby # Set the 'Content-type' header to 'text/css' header :content_type, 'text/css'

There’s a couple of shortcut methods available to set certain headers directly. Examples:

ruby content_type 'text/css' cache_control 'public, max-age=3600, must-revalidate'

For a complete list, please check the documentation for Happy::Controller::Actions.

Rendering view templates

Obviously, just serving simple strings isn’t really what you want in most applications, so Happy also allows you to render view templates through myriad of available template engines. (Happy uses the tilt gem, so any template engine supported by tilt is also supported by Happy.)

All template rendering is done through the render method. Simply pass the name of a template file. For example:

``` ruby class MyApp < Happy::Controller def route on(‘info’) { render ‘info.erb’ } on(‘help’) { render ‘help.erb’ }

render 'home.erb'   end end ```

The default directory Happy will look for view templates in is the views/ subdirectory of your application. This is configurable, of course; more on configuration alter.

Using layouts

Happy allows you to define a view template as a layout template, applying it to every response generated. Use the layout command to set it. For example:

``` ruby class MyApp < Happy::Controller def route layout ‘layouts/default.erb’

# From a previous example...
on('info') { render 'info.erb' }
on('help') { render 'help.erb' }

on('admin') do
  # use a different layout inside the admin section
  layout 'layouts/admin.erb'
  render 'admin.erb'

render 'home.erb'   end end ```

The layout file itself should contain an invocation of yield where the inner part of the response should appear.

Adding view helpers

In Happy, view templates are rendered within the scope of your controller (as opposed to a specific view context object), so any method from your controller will also be available in your views.

It is advised, however, that you specifically declare helper methods using the helper command so that they are available to all controllers. This is necessary if you modularize your applications into several different controller classes that share view files.

Here’s an example:

``` ruby class MyApp < Happy::Controller # You can provide a block that contains method definitions. # helpers do def some_helper ‘something useful’ end end

# Alternatively, you can provide a module that contains your # helper methods # helpers MyHelpers

def route # home.erb contains calls to helper methods render ‘home.erb’ end end ```

Serving responses explicitly

You will have noticed by now that if a path block (or the route method itself) returns a simple string, it will be used for the response body. However, you can also serve responses explicitly using the serve! method. Example:

ruby class MyApp < Happy::Controller def route serve! 'my response', :content_type => 'text/plain' end end

Note that calling serve! will finish processing of the current request.

Passing control over the request to another controller or Rack app

Happy allows you to modularize your application into several separate controller classes. For example, you could put your admin backend’s code into a separate controller and then invoke it within the /admin path. For this, you would use the run command. Kinda like this:

``` ruby class MyAdminController < Happy::Controller def route on ‘users’ do # … # do some user admin stuff here end

on 'articles' do
  # ...
  # do some articles admin stuff here

render 'admin/home.erb'   end end

class MyApp < Happy::Controller def route on ‘admin’ do run MyAdminController end

render 'home.erb'   end end ```

Yup, this also means that you can build reusable controllers that you can distribute within gems for other Happy developers to use.

Permission Managament

Setting and querying permissions

Happy contains a light-weight run-time permission management system powered by the Allowance gem. Using the can object, you can declare (and later query) permissions at runtime.


``` ruby class MyApp < Happy::Controller def setup_permissions if current_user # Logged in users can submit new stuff can.submit!

  # But only admin users can edit and delete it.
  if current_user.is_admin?
end   end

def route setup_permissions

on 'submit' do
  if can.submit?
    render 'submit.erb'
    redirect! '/login'

# Paths are defined dynamically, so the following is possible, too:
if can.edit?
  on('edit') { render 'edit.erb' }

if can.delete?
  on('delete') { render 'delete.erb' }

render 'home.erb'   end

def current_user # …a method returning the current user. end end ```

Permissions for specific objects


ActiveModel integration


Controller configuration


Happy Recipes

Writing & Reading Session Data


Setting & Reading Cookies


Using HAML (and other view engines) in Happy


Serving assets (stylesheets, JavaScript files etc.)




Dealing with users and authentication


Using ResourceController


Using ActiveModelResourceController


Authenticating against Twitter, Facebook etc. using OmniAuth


Handling image uploads using DragonFly