Skip to content

Instantly share code, notes, and snippets.

@tonyfast
Last active August 29, 2015 14:16
Show Gist options
  • Select an option

  • Save tonyfast/bd0224ab50e3b056e4c4 to your computer and use it in GitHub Desktop.

Select an option

Save tonyfast/bd0224ab50e3b056e4c4 to your computer and use it in GitHub Desktop.
Efficiently Template structured data using YAML
<head>
<script src="//cdn.jsdelivr.net/g/d3js,riot@2.0(riot.min.js+compiler.min.js),coffeescript">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/3.2.6/js-yaml.min.js"></script>
<style>
@import "http://bootswatch.com/superhero/bootstrap.min.css";
</style>
</head>
<body>
<script id="manifest" type="text/yaml">
- heading: document
children:
- heading: HEAD
class:
- coarse
style:
- background-color: blue
children:
# If the first entry is a template then use a custom thing
- template:
- type: riot/tag
mount: main
- heading: Authors
type: array
id: Authors
content:
- heading: tonyfast
content: stuff
- heading: rebelyellow
content: stuff
- heading: lildirty
content: stuff
- heading: Title of the Article
type: text
content: |
Lorem Ipsum
id: abstract
- heading: BODY
class:
- coarse
children:
- heading: Section 1
type: text
content: |
Lorem Ipsums
- heading: Section 2
type: text
content: |
Lorem Ipsums
- heading: Section 3
type: text
content: |
Lorem Ipsums
- heading: Picture 1
type: image
content:
url: 'blank.jpg'
caption: Caption
- heading: Section 4
type: text
content: |
Lorem Ipsums
- heading: FOOTER
class:
- coarse
children:
- heading: References
type: array
content:
- type: link
content:
- type: article
- type: repository
</script>
<script>
;( function(){
data = jsyaml.load( d3.select('#manifest').html() )
})();
</script>
<script type="text/coffeescript">
data = jsyaml.load( d3.select('#manifest').html() )
templater = ( d, s, template )->
#{ make template and return default }
console.log 't', d,s,template
if template
riot_template( d,s, template[0]['mount'] )
else
#{ default template }
riot_template( d,s )
build = ( d, s ) ->
if d[0].hasOwnProperty( 'template')
templater d.slice(1), s, d[0]['template']
#{autofill( d, s)}
else
d.forEach (_d,i) ->
templater _d, s, _d.hasOwnProperty('template')
autofill( _d, s)
riot_template = (d, s, custom) ->
###
Default template views
d - data to mount to s-selection
custom is a custom riot selector
###
if not custom
template = {
text: () ->
riot.mountTo(s.node(), 'panel', d)
array: () ->
riot.mountTo(s.node(), 'media-list', d )
}
if template.hasOwnProperty( d['type'] )
template[d['type']]()
else
() -> console.log( d, 'is untyped' )
else
riot.mountTo(s.node(), custom, d)
autofill = ( d, s) ->
#{ autofill class, attr, and style from a yaml list }
if d.hasOwnProperty('class')
d['class'].forEach (c) ->
s.classed c, true
### Let Riot handle this now
if d.hasOwnProperty('id')
s.id = d['id']
###
if d.hasOwnProperty('style')
d['style'].forEach (d) ->
if typeof d == 'object'
s.style d3.keys(d)[0], d3.values(d)[0]
if d.hasOwnProperty('attr')
d['attr'].forEach (d) ->
if typeof d == 'object'
s.attr d3.keys(d)[0], d3.values(d)[0]
traverse = (a) ->
#{ array of child indices }
a.reduce (p,n,i) ->
console.log p
if (i == 0)
p[n]
else
p['children'][n]
, data
d3.select 'body'
.append 'div'
.classed 'container', true
.classed 'body', true
.selectAll '.coarse'
.data d3.range( data[0]['children'].length )
.call (s) ->
s.enter()
.append 'div'
.classed 'coarse', true
.each (i) ->
d3.select this
.call (s) ->
console.log 'c', s, data[0]['children'][i]['children']
build( data[0]['children'][i]['children'], s )
</script>
<script type="riot/tag">
<main>
<div class='t'>{article.heading}</div>
<div class='t'>{article.content}</div>
<ul class='t'>
<li each={author in authors.content}>{ author.heading }</li>
</ul>
this.authors = this['opts'][0]
this.article = this['opts'][1]
</main>
<panel>
<div class="panel panel-primary" id={this.opts.id}>
<div class="panel-heading">
{ this.opts.heading }
</div>
<div class="panel-body">
{ this.opts.content }
</div>
</div>
</panel>
<media-list>
<div class="panel panel-default">
<div class="panel-heading">
{ this.opts.heading }
</div>
<div class="panel-body">
<div class="media" each={item,i in this.opts.content} id={item.id} >
<div class="media-left media-middle">
<a href="#">
<img class="media-object" alt="...">
</a>
</div>
<div class="media-body">
<h4 class="media-heading">{item.heading}</h4>
{item.content}
</div>
</div>
</div>
</div>
</media-list>
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment