Giter Club home page Giter Club logo

bldr's Introduction

Build Status

Bldr

Bldr is a minimalist templating DSL that provides a simple syntax for generating json documents from ruby objects. Bldr supports Sinatra and Rails 3.2.

Bldr enables to quickly generate json documents from ruby with a simple and intuitive DSL.

# app/views/posts/index.json.bldr

collection @posts do |post|
  attributes :title, :body, :created_at, :slug
  
  object :author => post.author do |author|
    attribute(:name) { author.display_name }
  end

  collection :comments => post.comments do |comment|
    attribute :spamminess
    attribute :created_at
    attribute(:body) do
      xss_filter(comment.body)
    end
  end
end

This would output the following json document:

[
  {
    "title": "Some title",
    "body": "blah blah",
    "slug": "some-title",
    "created_at": "2013-04-11T15:46:17-07:00",
    "author": {
      "name": "Joe Author"
    },
    "comments": [
      {
        "spamminess": 1.0,
        "created_at": "2013-04-11T15:46:17-07:00",
        "body": "a comment"
      }
    ]
  }
]

Usage

Bldr is a very concise DSL, containing only four core methods:

  • object
  • collection
  • attribute
  • attributes

These four methods provide a great deal of power and flexibility in describing json responses.

Why

If you're building an API, Model#to_json just doesn't cut it. Besides the JSON representation of your models arguably being a presentation concern, trying to cram all of this logic into an #as_json method quickly turns into pure chaos.

There are other json templating libraries available such as rabl or json_builder. Bldr is in the same vein as these libraries, but with a simpler synxtax.

Usage & Examples

See Examples on the wiki for documentation and usage examples.

Installation

In your gemfile:

gem 'bldr'

Configuration

No additional configuration is required for rails applications.

For sinatra apps, dependening on whether you're using a modular or classic application style, do one of the following:

# 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

Deprecations & Breaking Changes

0.7.0: current_object deprecation

The use of current_object is now deprecated. Instead of referencing current_object in bldr templates use block variables in object and collection methods:

# OLD (deprecated)
collection :people => people do
  attribute(:name) { current_object.name }
end

# NEW
collection :people => people do |person|
  attribute(:name) { person.name }
end

Make use of block variables the same way for the object method:

# OLD (deprecated)
object :person => person do
  attributes :name, :age

  person = current_object
  object :address => person.address do
    # current_object here would be assigned to person.address
    attribute(:zip) { current_object.zip_code }
    attribute(:address_title) { person.display_name }
  end
end

# NEW
object :person => person do |person|
  attributes :name, :age

  object :adress => person.address do |address|
    attribute(:zip) { address.zip_code }
    attribute(:address_title) { person.display_name }
  end
end

0.7.0: attribute method breaking change

One of the forms of the attribute method has changed in the 0.7.0 release. Previously, using the dynamic block form of attribute, if you did not pass in a block variable, the block would be eval'd in context of the current_object. This behavior fails the "principle of least surprise" test.

0.7.0 changes this behavior by simply executing the block in context of Bldr::Node, which provides access to instance variables and locals available in that context.

# OLD
object :person => person do
  attribute(:name) { display_name } # equivalent to doing attribute(:name) { |person| person.display_name }
end

# NEW
object :person => @person do
  attribute(:name) { @person.display_name }
end

See 941608e and d0bfbd8 for more info.

Editor Syntax Support

Vim

Add this line to your .vimrc:

au BufRead,BufNewFile *.bldr set filetype=ruby

Emacs

Add this to your ~/.emacs.d/init.el:

(add-to-list 'auto-mode-alist '("\\.bldr$" . ruby-mode))

TODO

  • XML support

Acknowledgements

  • RABL - Inspiration
  • Tilt - Mega awesome templating goodness

Contributors

  • Ian Hunter (@ihunter)
  • Justin Smestad (@jsmestad)
  • Adam LaFave (@lafave)

Copyright

Copyright (c) 2011-2013 Alex Sharp. See the MIT-LICENSE file for full copyright information.

bldr's People

Contributors

ajsharp avatar anveo avatar ian avatar jsmestad avatar lafave avatar zk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

bldr's Issues

Return empty value when specified in bldr

Using this example as a way to get it working properly. If I do not do user.build_profile or Profile.new, the payload returned will not have a 'profile': {...} object if user.profile is nil.

object :user => user do
  .....
  object :profile => (user.profile || user.build_profile) do
    attributes :biography, :picture
  end
end

Support cleaner syntax for nested collection properties

Currently, to perform operations on nested collections, we provide the current_object method:

collection :posts do
  attributes :title, :body

  collection :comments => current_object.comments do
    attributes :body, :author, :website
  end
end

I would like to support a clean syntax for performing these operations, maybe something like the following:

collection :posts do
  attributes :title, :body

  collection :comments => :comments do
    attributes :body, :author, :website
  end
end

And even:

collection :posts do
  attributes :title, :body

  collection :comments do
    attributes :body, :author, :website
  end
end

nil template's blow up

This happens when the template renders nothing at all. The object method will return nil, and then we try to call #result on nil, instead of a Bldr::Template instance.

Backtrace line numbers get messed up with templates

The line number frequently is off by two to the nearest seemingly matching line.

app/views/api/account/show.json.bldr:31:in `block (4 levels) in singletonclass'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:158:in `instance_eval'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:158:in `attribute'
app/views/api/account/show.json.bldr:31:in `block (3 levels) in singletonclass'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:28:in `instance_eval'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:28:in `initialize'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:75:in `new'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:75:in `object'
app/views/api/account/show.json.bldr:13:in `block (2 levels) in singletonclass'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:28:in `instance_eval'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:28:in `initialize'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:75:in `new'
[GEM_ROOT]/gems/bldr-0.5.3/lib/bldr/node.rb:75:in `object'
app/views/api/account/show.json.bldr:3:in `block in singletonclass'
:
:
app/views/api/account/show.json.bldr:65534:in `__tilt_14729920'

bldr call with top level collection node returns array

(rdb:1) bldr :'account/groups', :locals => {:groups => current_user.groups}
[#<Group _id: 4e67ad0f2249c75c2900003d, _type: nil, name: "schools", members: ["vt"]>]

I believe this to be because there is no to_json call for a top level collection node. Will submit PR.

Better partial support for rails

Currently the Rails lookup path is not supported, so you have to specify the full path to the template like so:

object(@person) do
  template "app/views/people/_person"
end

You should be able to simply specify template "person"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.