I have a similar situation, I program the business logic and my daughter programs the HTML and CSS. So, inspired by hyperstream, and since CycleJS uses the Snabbdom virtual DOM library, I wrote snabbdom-template. This module inserts dynamic data by targeting standard HTML tag names and other CSS selectors and replacing mocked values.
Here's a simplified workflow example: first I program the business logic and core HTML:
main.js
...
function main(sources) {
const data$ = sources.incomingdata
const vdom$ = data$
.map(list => div([
div('#message', 'Ready.'),
ul('#mapme', list.map(item => li(item)))
])
)
return {
DOM: vdom$
}
}
...
Or—if using Babel and snabbdom-jsx:
...
const vdom$ = data$
.map(list =>
<div>
<div id="message">Ready.</div>
<ul id="mapme">
{list.map(item => <li>{item}</li>)}
</ul>
</div>
)
...
Then I tell my daughter I need a message div
with id
set to "message" followed by an unordered list with an id
that is set to "mapme". Let's say she provides a file containing:
list.html
<div>
<div id="message">Message goes here.</div>
<ul id="mapme">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
Then I change my main.js to:
...
const snabbdom_template = require('snabbdom-template')
const fs = require('fs')
const template = fs.readFileSync('list.html', 'utf-8')
function main(sources) {
const data$ = sources.incomingdata
const vdom$ = data$
.map(list => snabbdom_template(template, {
'div#message': 'Ready.',
'#mapme': {_map: {'li': list}}
}))
return {
DOM: vdom$
}
}
...
When I bundle main.js using browserify I add the brfs transform to hardcode the templates into the bundle:
browserify -t brfs main.js > bundle.js
Now she can make updates to list.html—as long as core HTML and ID's or classes used to target data remain—and the only thing I need to do is rebundle.