View View on GitHub

Powerful template rendering engine for dynamic data

Views provide a powerful way to inject data into complex strings and markup structures. With a powerful API you can extend the default helpers for infinite possibilities.

App #

Create dynamic data-driven interfaces

Make

VariableTypeDefaultDescriptionRequired
namestringApplication name
optionsobjectObject properties below

Options Object

VariableTypeDefaultDescriptionRequired
modelobject{}Data object to bind to view
targetselectionIf view isn’t a selection the DOM target
viewselection, stringThe DOM view or a view string/reference

Applications are the glue between the renderer and observables. Updating properties in an app’s data model triggers the view to update the DOM with the associated changes allowing for complex, data-bound interfaces.

Create View

// js/views/load/todo.html

<ul class="todo">
    {{ #items|each }}
        <li class="todo__item{{ #done }} -is-done{{ /done }}">
            <div class="todo__toggle" data-ref="toggle" data-id="{{ # }}"></div>
            <span class="todo__label">{{ label }}</span>
        </li>
    {{ /items }}
</ul>

Note: Adding HTML view files into the js/views/load directory will automatically add the view into Wee’s data store when the build process is run. These auto-loaded views can be accessed directly when creating an app. Module views adhere to the same structure but are prefixed with “moduleName.” when referenced.

Create App

Wee.app.make('todo', {
    target: 'ref:todo', // DOM target to render app into
    view: 'todo', // String or loaded view file target
    model: {
        items: [
            {
                label: 'Download and run Wee',
                done: true
            },
            {
                label: 'Explore the guide and welcome modules'
            },
            {
                label: 'Reset your project to a blank slate'
            },
            {
                label: 'Customize wee.json'
            },
            {
                label: 'Build something incredible'
            }
        ]
    }
});

Note: Since applications are a type of controller, all the standard scoped controller methods are available as properties on the app.

Update App Data Model

// Add new property to app model
Wee.app.todo.$set('newProperty', 'data-binding at work');

// Add new item to end of the todo list
Wee.app.todo.$push({
    label: 'Add something dynamic'
});

There are 2 additional methods available specifically to app instances, $pause and $resume. These allow for selectively enabling and disabling the actual rendering of any model changes to the DOM. When resuming you can opt to have the app render with any model updates made since the pause.

Wee.app.todo.$pause(); 

Resume

VariableTypeDefaultDescriptionRequired
updatebooleanfalseRender app immediately
Wee.app.todo.$resume(true); 

Render #

Parse data into template string

VariableTypeDefaultDescriptionRequired
templatestringTemplate string
dataobjectData object

Simple

var template = 'My name is {{ firstName }} {{ lastName }}',
    data = {
        firstName: 'John',
        lastName: 'Smith'
    };

Wee.view.render(template, data);
"My name is John Smith"

Fallback Values

var template = 'My name is {{ firstName }} {{ lastName| |'Doe' }}',
    data = {
        firstName: 'John'
    };

Wee.view.render(template, data);
"My name is John Doe"

Changing Context

var template = '{{ #child }}{{ #child }}{{ name }}\'s dad is {{ ../name }} and his grandad is {{ $root.name }}.{{ /child }}{{ /child }}',
    data = {
        name: 'John',
        child: {
            name: 'Jimmy',
            child: {
                name: 'Charlie'
            }
         }
    };

Wee.view.render(template, data);
"Charlie's dad is Jimmy and his grandad is John."

Helpers

var template = 'My name is {{ firstName }}{{ #lastName|notEmpty }} {{ lastName }}{{ /lastName }}',
    data = {
        firstName: 'John',
        lastName: 'Smith'
    };

Wee.view.render(template, data);
"My name is John Smith"

Loop Variables

Within tag pairs there are a handful of variables made available automatically.

  • {{ $key }} - The key when iterating over an object
  • {{ . }} - The single currently iterated value
  • {{ # }} - Zero-based loop index
  • {{ ## }} - One-based loop index
var template = '{{ #names }}{{ # }} | {{ ## }} | {{ . }} | {{ $key }}<br>{{ /names }}',
    data = {
        names: {
            'John': 45,
            'Jane': 42,
            'Jimmy': 18,
            'Jenny': 15
        }
    };

Wee.view.render(template, data);
0 | 1 | 45 | John<br>
1 | 2 | 42 | Jane<br>
2 | 3 | 18 | Jimmy<br>
3 | 4 | 15 | Jenny<br>

Advanced

The render method does more than simple variable output. It can traverse as deep into the provided object as you need for multi-level output.

var template = '<p>My Name is {{ firstName }}{{ #lastName|notEmpty }} {{ lastName }}{{ /lastName }}</p>' +
    '{{ #children|notEmpty }}' +
        '<p>My Children are:</p>' +
        '<ul>{{ #.|each }}' +
            '<li>{{ name }} - {{ age }}</li>' +
        '{{ /. }}</ul>' +
    '{{ else }}' +
        '<p>I have no children.</p>' +
    '{{ /children }}',
    data = {
        firstName: 'John',
        lastName: 'Smith',
        children: [
            {
                name: 'Judy',
                age: '12'
            },
            {
                name: 'James',
                age: '9'
            }
        ]
    };

Wee.view.render(template, data);
<p>My Name is John Smith</p>
<p>My Children are:</p>
<ul>
    <li>Judy - 12</li>
    <li>James - 9</li>
</ul>

addView #

Add views to store for on-demand reference

VariableTypeDefaultDescriptionRequired
namestringView name
valuestringView value
Wee.view.addView('copyright', '<small>&copy; {{ year }}</small>');
var template = '{{> copyright }}',
    data = {
        year: 2015
    };

Wee.view.render(template, data);
"<small>&copy; 2015</small>"

You can also add views to the store and then reference them when creating apps or rendering.

Wee.view.addView('viewName', 'My name is {{ firstName }} {{ lastName }}');
Wee.view.render('viewName', {
    firstName: 'Don',
    lastName: 'Draper'
});
Wee.app.make('appName', {
    view: 'viewName',
    model: {
        firstName: 'Don',
        lastName: 'Draper'
    }
});

Helpers #

Add helper to run additional processing on tag data

Helpers have access to certain properties via the current scope this. All helpers have access to val, data, root, tag, and index. Tag pairs have a unique property empty and single tags have the unique property fallback. A common use for helpers is filtering tag data. Default helpers used for filtering tag pairs include is, not, isEmpty, and notEmpty.

VariableTypeDefaultDescriptionRequired
namestringHelper name
fnfunctionHelper callback
Wee.view.addHelper('upper', function() {
    return this.val.toUpperCase();
});
var template = 'My name is {{ name|upper }}.',
    data = {
        name: 'john'
    };

Wee.view.render(template, data);
"My name is JOHN."

Parametric

Wee.view.addHelper('starts', function(num) {
    return this.val.substr(0, num || 1);
});
var template = '{{ name }} starts with {{ name|starts(5) }}.',
    data = {
        name: 'Rhinoceros'
    };

Wee.view.render(template, data);
"Rhinoceros starts with Rhino."

Boolean Response

Returning true or false determines if the current tag pair should be parsed or skip to the next evaluation.

Wee.view.addHelper('isNumber', function() {
    return typeof this.val == 'number';
});
var template = '{{ #age|isNumber }}I am {{ age }} years old.{{ /age }}',
    data = {
        age: 30
    };

Wee.view.render(template, data);
"I am 30 years old."

Data Modification

By modifying the value of this.data the remaining template parsing can be manipulated. The following extracts a range of data from a larger set of data.

Wee.view.addHelper('range', function(offset, limit) {
    this.data[this.tag] = this.val.filter(function(el, i) {
        return i >= offset && i < limit;
    });
});
var template = '{{ #names|range(2, 5) }}{{ . }} {{ /names }}',
    data = {
        names: [
            'John',
            'Jane',
            'Jim',
            'Janice',
            'Jacob',
            'Jasper'
        ]
    };

Wee.view.render(template, data);
"Jim Janice Jacob"

Note: Helpers can take any number of parameters.