Skip to content


Subversion checkout URL

You can clone with
Download ZIP
HTML forms library for ruby
Fetching latest commit...
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



Forme is a HTML forms library for ruby with the following goals:

  1. Have no external dependencies

  2. Have a simple API

  3. Support forms both with and without related objects

  4. Allow compiling down to different types of output

Demo Site

A demo site is available at

Source Code

Source code is available on GitHub at

Basic Usage

Without an object, Forme is a simple form builder:

f =>'/foo', :method=>:post) # '<form action="/foo" method="post">'
f.input(:textarea, :value=>'foo', :name=>'bar') # '<textarea name="bar">foo</textarea>'
f.input(:text, :value=>'foo', :name=>'bar') # '<input name="bar" type="text" value="foo"/>'
f.close # '</form>'

With an object, Form#input calls forme_input on the obj with the form, field, and options, which should return a Forme::Input or Forme::Tag instance. Also, in Form#initialize, forme_config is called on object with the form if the object responds to it, allowing customization of the entire form based on the object.

f =
f.input(:field) # '<input id="obj_field" name="obj[field]" type="text" value="foo"/>'

If the object doesn't respond to forme_input, it falls back to creating text fields with the name and id set to the field name and the value set by calling the given method on the object.

f =[:foo])
f.input(:first) # '<input id="first" name="first" type="text" value="foo"/>'


Forme comes with a DSL:

Forme.form(:action=>'/foo') do |f|
  f.input(:text, :name=>'bar')
  f.tag(:fieldset) do
    f.input(:textarea, :name=>'baz')
# <form action="/foo">
#   <input name="bar" type="text"/>
#   <fieldset>
#     <textarea name="baz"></textarea>
#   </fieldset>
# </form>

You can wrap up multiple inputs with the :inputs method:

Forme.form(:action=>'/foo') do |f|
  f.inputs([[:text, {:name=>'bar'}], [:textarea, {:name=>'baz'}]])
# <form action="/foo">
#   <fieldset class="inputs">
#     <input name="bar" type="text"/>
#     <textarea name="baz"></textarea>
#   </fieldset>
# </form>

You can even do everything in a single method call:

  :inputs=>[[:text, {:name=>'bar'}], [:textarea, {:name=>'baz'}]])

Basic Design

Interally, Forme builds an abstract syntax tree of objects that represent the form. The abstract syntax tree goes through a series of transformations that convert it from high level abstract forms to low level abstract forms and finally to strings. Here are the main classes used by the library:


main object


high level abstract tag (a single Input could represent a select box with a bunch of options)


low level abstract tag representing an html tag (there would be a separate Tag for each option in a select box)

The group of objects that perform the transformations to the abstract syntax trees are known as transformers. Transformers use a functional style, and all use a call-based API, so you can use a Proc for any custom transformer.

Transformer Types


tags input/tag, returns string


takes input, returns tag


takes tag and input, returns version of tag with errors noted


takes tag and input, returns labeled version of tag


takes tag and input, returns wrapped version of tag


takes form, options hash, and block, wrapping block in a tag

The serializer is the base of the transformations. It turns Tag instances into strings. If it comes across an Input, it calls the formatter on the Input to turn it into a Tag, and then serializes that Tag. The formatter first converts the Input to a Tag, and then calls the error_handler if the :error option is set and the labeler if the :label option is set. Finally, it calls the wrapper to wrap the resulting tag before returning it.

The inputs_wrapper is called by Forme::Form#inputs and serves to wrap a bunch of related inputs.

Built-in Transformers

Forme ships with a bunch of built-in transformers that you can use:



returns HTML strings


returns HTML strings, formats dates and times in American format without timezones


returns plain text strings



turns Inputs into Tags


disables all resulting input tags


uses span tags for most values, good for printable versions of forms



modifies tag to add an error class and adds a span with the error message



uses implicit labels, where the tag is a child of the label tag


uses explicit labels with the for attribute, where tag is a sibling of the label tag



returns tag without wrapping


wraps tag in li tag


wraps tag in p tag


wraps tag in div tag


wraps tag in span tag


wraps tag in a tr tag with a td for the label and a td for the tag, useful for lining up inputs with the :explicit labeler without CSS



uses a fieldset to wrap inputs


uses an ol tag to wrap inputs, useful with :li wrapper


uses a div tag to wrap inputs


use both a fieldset and an ol tag to wrap inputs


uses a table tag to wrap inputs, useful with :trtd wrapper


You can associate a group of transformers into a configuration. This allows you to specify a single :config option when creating a Form and have it automatically set all the related transformers.

There are a few configurations supported by default:


All default transformers


fieldset_ol inputs_wrapper, li wrapper, explicit labeler

You can register and use your own configurations easily:

Forme.register_config(:mine, :wrapper=>:li, :inputs_wrapper=>:ol, :serializer=>:html_usa)>:mine)

If you want to, you can base your configuration on an existing configuration:

Forme.register_config(:yours, :base=>:mine, :inputs_wrapper=>:fieldset_ol)

You can mark a configuration as the default using:

Forme.default_config = :mine

Sequel Support

Forme ships with a Sequel plugin (use Sequel::Model.plugin :forme to enable), that makes Sequel::Model instances support the forme_config and forme_input methods and return customized inputs.

It deals with inputs based on database columns, virtual columns, and associations. It also handles nested associations using the subform method:

Forme.form(Album[1], :action=>'/foo') do |f|
  f.inputs([:name, :copies_sold, :tags]) do
    f.subform(:artist, :inputs=>[:name])
    f.subform(:tracks, :inputs=>[:number, :name])

For many_to_one associations, you can use the :as=>:radio option to use a series of radio buttons, and for one_to_many and many_to_many associations, you can use the :as=>:checkbox option to use a series of checkboxes. For one_to_many and many_to_many associations, you will probably want to use the association_pks plugin that ships with Sequel.

The Forme Sequel plugin also integerates with Sequel's validation reflection support with the validation_class_methods plugin that ships with Sequel. It will add pattern and maxlength attributes based on the format, numericality, and length validations.

Sinatra ERB Support

Forme ships with a Sinatra extension that you can get by require "forme/sinatra" and using helpers Forme::Sinatra::ERB in your Sinatra::Base subclass. It allows you to use the following API in your Sinatra ERB forms:

<% form(@obj, :action=>'/foo') do |f| %>
  <%= f.input(:field) %>
  <% f.tag(:fieldset) do %>
    <%= f.input(:field_two) %>
  <% end %>
<% end %>

In addition to ERB, it also works with Sinatra's Erubis support.

Other Similar Projects

All of these have external dependencies:

  1. Rails built-in helpers

  2. Formtastic

  3. simple_form

  4. padrino-helpers

Forme's API draws a lot of inspiration from both Formtastic and simple_form.


Jeremy Evans <>

Something went wrong with that request. Please try again.