Skip to content

Documentation & Examples

ajsharp edited this page Feb 25, 2013 · 10 revisions

Sections


Bldr has two top-level DSL methods -- object and collection. Inside a object or collection block, the attribute and attributes methods are how you build your json documents.

### Basic object with attributes
get '/post/:id' do
  bldr :show, :locals => {:post => Post.find(params['id']) }
end

# show.bldr
object :post => post do
  attributes :title, :body
end

# output
{ "post": {"title": "my title", "body": "..."} }
### Collections
get '/posts' do
  bldr :'posts/index.bldr', :locals => {:posts => Post.all}
end

# index.bldr
collection :posts => posts do
  attributes :body, :email
end

# output
{"posts": [{"body": "epic trollery", "email": "troll@trolling.edu"}]}
### "Empty" objects

If you need to build a json document whose structure doesn't rely on an object, you can do that too by not passing any args to the object method.

object do
  attribute :url,     "http://zaarly.com"
  attribute :success, true
end

# output
{"url": "http://zaarly.com", "success": true}
### Implicit object

If your locals keys are the same as how you want them named in the generated JSON, you can save a few keystrokes by taking advantage of Bldr's implicit object syntax. This works for both object and collection.

get '/post/:id' do
  bldr :show, :locals => { :post => Post.find(params['id']) }
end

# index.bldr
object :post do
  attributes :id, :body, :title
end

# output
{"post": {"id": 1, "body": "...", "title": "}}
### Dynamic attributes

The attribute method supports a block syntax. The block takes a single argument, which is the object currently being operated on.

object :post => post do
  attribute :comment_count do |post|
    post.comments.count
  end
end

# output
{ "post": {"comment_count": 1} }
### Deep object hierarchies

Bldr supports building arbitrarily deep object hierarchies. This is supported by both the object and collection methods.

get '/post/:id' do
  bldr :show, :locals => { :post => Post.find(params['id']) }
end

# show.bldr
object :post do |post|
  attributes :title

  object :author do
    attributes :name, :email
  end
end

# output
{ "post": {"title": "my title", "author": {"name": "John", "email": "john@doe.com"}} }

When nesting collections within each other, access individual items in a collection block by passing a block variable to the collection, as you would with any other enumberable method.

get '/posts' do
  bldr :index, :locals => { :posts => Post.all }
end

# index.bldr
collection :posts => posts do |post|
  attributes :title

  collection :comments => post.comments do |comment|
    attribute(:author) { comment.author.display_name }
    attribute :body
  end
end

# output
{"posts": [
  { "title": "my title", 
    "comments": [
      {"body": "...", "author": "Comment Troll"},
      {"body": "...", "author": "Uber Troll"}
    ]
  }
]}
### Attribute aliases

The attribute method allows aliasing attributes via a simple hash syntax. The key is the name of the aliased key you want to appear in the json document, and the value is the name of the object's method.

object :post => post do
  attributes :title, :body

  object :author => post.author do
    attribute :surname => :last_name
  end
end

# output
{ "post": {"title": "my title", "body": "...", "author": {"surname": "Doe"}} }
### Local Variables

Local variables are passed from sinatra actions to bldr templates by passing the bldr method a :locals hash.

get '/posts' do
  posts = Post.all

  bldr :'posts/index.json', :locals => {:posts => posts}
end
### Instance Variables

You can access instance variables set in your controller actions in your bldr templates:

get "/posts/:id" do
  @post = Post.find(params[:id])
  bldr :'posts/show.bldr'
end

# posts/show.bldr
object :post => @post do
  attributes :body, :title
  attribute(:comment_count) { @post.comments.count }
end
### Templates

The template method includes another template/partial into the current doc. When using Sinatra, the Sinatra.settings.view is used to determine default view path. This is usually app/views.

# Main view
object :post => post do
  attributes :title, :body
  template 'user', :locals => {:user => post.author}
end

# user view
object :user => user do
  attribute :name
end

# output
{ "post": {"title": "my title", "body": "...", "user": {"name": "John Doe"}} }
### Custom Handlers

Bldr supports the definition of custom handlers, based on the class of specific values in the result. You would make use of this to define how specific classes are rendered by Bldr at a global level.

For example, the BSON::ObjectId class defines to_json and as_json methods that produce a result like the following: {"$oid": "4e77a682364141ecf5000002"}. If you wanted to over-ride this default format, you could do so by defining a custom handler:

# place in a file that get's loaded before your application code
Bldr.handler BSON::ObjectId do |val|
  val.to_s # => "4e77a682364141ecf5000002"
end
Clone this wiki locally