Bldr
Bldr is a minimalist templating library that provides a simple DSL for generating json documents from ruby objects. It currently supports Sinatra out of the box -- Rails 3 support is planned for the near future.
If you would like to contribute, pull requests with specs are warmly accepted :)
Features
- Simple json templating DSL
- Uses Tilt's built-in rendering and template caching for better performance
Installation
There are two ways to use Bldr in your Sinatra app, depending on whether you are using Sinatra's classic or module application style:
# Method 1: Classic style
require 'sinatra/bldr'
get '/hello' do
bldr :hello
end
# Method 2: Modular style
require 'sinatra/bldr'
class MyApp < Sinatra::Base
register Sinatra::Bldr
end
Usage
In your sinatra endpoints/actions, use the bldr helper method to
render templates.
get "/posts" do
# ...
posts = Post.all
bldr :'template.json', {}, {:posts => posts}
end
# views/template.json.bldr
collection :posts => posts do
attributes :title
attribute :comment_count { |post| post.comments.count }
collection :comments => current_object.comments do
attributes :body, :author, :email
end
end
Examples
Rendering a simple list of attributes
object :post => post do
attributes :title, :body
end
Output:
{
"post": {
"title": "my title",
"body": "..."
}
}
Dynamic attributes
object :post => post do
attribute :comment_count do |post|
post.comments.count
end
end
Output:
{
"post": {
"comment_count": 1
}
}
Attribute aliases
object :post => post do
attributes :title, :body
object :author => post. do
attribute :surname => :last_name
end
end
Output:
{
"post": {
"title": "my title",
"body": "...",
"author": {
"surname": "Doe"
}
}
}
Nested objects
object :post => post do
attributes :title, :body
object :author => post. do
attributes :first_name, :last_name, :email
attribute(:full_name) { || "#{author.first_name} #{author.last_name}" }
end
end
Output:
{
"post": {
"title": "my title",
"body": "...",
"author": {
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]",
"full_name": "John Doe"
}
}
}
Root-level attributes
get '/redirector' do
url = params['redirect_url']
bldr :'redirect.json', :locals => {:url => url}
end
# views/redirect.json.bldr
object do
attribute(:redirect_to) { url }
end
Output:
{"redirect_to": "http://example.org"}
Collections
All the examples above can be used inside a collection block. Here we assume a Post model which has many Comments. You might use the below code to render an action which returns a collection of posts, where each post has a collection of comments.
collection :posts => posts do
attributes :title
attribute :comment_count { |post| post.comments.count }
# current_object
collection :comments => current_object.comments do
attributes :body, :author_name, :author_email
end
end
Output:
{
"posts": [
{
"title": "my title",
"comment_count": 2,
"comments": [
{
"body": "...",
"author_name": "Comment Troll",
"email": "[email protected]"
},
{
"body": "...",
"author_name": "Uber Troll",
"email": "[email protected]"
}
]
}
]
}
When inside of a collection block, you can use the current_object
method to access the member of the collection currently being iterated
over. This allows you to do nested collections, as in the example above.
Templates
It is recommended to name your templates with the content type extension before
the .bldr extension. For example: my_template.json.bldr.
The templates themselves are just plain ruby code. They are evaluated in the context of a
Bldr::Node instance, which provides the bldr DSL. The DSL is comprised
primarily of 3 simple methods:
object- Creates an objectcollection- Iterates over a collection of objectsattributes- Add attributes to the current object.
Local Variables
You may pass local variables from your sinatra actions to bldr templates
by passing the bldr method a :locals hash, like so:
get '/posts' do
posts = Post.all.recent
bldr :'posts/index.json', :locals => {:posts => posts}
end
Editor Syntax Support
To get proper syntax highlighting in vim, add this line to your .vimrc:
au BufRead,BufNewFile *.bldr set filetype=ruby
TODO
- Rails 3 support
- Replace current_object with a block param for collection methods
- XML support
Acknowledgements
Contributors
- Ian Hunter (@ihunter)
Copyright
Copyright (c) 2011 Alex Sharp. See the MIT-LICENSE file for full copyright information.
