Meet the StatefulWidget! (Part 1)
Hey, great, you decided to dive into Apotomo. Most people didn’t regret that, so far. For Will, Apotomo is “what was missing in my two years of study of Ruby on Rails”, for Andy “it’s like a breath of fresh air for rails”, and for Markus, it’s just “sexy”.

In this tutorial we’re going to model and implement a small todo application, namely dumdidoo, which saves and displays things you have to do.
1 It’s on github, so go and get it. Be sure to change to the 0.1 tag, so you’re at the very beginning of our exciting way.
$ git clone git://github.com/apotonick/dumdidoo.git $ cd dumdidoo/ $ git submodule init $ git submodule update $ script/server
When browsing to http://localhost:3000/dashboard you see the raw view of the #index action in the DashboardController.
2Luckily, I already provide you with some Todo model and random items in the database. What about some list widget to show the items?
$ script/generate widget item_list display --haml create app/cells/ create app/cells/item_list create test/widgets create app/cells/item_list.rb create app/cells/item_list/display.html.haml create test/widgets/item_list_test.rb
Just telling the widget generator to create things for me. It spits out the widget class in app/cells/item_list.rb and a bare view for the display state.
In Apotomo a widget is like a controller in Rails, and a state is similar to an action. The standard state of a widget is usually #display, that’s somehow matching to the index action in a controller.
So if you look into the widget class and view files you’ll see they look like good old controllers!
3To plug the widget into a page we have to work in the controller.
1 2 3 4 5 6 7 8 9 | class DashboardController < ApplicationController include Apotomo::ControllerMethods def index use_widgets do |root| root << widget(:item_list, 'dashboard_list') end end end |
In Apotomo, widgets are organized in a tree. The #use_widgets method yields this ominous root node, and we attach a widget of type item_list to it, identified by ‘dashboard_list‘.
We need the id to render that widget.
app/views/dashboard/index.html.erb
<h2>Dashboard</h2> <%= render_widget 'dashboard_list' %>
Ok, so we can call #render_widget in controller views to render widgets that we defined earlier with #use_widgets. Widgets, widgets, widgets…
When viewing the page, the widget’s default view appears within the controller’s view. That looks trivial, but, hey, you implemented your first widget! Congratulations!
4Now it’s time to extend this item_list widget and add functionality to list the items.
1 2 3 4 5 6 | class ItemList < Apotomo::StatefulWidget def display @items = Todo.find :all render end end |
app/cells/item_list.rb
This will collect all the Todo items and push ‘em to an instance variable of our widget.
The render call without any arguments just looks for the corresponding view in app/cells/item_list/ (which is named after the state). In our case, it will find app/cells/item_list/display.html.haml.
Note that you could also have erb views, or builder, or whatever you prefer.
%h3 Things
%ul
- @items.each do |item|
%li
= item.textapp/cells/item_list/display.html.haml
Widget views can access instance variables from its widget instance, just as you know that from ordinary controllers.
When browsing back to the page, we see the list of all Todo items!
Wow! You just learned how to implement encapsulated, reuseable components, and we’re at tag 0.3, yet.
5I was drunk yesterday. Today, I’m tired. I will stop here. Did it take you 12 minutes? No? Do you have questions already? Feel free to use the comments below.
Well, tomorrow we’re gonna extend the list, so it is pageable. We’re gonna use will_paginate for that and on top of that we’ll get AJAX paging. Exciting!

