Skip to content

Instantly share code, notes, and snippets.

@halfbyte
Created May 28, 2012 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halfbyte/2820063 to your computer and use it in GitHub Desktop.
Save halfbyte/2820063 to your computer and use it in GitHub Desktop.
A deserializer to initialize Backbone Collections from HTML.
<ul class="books">
<li>
<h3>Practical Arduino</h3>
<dl class="metadata">
<dt>ISBN:</dt>
<dd class="isbn">978foobar</dd>
<dt>Authors</dt>
<dd class="creator">Jonathan Oxer, Hugh Blemings</dd>
<dt>Created:</dt>
<dd class="created-at" data-date="2011-01-01">January 1st, 2011</dd>
</dl>
<p class="description">
Create your own Arduino-based designs, gain in-depth knowledge of the architecture of Arduino, and learn the user-friendly Arduino language all in the context of practical projects that you can build yourself at home. Get hands-on experience using a variety of projects and recipes for everything from home automation to test equipment. Arduino has taken off as an incredibly popular building block among ubicomp (ubiquitous computing) enthusiasts, robotics hobbyists, and DIY home automation developers. Authors Jonathan Oxer and Hugh Blemings provide detailed instructions for building a wide range of both practical and fun Arduino-related projects, covering areas such as hobbies, automotive, communications, home automation, and instrumentation. * Take Arduino beyond "blink" to a wide variety of projects from simple to challenging * Hands-on recipes for everything from home automation to interfacing with your car engine management system * Explanations of techniques and references to handy resources for ubiquitous computing projects Supplementary material includes a circuit schematic reference, introductions to a range of electronic engineering principles and general hints & tips. These combine with the projects themselves to make Practical Arduino: Cool Projects for Open Source Hardware an invaluable reference for Arduino users of all levels. You'll learn a wide variety of techniques that can be applied to your own projects. What you'll learn * Communication with serial devices including RFID readers, temperature sensors, and GPS modules * Connecting Arduino to Ethernet and WiFi networks * Adding synthesized speech to Arduino * Linking Arduino to web services * Decoding data streams from commercial wireless devices * How to make DIY prototyping shields for only a couple of dollars Who this book is for This book is for hobbyists and developers interested in physical computing using a low-cost, easy-to-learn platform. Table of Contents * Introduction * Appliance Remote Control * Time-Lapse Camera Controller * Virtual USB Keyboard * PS/2 Keyboard or Mouse Input * Security/Automation Sensors * Online Thermometer * Touch Control Panel * Speech Synthesizer * Water Flow Gauge * Oscilloscope/Logic Analyzer * Water Tank Depth Sensor * Weather Station Receiver * RFID Access Control System * Vehicle Telemetry Platform * Resources
</p>
</li>
</ul>
window.BackboneExt ?= {}
# Polyfill for Object.getPrototypeOf to play nice with opera.
# Not sure I should be doing this, but anyway
if typeof Object.getPrototypeOf isnt "function"
if typeof "test".__proto__ is "object"
Object.getPrototypeOf = (object) ->
return object.__proto__
else
Object.getPrototypeOf = (object) ->
# May break if the constructor has been tampered with
return object.constructor.prototype
# Deserializing list like html structures to backbone collection compatible json data
# You can either Subclass Deserializer or init with option hash to overwrite.
# Configuration
# root: A selector spec for the root element.
# iterate: A selector spec for an iterator element (can be as simple as div or li)
# selectors: A hash that describes the deserialization of one model instance
# the key will be the attribute name
# the value can be
# a string: will be used as a selector, value of the attribute will be the inner html
# a hash:
# selector: as above
# attribute: if you want to read from an attribute instead of the tag contents
# processors: an array of post processor names that allow you to re-transform contents
# they are defined in the hash processors in the deserializer class. the constructor
# should be clever enough to copy and merge superclass constructors, so you can
# add your own in your own subclass. (make sure you call super on your constructor, tho)
# currently available:
# 'strip' - analoguous to ruby's String#strip this strips whitespace at beginning and end using a simple regex. Good for longer texts.
#
# returns a json structure that can be used to do a backbone.js collection#reset
class window.BackboneExt.Deserializer
selectors: {}
root: null
iterate: null
constructor: (opts={}) ->
_(this).extend(opts)
console.log(Object.getPrototypeOf(Object.getPrototypeOf(this)), typeof(Object.getPrototypeOf(Object.getPrototypeOf(this))))
# ugly bit of code to copy over processors from base class when superizing
if desi = Object.getPrototypeOf(Object.getPrototypeOf(this)) and typeof(desi) == 'deserializer'
@processors = _(desi.processors).extend(@processors)
deserialize: ->
root = $(@root)
collectionData = []
$(@iterate, root).each (i, element) =>
collectionData.push @deserializeSingleElement($(element))
# and finally: stuff the data into the backbone collection
collectionData
deserializeSingleElement: (block) =>
modelData = {}
console.log("selectors", @selectors)
_(@selectors).each (selectorSpec, name) =>
modelData[name] = @deserializeAttribute(block, selectorSpec)
modelData
selector: (selectorSpec) ->
return selectorSpec unless _(selectorSpec).isObject()
selectorSpec.selector
processorList: (selectorSpec) ->
return null unless _(selectorSpec).isObject()
return selectorSpec['processors'] if _(selectorSpec).isArray()
[selectorSpec['processors']]
attribute: (selectorSpec) ->
return null unless _(selectorSpec).isObject()
selectorSpec['attribute']
deserializeAttribute: (block, selectorSpec) =>
@processAll @extract(block, @selector(selectorSpec), @attribute(selectorSpec)), @processorList(selectorSpec)
extract: (block, selector, attribute) ->
if attribute
$(selector, $(block)).attr(attribute)
else
$(selector, $(block)).html()
processAll: (data, processors = []) =>
for processor in processors
data = @process(data, processor)
data
process: (data, processor) =>
if @processors[processor] then @processors[processor](data) else data
# strips whitespace at beginning and end of string
processors:
strip: (input) ->
return unless input?
input.replace(/^\s*(.*?)\s*$/, '$1')
books = new App.models.BooksCollection()
ds = new BackboneExt.Deserializer
root: 'ul.books'
iterate: 'li'
selectors:
title: 'h3'
isbn: '.metadata .isbn'
creator: '.metadata .creator'
description:
selector: '.description'
processors: 'strip'
created_at:
selector: '.metadata .created-at'
attribute: 'data-date'
books.reset ds.deserialize()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment