Commit 7f8c3afc authored by S Anand's avatar S Anand

ENH: Templates allow access to source node. Fixes #169

parent 8cc54cb5
Pipeline #87297 failed with stage
in 2 minutes and 28 seconds
<div>sum(<%= JSON.stringify($data.x) %>) = <%= _.sum($data.x) %></div>
......@@ -21,6 +21,9 @@ This displays `Your platform is ...` and shows the userAgent just below the scri
Note: the `<template>` tag is not supported by Internet Explorer. Use
`<script type="text/html">` for IE compatibility.
## $.template variables
Templates can access any global variable. You can pass additional variables
using as `.template({var1: value, var2: value, ...})`. For example:
......@@ -38,6 +41,45 @@ using as `.template({var1: value, var2: value, ...})`. For example:
To re-render the template, run `.template(data)` again with different data.
Templates can also use these default variables:
- `obj`: the full data object passed to the template
- `$node`: the generating `<template>` element as a jQuery object
- `$node.attr('class')` returns the class of the template
- `$node.data('key')` returns `data-key` in `<template data-key="...">`
- `$data`: a shortcut for `$node.data()`.
`$data.key` is the same as `$node.data('key')`
If you pass `obj`, `$node` or `$data` explicitly to `.template({...})`, it
overrides the default variables. The values you pass take priority.
You can pass any JSON object as a data attribute. In the example below,
`data-list` and `data-obj` are interpreted as JSON objects:
<!-- render:html -->
```html
<template class="datavar" data-list="[1,2,3]" data-obj="{x:1,y:[2,3]}">
list = <%= JSON.stringify($data.list) %>,
obj = <%= JSON.stringify($data.obj) %>,
</template>
<script>
$('.datavar').template()
</script>
```
This is particularly useful with [external sources](#template-external-source).
For example, using an external [datavars.html](datavars.html) template:
<!-- render:html -->
```html
<template class="datavars" src="datavars.html" data-x="[1,2]"></template>
<template class="datavars" src="datavars.html" data-x="[3,4,5]"></template>
<script>
$('.datavars').template()
</script>
```
## $.template subtemplates
You can use sub-templates as follows:
......@@ -62,7 +104,8 @@ You can use sub-templates as follows:
(This is typically used by sub-templates.)
`data-template-item=".row"` creates a function `item()` inside `.main-template`.
Calling `item()` renders `.roww` as a sub-template.
Calling `item()` renders `.row` as a sub-template.
**Notes**:
......
......@@ -103,9 +103,11 @@ function make_template_sync($this, html, data, default_options) {
// $this.data(_compiled) has the compiled template. This adds sub-template
// variables from data-template-* attributes.
$this.data(_compiled, function (subtemplate_data) {
subtemplate_data = _.extend(subtemplate_data || {}, _.mapValues(subtemplates($this), function (selector) {
return $(selector).data(_compiled)
}))
subtemplate_data = _.extend(
{$node: $this, $data: $this.data()},
_.mapValues(subtemplates($this), function (selector) { return $(selector).data(_compiled) }),
subtemplate_data || {}
)
return compiled_template(subtemplate_data)
})
......
<%= data.join(' ') %>
<%= data.join(',') %>
<!-- Ensure that these variables exist -->
<% $node %> <!-- The target node -->
<% $node.data('x').toLowerCase() %> <!-- ... having data-x=".." -->
<% $data.x.toLowerCase() %> <!-- same as $data.x -->
......@@ -39,6 +39,8 @@ async function run_puppeteer() {
args: ['--no-sandbox']
})
const page = await browser.newPage()
// Note: if there's a console error, msg.type == 'error'
// msg.args has the error arguments.
page.on('console', msg => console.log(msg.text)) // eslint-disable-line no-console
const paths = glob.sync('test/test-*.html')
for (let i = 0; i < paths.length; i++) {
......
......@@ -60,8 +60,8 @@
$('#t2').one('template', function (e) {
var $divs = e.target.filter('div')
t.equal($divs.length, list.length, 'Correct number of nodes are created')
var text = $divs.map(function () { return this.innerHTML }).get().join(' ')
t.equal(text, list.join(' '), 'Template content is correct')
var text = $divs.map(function () { return this.innerHTML }).get().join(',')
t.equal(text, list.join(','), 'Template content is correct')
t.deepEqual(e.templatedata, { list: list })
$divs.attr('class', 'my-unique-item')
t.equal($('.my-unique-item').length, 3, 'Repeated calls over-write the same node')
......@@ -70,12 +70,12 @@
})
</script>
<template id="t3" src="sample-template.html"></template>
<template id="t3" data-x="hi" src="sample-template.html"></template>
<script>
tape('$().template() renders src= via AJAX load', function (t) {
var data = { data: ['x', 'y'] }
$('#t3').one('template', function (e) {
t.equal(text(e.target), data.data.join(' '))
t.equal(text(e.target), data.data.join(','))
t.deepEqual(e.templatedata, data)
t.end()
}).template(data)
......@@ -83,13 +83,13 @@
</script>
<template id="t4" src="nonexistent.html">
<%= xhr.status %>: Not found. <%= data.join(' ') %>
<%= xhr.status %>: Not found. <%= data.join(',') %>
</template>
<script>
tape('$().template() renders contents if src= returns an error', function (t) {
var data = { data: ['x', 'y'] }
$('#t4').one('template', function (e) {
t.equal(text(e.target), '404: Not found. x y')
t.equal(text(e.target), '404: Not found. x,y')
t.deepEqual(e.templatedata.data, data.data)
t.equal(e.templatedata.xhr.status, 404)
t.end()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment