Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

update readme

  • Loading branch information...
commit 8f3475efe0c00377ff88cf372a5ad393667895df 1 parent 7106af7
▟ ▖▟ ▖ authored

Showing 1 changed file with 114 additions and 69 deletions. Show diff stats Hide diff stats

  1. +114 69 README.md
183 README.md
Source Rendered
@@ -16,96 +16,141 @@ It works in browsers too.
16 16 $ npm install dynamictemplate
17 17 ```
18 18
19   -## Documentation
  19 +## Solutions
20 20
21   -### Writing templates
  21 +if any of this problems are familiar to you, you should skip the tl;dr and read the documentation:
22 22
23   -```coffeescript
24   -tpl = new Template schema:'xml', doctype:off, pretty:off, encoding:'utf-8', end:on, -> # default settings
25   - @$tag 'xml', ->
26   - @$tag 'child', "content"
27   -```
  23 + * building a real-time user interface
  24 + * updating large chunks of DOM
  25 + * manipulating nested DOM structures
  26 + * working with a designer
  27 + * isomorph code
  28 + * html streaming
28 29
29   -This actually allows you to write real templates with [asyncxml](https://github.com/dodo/node-asyncxml).
30   -Normally, asyncxml just gives you the ability to write asynchronous XML-generating code.
31 30
32   -### How to write tags
  31 +## TL;DR
33 32
34   -Maybe the main difference to some other template engines is that all the tags are asynchronous.
35   -This has the side effect that every tag has to be closed manually. As this can get a little bit anoying when you write very large templates, I added a little shortcut which invokes the end for you at the and of the child scope:
  33 +Convenient DOM manipulation in template style for real-time user interfaces.
36 34
37   -```coffeescript
38   -@html ->
39   - @body("content").end()
40   - @end()
  35 + * async & dynamic → changeable even after template was rendered
  36 + * pure javascript with a hugh event based api → modular & extendable
  37 + * runs on server and browser side
  38 + * different approach than dom: don't get your elements out of the black box. keep only those which you need.
  39 + * minimalistic (all the other stuff is hidden in modules :P)
41 40
42   -# is the exactly same as
  41 +## Documentation
43 42
44   -@$html ->
45   - @$body "content"
46   -```
47 43
48   -Just add a dollar sign (`$`) in front of the tag method and it acts a little bit more synchronous again.
  44 +Writing and maintaining user interfaces can be hard.
49 45
50   -### Plugins
  46 +Δt is this new event based way of writing and maintaining user interfaces in javascript.
51 47
52   - * [Δt compiler](https://github.com/dodo/node-dt-compiler) - this compiles static HTML to template masks.
53   - * [Δt stream adapter](https://github.com/dodo/node-dt-stream) - this lets you use node's beloved Stream to get static HTML from the templates.
54   - * [Δt jquery adapter](https://github.com/dodo/node-dt-jquery) - this lets you insert the template into dom with the help of [jQuery](http://jquery.com/).
55   - * [Δt list](https://github.com/dodo/node-dt-list) - this gives all you need to handle an ordered list of tags.
  48 +DOM has growen old. It's one of the legacies from the last millenium each browser caries with it.
  49 +Like nearly every browser API, the DOM has an ,opinionated, ugly interface to work with:
  50 +the fastest way to fill a DOM is `innerHTML`, the way to get stuff back once its parsed is by querying it, the convenient way to manipulate it is by changing, creating and removing nodes. so WTF.
  51 +These are the reasons why jquery and mootools are still the most used js libraries. but seriously, have you every tried to write an large userinterface with it?
56 52
57   -### The dynamic part
  53 +So let's try something new:
58 54
59   - TODO i couldnt find the time to build an example
60   - that's works best with dynamictemplate, so please stand by.
  55 +``´javascript
  56 +var Template = require('dynamictemplate').Template;
  57 +var tpl = new Template({schema:'html5'}, function () {
  58 + this.div(function () {
  59 + this.text("hello world");
  60 + this.end();
  61 + });
  62 +});
  63 +```
61 64
  65 +```coffeescript
  66 +{ Template } = require 'dynamictemplate'
  67 +tpl = new Template schema:'html5', ->
  68 + @div ->
  69 + @text "hello world"
  70 + @end()
  71 +```
62 72
63   -#### Just FYI
  73 +That was easy. We created a new template instance and with it a new `<div>` element with some text and closed it.
  74 +
  75 +Let's try something more complex:
  76 +
  77 +```javascipt
  78 +function template(view) {
  79 + return new Template({schema:5}, function () {
  80 + this.$div(function () {
  81 + view.on('set title', this.text);
  82 + });
  83 + this.$a(function () {
  84 + this.text("back");
  85 + view.on('navigate', function (url) {
  86 + this.attr('href', url);
  87 + }.bind(this));
  88 + });
  89 + });
  90 +}
  91 +```
64 92
65   -This is not finished yet.
66   -But please, make yourself comfortable, take a cookie and **start contributing**!
  93 +```coffeescript
  94 +template = (view) ->
  95 + new Template schema:'5', ->
  96 + @$div ->
  97 + view.on('set title', @text)
  98 + @$a href:'/', ->
  99 + @text "back"
  100 + view.on('navigate', (url) => @attr(href:url))
  101 +```
67 102
  103 +Ok. let me explain: we created a div which text changes on every 'set title' event the view object will emit and we created an anchor element which `href` attribute will change on every 'navigate' event. that's it.
  104 +note that the div element will be empty at the beginning.
  105 +if you play a while with it you might hit some known problems from nodejs: flow control. how convenient that it seems that nearly everybody has writting her own library. **Use your own flow control library!**
  106 +if you don't know any, [async]() might be a good fit.
  107 +
  108 +if you already started playing around with it you might found out that nothing is happing. Its because each `this.div` call doesn't produce a div tag but a `new` and a `add` event with the object representation of the div tag as argument. Doesn't sound very useful to you? how about you use one of the many adapters? An Adapter is little modules that listens for these events and act accordingly on its domain. This means if you use dt-jquery or dt-dom it will create a dom element. in the case of dt-stream it will create a nodejs stream instance that emits html strings as data.
  109 +
  110 +```javascript
  111 +var jqueryify = require('dt-jquery');
  112 +tpl = jqueryify(template(view));
  113 +// or
  114 +var domify = require('dt-dom');
  115 +tpl = domify(template(view));
  116 +// or
  117 +var streamify = require('dt-stream');
  118 +tpl = streamify(template(view));
  119 +```
  120 +For more information on the events look at [asyncxml]() which generates them.
68 121
69   -## Example
  122 +Let's have another example:
70 123
71   -If you are familiar with [coffeekup](http://coffeekup.org), you should recognize this:
  124 +```javascript
  125 +```
72 126
73 127 ```coffeescript
74   -stringify = (func) -> func.toString()
75   -shoutify = (s) -> s.toUpperCase() + "!"
76   -template = ({title, desc, path, user, max}) ->
77   - new Template schema:5, doctype:on, ->
78   - @$html ->
79   - @$head ->
80   - @$meta charset:'utf-8'
81   - @$title "#{title or 'Untitled'} | My awesome website"
82   - if desc?
83   - @$meta name:'description', content:desc
84   - @$link rel:'stylesheet', href:'/stylesheets/app.css'
85   - @$script src:'/javascripts/jquery.js'
86   - @$script stringify -> # browser code
87   - $ ->
88   - alert "Alerts are so annoying..."
89   - @$body ->
90   - @$header ->
91   - @$h1 title or 'Untitled'
92   - @$nav ->
93   - @$ul ->
94   - unless path is '/'
95   - @$li -> @$a href:'/', "Home"
96   - @$li -> @$a href:'/chunky', "Bacon!"
97   - switch user.role
98   - when 'owner', 'admin'
99   - @$li -> @$a href:'/admin', "Secret Stuff"
100   - when 'vip'
101   - @$li -> @$a href:'/vip', "Exclusive Stuff"
102   - else
103   - @$li -> @$a href:'/commoners', "Just Stuff"
104   - @$section ->
105   - @$h2 "Let's count to #{max}:"
106   - @$p "#{i}" for i in [1..max]
107   - @$footer ->
108   - @$p shoutify "bye"
  128 +template = (view) ->
  129 + new Template schema:5, ->
  130 + @$div class:'user', ->
  131 + name = @$a(class:'name')
  132 + about = @$span(class:'about')
  133 + setUser = (user) ->
  134 + name.text(user.name)
  135 + name.attr(href:user.url)
  136 + abouot.text(user.description)
  137 + view.on('set user', setUser)
  138 + setUser(view.currentUser)
  139 +
109 140 ```
110 141
  142 +Alright. here is the trick: unlike the DOM where you normally have to query most elements, which feels mostly like grabbing into a black box with spiders and snakes, with Δt you already created the tags, so store them in variables, scopes and/or closures when you need them.
  143 +
  144 +For more information look at the various examples and plugins supporting Δt:
  145 +
  146 +### Plugins
  147 +
  148 + * [Δt compiler](https://github.com/dodo/node-dt-compiler) - this compiles static HTML (like mockup files from a designer) to template masks.
  149 + * [Δt stream adapter](https://github.com/dodo/node-dt-stream) - this lets you use node's beloved Stream to get static HTML from the templates.
  150 + * [Δt jquery adapter](https://github.com/dodo/node-dt-jquery) - this lets you insert the template into dom with the help of [jQuery](http://jquery.com/).
  151 + * [Δt list](https://github.com/dodo/node-dt-list) - this gives all you need to handle an ordered list of tags.
  152 + * [Δt selector](https://github.com/dodo/node-dt-selector) - this gives you specific selected tags without modifing the template.
  153 +
  154 +
111 155 [![Build Status](https://secure.travis-ci.org/dodo/node-dynamictemplate.png)](http://travis-ci.org/dodo/node-dynamictemplate)
  156 +

0 comments on commit 8f3475e

Please sign in to comment.
Something went wrong with that request. Please try again.