We did a re-write of the nearby.lk data model library, and we decided to open source the core of it. It supports JSON or YAML data files, and parses them based on a specification (like a schema).
We did a re-write of the nearby.lk data model library, and we decided to open source the core of it. It supports JSON or YAML data files, and parses them based on a specification (like a schema).
The specification is a coffeescript class with a render function. The editor checks the input against the specification and uses the render function to show the parsed input. The editor can either work in YAML mode (plain YAML input) or form input mode (user fills up a form). It can handle quite complex data models.
Here's the editor accepting (and rendering a resume).
This is the class for the Resume example.
class Resume extends Base
@extend()
Set the type of the model.
type: 'Resume'
Define properties. The type of the property is determined based on the property parameters. It defaults to Value property.
@property 'name', {}
...
oneof
specifies that the property is one of the models specified.
@property 'address',
oneof: ['Null', 'Address']
This is a list of values. rows
and columns
are schema parameters for values.
@property 'statement',
list:
rows: 3
columns: 50
This property is a list of other models.
@property 'timeline',
list:
oneof: ['Experience', 'Education', 'Recognition']
defaultValues: -> {from: '2010', to: '2020'}
...
These are some private functions of the Resume model.
_education: ->
res = (e for e in @_values.timeline when e.type is 'Education')
res.sort (x, y) -> y._values.from - x._values.from
...
This is the template to render the output.
template: (self) ->
values = self._values
education = self._education()
experience = self._experience()
recognitions = self._recognitions()
@div ".resume", ->
@div ".row", ->
@div ".six.columns", ->
@div ".name", "#{values.name}"
@div ".role", "#{values.role}"
if values.website isnt ''
@div ".website", ->
@a href: "#{values.website}", "#{values.website}"
if values.address.type isnt 'Null'
@div ".three.columns.address", ->
values.address.weya this
...
New properties (e.g. image uploads) can be defined similarly.
On nearby.lk, we have local business information. Initially it was basic information like contact numbers, a small description, etc. Later, more details needed to be included. Also, the page structures differed based on the type of location. We didn't want to have the content in free flow. It's easier to make mistakes and not have uniform style with free text content. Also you can do a much better search with structured content.
nearby.lk is not yet running this re-written library. A little more work needs to be done to integrate this with the nearby search engine.
These samples show the classes for Resume example.
Mod.require 'Models.Editor', (Editor) ->
editor = new Editor
model: 'Resume' #Base model name
editor.render element,
width: width
height: height
onRendered
onRendered = ->
editor.yaml() #yaml edit mode
editor.structured() #structured edit mode
editor.resize #resize editor
width: width
height: height
editor.getModel() #return model object
#returns json object omiting default values
editor.getModel().getJSON()
#returns full json object
editor.getModel().getJSONFull()
editor.setJSON jsonObject #set json object content
Mod.require 'Models.Models', (Models) ->
ModelClass = Models.get 'Resume'
model = new ModelClass
#parse json object
results = ModelClass.parse jsonObject
#results.score = How maching it was [0..1]
#results.errors = List of errors when parsing
#results.value = model
#returns json object omiting default values
model.getJSON()
#returns full json object
model.getJSONFull()
model.render element
model.html() #returns html