/
index.html
216 lines (173 loc) · 7.39 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Fragment</title>
<link rel="stylesheet" href="examples/screen.css" type="text/css" media="screen">
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"
></script>
<script src="mustacho.js" type="text/javascript" charset="utf-8"></script>
<script src="showdown-dev.js" type="text/javascript" charset="utf-8"></script>
<script src="fragment.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
$(function(){
$('body').append(fragment('body', {
links: [
{href:"examples/basics.html", title:"Basics", desc:
"Covers most functionality"},
{href:"examples/blog/", title:"Blog", desc:
"A client side-only blog built with Fragment"},
{href:"examples/benchmark.html", title:"Benchmark"},
]
}));
});
</script>
</head>
<body>
<h1>Fragment</h1><!-- for SEO purposes -->
<div fragment="body:text/markdown">
Fragment is a sort of (browser) JavaScript templating toolkit.
A *fragment* is like a view, but is much more light-weight than
traditional templates. *Fragment templates* can be embedded in the
document (and other fragments) or live in separate files.
*Fragment templates* generate *fragments* which can be though of as
*instances of templates with local contexts*.
Each *fragment* is a regular jQuery object with some extra functionality, like
a local `context` (a javascript object which is exposed to the fragment Mustache
markup) and an `update` function which can be used to "redraw" the fragment if
the global or local context has changed.
You can grab the latest version from
[http://github.com/rsms/js-fragment](http://github.com/rsms/js-fragment)
## Introduction
Here's a simple fragment template:
<ul fragment="list">
{\{#links}}
<li><a href="{\{href}}">{\{title}}</a></li>
{\{/links}}
</ul>
Which we can create a new *fragment* instance of by calling the `fragment`
function and then add it to our document:
var frag = fragment('list', {
links: [
{href: "http://www.google.com/", title: "Google"},
{href: "http://www.bing.com/", title: "Bing"}
]
});
$('parent').append(frag);
Suppose the `parent` element was empty before, this is now what it contains:
<parent>
<ul class="list">
<li><a href="http://www.google.com/">Google</a></li>
<li><a href="http://www.bing.com/">Bing</a></li>
</ul>
</parent>
Now, let's change the context and update the fragment:
frag.context.links.push({ href: "http://yahoo.com/", title: "Yahoo!" });
frag.update();
The content is now updated to reflect the most recent context:
<parent>
<ul class="list">
<li><a href="http://www.google.com/">Google</a></li>
<li><a href="http://www.bing.com/">Bing</a></li>
<li><a href="http://yahoo.com/">Yahoo!</a></li>
</ul>
</parent>
### Including other fragments
Since *Fragment* is powered by [Mustache](http://mustache.github.com/)
we not only have markup and processing, but can also include other snippets,
called "partials".
Let's rewrite our list fragment and split up the list and the list item templates:
<ul fragment="bulleted-list">
{\{#links}}
{\{>list-item}}
{\{/links}}
</ul>
<ol fragment="numbered-list">
{\{#links}}
{\{>list-item}}
{\{/links}}
</ol>
<li fragment="list-item"><a href="{\{href}}">{\{title}}</a></li>
When creating a fragment out of the `bulleted-list` or `numbered-list` template,
`{\{>list-item}}` tells Mustache to include the `list-item` fragment template.
The result from `bulleted-list` would be the same as before (in the previous
examples). Partials enables us to re-use fragment templates and stay
[DRY](http://en.wikipedia.org/wiki/Don't_repeat_yourself).
### Loading remote fragment templates
*Fragment* supports loading of templates in remote locations. Let's consider our
previous list and list item templates. Let's move the `bulleted-list` template
to a separate file called `bulleted-list.html`:
<ul>
{\{#links}}
{\{>list-item}}
{\{/links}}
</ul>
We keep the `list-item` in our document during this example. Now, as loading
remote resources obviously requires I/O and we must wait for it to complete, we
invoke `fragment` with a callback function:
var context = {
links: [
{href: "http://www.google.com/", title: "Google"},
{href: "http://www.bing.com/", title: "Bing"}
]
};
fragment('bulleted-list.html', context, function(err, frag){
if (err) throw err;
$('parent').append(frag);
});
The `bulleted-list.html` is loaded and a template is created and cached for
later, and finally a fragment instance is created and passed as the second
argument to our callback. The first argument to callbacks are always an error
(or a false value if there was no error).
Remote templates can include other templates using the `{\{>name}}` construct
since they are evaluated in the same execution context, technically speaking.
## Examples
{{#links}}
- [{{title}}{{^title}}{{href}}{{/title}}]({{href}})
{{#desc}}-- {{desc}}{{/desc}}
{{/links}}
## API
Overview:
{root}.context = {}
{root}.fragment(id [,context] [,asHTML[, noProcessing]] [,callback]) -> frag
{root}.fragment.tagName = "frag"
{root}.fragment.classPrefix = ""
{root}.fragment.preprocessors = {}
{root}.fragment.template(id [,callback(err, Template)]) -> Template
{root}.fragment.template.attrName = "fragment"
{root}.fragment.Template() <constructor>
{root}.fragment.Template.prototype.id = <string>
{root}.fragment.Template.prototype.head = <string>
{root}.fragment.Template.prototype.body = <string>
{root}.fragment.Template.prototype.tail = <string>
{root}.fragment.Template.prototype.type = <string>
{root}.fragment.Template.prototype.classname = <string>
{root}.fragment.Template.prototype.createFragment([context,] [asHTML[,
noProcessing[, dontExpandMustacheUntouchables]]]) -> frag
{root}.fragment.Template.prototype.processFragment(html[, context[,
preMustached[, dontExpandMustacheUntouchables]]]) -> string
[jQuery frag].prototype.context = {}
[jQuery frag].prototype.template = Template
[jQuery frag].prototype.update()
By default, `{root}` is `window` (the outer JavaScript context in browsers), but
can be changed by modifying the last line in `fragment.js`.
### fragment(id [,context] [,asHTML[, noProcessing]] [,callback(err, frag)]) -> frag
Create a new fragment from template `id`.
Call style examples:
- `fragment("foo") -> frag`
-- Returns a new fragment jQuery object for template with id `foo`.
- `fragment("foo", {user:"john"}) -> frag`
-- Like above, but with a local context.
- `fragment("foo", {user:"john"}, function(err, frag) {...})`
-- Like above, but invokes a callback, passing the fragment when loaded. Will
try to GET the template if no template with id `foo` can be found.
- `fragment("foo", {user:"john"}, true) -> frag`
-- Returns a HTML string fragment of template `foo`
- `fragment("foo", true, true) -> frag`
-- Returns an unprocessed HTML string fragment of template `foo`
---
Fragment -- [http://github.com/rsms/js-fragment](http://github.com/rsms/js-fragment)
</div>
</body>
</html>