Giter VIP home page Giter VIP logo

asbestos's Introduction

Asbestos

Template handler for Rails that allows you to use a subset of XML Builder markup to produce JSON.

Take, for instance, a common "show.xml.builder" template:

xml.instruct!
xml.category(:private => false) do
  xml.name @category.name
  xml.parent do
    xml.id @category.parent_id
    xml.name @category.parent.name
  end
end

If you copied that to "show.json.asbestos", you would get:

{"category": {
  "private": "false",
  "name": "Science & Technology",
  "parent": {
    "id": 1,
    "name": "Religion"
  }
}}

But of course, you don't want to duplicate your builder template in another file, so we'll handle this in the controller:

def show
  respond_to do |wants|
    wants.xml
    wants.json {
      # takes the "show.xml.builder" template and renders it to JSON
      render_json_from_xml
    }
  end
end

With this method there's no need for a special template file for JSON. Asbestos is designed to use existing XML Builder templates.

How does it work?

The xml variable in your normal builder templates is the XML Builder object. When you call methods on this object, it turns that into XML nodes and appends everything to a string, which is later returned as the result of rendering.

This plugin provides Asbestos::Builder, which tries to mimic the behavior of the XML Builder while saving all the data to a big nested ruby hash. In the end, to_json is called on it.

Aggregates and ignores (important!)

Problems start when you have Builder templates that render collections, like in index actions:

xml.instruct!
for category in @categories
  xml.category do
    # ...
  end
end

There is a ruby loop in there, so if there are multiple categories the resulting JSON would have just one. This is because the same "category" field in the JSON hash would keep getting re-written by the next iteration. Asbestos::Builder is, unfortunately, not aware about any loops in your template code.

The solution is to indicate explicitly which keys you want aggregated:

render_json_from_xml :aggregate => ['category']

Now, what would previously create a "category" key will get aggregated under a "categories" array, instead:

{ "categories": [ ... ] }

Sometimes, most often with root elements, you want a key ignored. You can specify which occurrences to ignore:

render_json_from_xml :ignore => ['category']

asbestos's People

Contributors

davidhq avatar mislav avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

etrepat

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.