• Stars
    star
    40
  • Rank 660,144 (Top 14 %)
  • Language
    JavaScript
  • Created over 11 years ago
  • Updated about 11 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Declarative view technology for Backbone

Backbone.ViewDSL

Backbone.ViewDSL provides declarative view technology on top of Backbone.

The main feature of Backbone.ViewDSL is an extensible DOM templating engine which allows you to

  • Interpolate string or DOM values
  • Instantiate sub-views directly from inside templates
  • Bind data to DOM text nodes or element attributes
  • Automatically setup references for DOM nodes being rendered
  • Create custom directives as custom HTML tags or attributes

To give a taste of these features there's a basic example

class App extends Backbone.ViewDSL.View
  template: """
    <h1 element-id="$header">{{bind:user.name}}'s todos</h1>
    <view name="views:UserCard" model="user"></view>
    <foreach collection="todos">
      <view name="views:TodoView"></view>
    </foreach>
    """

This work was mainly inspired by Angular.js but tries to stay as close to Backbone style as possible so it is very easy to use in your application in a completely non-intrusive way.

Installation

You can grab compiled JavaScript code from the repo or use npm:

% npm install backbone.viewdsl

or bower package managers:

% bower install backbone.viewdsl

The only dependencies are jQuery, Backbone and underscore.js — if you use one of the package managers they will be installed automatically, otherwise you should download them by hand.

Backbone.ViewDSL designed to work in CommonJS environment as well as with any available AMD loader (such as RequireJS). If you don't use nor AMD neither CommonJS loading strategies then all the public API will be available through the Backbone.ViewDSL browser global.

Basic usage

The main usage pattern is exposed via Backbone.ViewDSL.View subclass of Backbone.View with a custom implementation of render() method.

Usually you want to define a new subclass of it and set a template attribute:

class Message extends Backbone.ViewDSL.View
  template: """
    {{greeting}}, {{options.name}}!
    """

  greeting: ->
    'Hello'

view = new Message(name: 'World')
view.render()

This template uses string interpolation to insert options.name value and a result of greeting() method call inside the DOM text node. That way view's el DOM element will have a form of <div>Hello, World!</div>.

Templates are always rendered in the context of a view so we can reference any view's attribute inside them or call any methods without arguments. If you need to reach some nested attribute or method then you can use usual dotted-path like a.b.c.

Sub-views instantiation

Backbone doesn't have an opinion on how to manage view hierarchies inside your application so usually you cook something by yourself.

Backbone.ViewDSL tries to make this task a lot easier by providing you with a view directive which allows instantiating sub-views right from inside templates. The directive can be used as a <view> DOM element or view DOM attribute.

The example would be

class App extends Backbone.ViewDSL.View
  template: """
    <view name="views.Sidebar" model="user" id="sidebar"></view>
    <footer view="views.Footer" view-model="user" view-id="footer"></footer>
    """

app = new App
app.render()

This snippet of code alone makes a lot of things under the hood.

View views.Sidebar will be rendered and app.user will be passed into its constructor as a model option. After that rendered view will be stored as app.sidebar attribute.

There's a bit different story with views.Footer — it also gets app.user as a constructor model option but instead of creating new DOM node for the view itself it will reuse <footer> element. That could be useful if you don't know before with what kind of element view will be used.

Without using Backbone.ViewDSL all of these would look like this:

class App extends Backbone.View

  render: ->
    this.sidebar = new Sidebar(model: this.user)
    this.sidebar.render()
    this.$el.append(this.sidebar.$el)

    this.footer = new Footer(model: this.user, tagName: 'footer')
    this.footer.render()
    this.$el.append(this.footer.$el)

The variant which uses Backbone.ViewDSL.ViewDSL looks a lot cleaner, doesn't it? Also Backbone.ViewDSL.View keeps track of all instantiated sub-views and handles its disposal so no memory leaks will happen.

String and DOM values interpolation

As it was already shown Backbone.ViewDSL allows you to insert specific bits of text inside templates. But what's more interesting — you can also insert entire DOM elements into templates, even with attached event handlers.

class View extends Backbone.ViewDSL.ViewDSL
  template: """
    {{element}} {{jquery}}
    """
  element: ->
    document.createElement('div')
  jquery: ->
    $('<div>').addClass('klass')

Rendered view will have <div></div> <div class="klass"></div> as its content. As you can see you can also insert jQuery objects into template.

Referencing DOM nodes

Sometimes you need to reference DOM element from recently rendered template — you can select it by using this.$ method call but a better way would be to use element-id attribute directive.

class View extends Backbone.ViewDSL.View
  template: """
    <div class="main" element-id="block"></div>
    """

view = new View
view.render()

That way rendered <div> element will be available as view.block attribute.

Other built-in directives

There are a couple of other built-in directives — attr-* and class-* wildcard directives and show-if directive.

The attr-* directive can be used to attach attributes to DOM elements based on some view's value. For example given the template

<img attr-src="model.imageURL">

We will get src attribute set to value of model.imageURL view's attribute. There's also a special case for attributes which has boolean interpretation (checked, contenteditable and so on...) — if expression evaluates to Boolean value then attribute will be present if value is true in case of false value attribute will not be rendered.

class View extends Backbone.ViewDSL.View
  template: """
    <h1 attr-contenteditable="isEditable">title</h1>
    """
  isEditable: ->
    this.model.get('isEditable') and this.user.canEdit(this.model)

Note that isEditable method returns boolean value.

The class-* wildcard directive works like a attr-* directive but instead regulates if element should receive an additional CSS class based on some view's attribute or method.

class View extends Backbone.ViewDSL.View
  template: """
    <h1 class-editable="isEditable">title</h1>
    """
  isEditable: ->
    this.model.get('isEditable') and this.user.canEdit(this.model)

In this example, <h1> will have class editable if and only if isEditable method evaluates to true.

The last of the built-in directives — show-if controls if element is visible based on some expression which evaluates to boolean value:

<div show-if="this.collection.isEmpty">No items"</div>

The <div> element will be displayed only if this.collection.isEmpty() evaluates to true. Methods $.show() and $.hide() are used to correspondingly show and hide elements.

Data-binding

You want your views to react to underlying data changes but manually maintaining a set of change event handlers isn't an option.

For that reason a part of Backbone.ViewDSL directives like attr-*, class-* and show-if as well as interpolation mechanism allows you to bind their action on data changes and react to them accordingly.

To turn data-binding on you have to prefix all expressions with bind: modifier:

class View extends Backbone.ViewDSL.View
  redAllowed: true

  template: """
    <div class-red="bind:isRed">Hello, {{bind:model.name}}!</div>
    """

  isRed: ->
    this.model.get('red') and this.redAllowed

view = new View(model: new Backbone.Model(name: 'World', red: false))
view.render()

That way rendered view's el will have

<div>Hello, World!</div>

as its innerHTML and it will react to data changes according to directive actions. So this snippet of code

view.model.set(name: 'Commrade', red: true)

will result el.innerHTML having different contents

<div class="red">Hello, Commrade!</div>

Remember that bind: modifier also works with attr-* and show-if directives.

Creating custom directives

Rendering collections

Parametrizable views

More Repositories

1

autobind-decorator

Decorator to automatically bind methods to class instances
JavaScript
1,448
star
2

reactify

[DEPRECATED] Browserify transform for JSX (superset of JavaScript used in React library by Facebook)
JavaScript
689
star
3

react-css-components

Define React presentational components with CSS
JavaScript
676
star
4

react-fa

DEPRECATED: use https://github.com/FortAwesome/react-fontawesome instead
JavaScript
492
star
5

react-async

[DEPRECATED] Asynchronously fetch data for React components
JavaScript
446
star
6

react-quickstart

[DEPRECATED] React project template with server-side UI rendering and routing
JavaScript
370
star
7

react-time

Component for React to render relative and/or formatted dates into <time> HTML5 element
JavaScript
211
star
8

styling

Create CSS modules with the full power of JavaScript
JavaScript
130
star
9

react-derivable

React bindings for derivable state computation library
JavaScript
122
star
10

sitegen

Generate websites by composing React components
JavaScript
118
star
11

reactdown

Markdown based live document format
JavaScript
116
star
12

rrouter

Declarative routing layer for React applications
JavaScript
114
star
13

backbone.projections

backbone.projections is a set of projections for Backbone.Collection
CoffeeScript
110
star
14

validated

Validate your configurations with precise error messages
JavaScript
91
star
15

typescript-loader

[DEPRECATED] TypeScript Webpack Plugin
JavaScript
82
star
16

react-flexgrid

Flexbox Grid reimagined as a set of React components
JavaScript
73
star
17

less2stylus

[NOT MAINTAINED] LESS to Stylus source to source convertor capable of translating Bootstrap
CoffeeScript
71
star
18

xcss

xCSS is a library for programmatic stylesheet composition
JavaScript
63
star
19

react-stylesheet

[DEPRECATED] A component for React to declare stylesheet dependencies for your reusable components
JavaScript
40
star
20

cssobjectify

Browserify transform to turn stylesheets into JSON objects
JavaScript
39
star
21

todomvc-flux-swarm

JavaScript
38
star
22

es6-template-strings-jsx

JavaScript
38
star
23

rethemeable

Utilities for producing and consuming themable React components
JavaScript
35
star
24

react-app-express

*DEPRECATED* React + Express + Browserify + History API + Server Side Rendering
JavaScript
32
star
25

react-app-controller

*DEPRECATED* React application controller to manage top-level React components according to window.location
JavaScript
32
star
26

type-systems

Playing with type systems
OCaml
32
star
27

routr

Request routing for WebOb based WSGI applications
Python
29
star
28

memoize-decorator

Memoize getters and methods to compute only once
JavaScript
29
star
29

sweet-assertions

Syntax for writing informative testing assertions
JavaScript
29
star
30

sweetify

Browserify transform for using Sweet.js macros
JavaScript
29
star
31

upaas

μPaaS — nano PaaS based on Docker and gitreceive
Shell
28
star
32

rescript

[PoC] Rescript is a scripting runtime for ReasonML
OCaml
25
star
33

webpack-package-loaders-plugin

Webpack module loaders discovery through package.json
JavaScript
25
star
34

julia-repl-vim

Julia REPL plugin for vim/neovim
Julia
24
star
35

react-app

*DEPRECATED* Rapid appliaction development with React
JavaScript
23
star
36

ctags-webpack-plugin

Webpack plugin to generate accurate ctags
JavaScript
21
star
37

purescript-node-thunk

Node callbacks as thunks
PureScript
20
star
38

console-ui

Composable console output (somewhat inspired by React)
JavaScript
20
star
39

rrun

[WIP] rrun allows to seamlessly run Reason/OCaml code with native speed
OCaml
19
star
40

sweet-jsx

Use JSX and sweet.js macros together
JavaScript
18
star
41

ppx_let_promise

Like async/await syntax for Promises in JS but for OCaml
OCaml
18
star
42

K.jl

K programming language dialect embedded in Julia
Julia
17
star
43

jsonpublish

Configurable JSON encoder for publishing Python objects as JSON documents
Python
17
star
44

markstruct

Block-based structured editor for Markdown
JavaScript
16
star
45

es6-module-jstransform

ES6 module syntax to CommonJS transformation
JavaScript
16
star
46

BQN.jl

BQN implementation in Julia
Julia
16
star
47

vim-flow-outline

Outline for JS modules with Flow
Vim Script
16
star
48

rework-macro

Macro CSS transform for rework/xcss
JavaScript
16
star
49

esy-docker

A set of make rules to produce docker images for esy projects
Makefile
15
star
50

configure

Configuration toolkit based on YAML
Python
15
star
51

mocha-doctest

Test your documentation
JavaScript
14
star
52

connect-browserify

Connect/express middelware for serving front-end applications with browserify.
JavaScript
13
star
53

YouTubeManager

YouTubeManager is an wrapper for YouTube JS Player API which tries to mimic SoundManager2 API.
CoffeeScript
13
star
54

domain-context

Globally accessible domain-bound contexts, connect/express middleware included
CoffeeScript
12
star
55

babel-plugin-ast-literal

Babel Plugin AST Literal
JavaScript
11
star
56

react-custom-events

Don't use this, this was an experiment and it doesn't work anymore with recent versions of React
JavaScript
11
star
57

react-image-size-loader

Webpack loader for images which turns them into <img /> components with height and width
JavaScript
11
star
58

wpack

JavaScript
10
star
59

jstransformify

Browserify transform which applies jstransform visitors
JavaScript
9
star
60

react-macros

A set of syntax extensions for React
JavaScript
8
star
61

backbone.viewevents

Events for Backbone.View which can bubble up through view hierarchy.
JavaScript
7
star
62

prefetch-context-webpack-plugin

Webpack plugin which prefetches context (all files within the directory tested by a regular expression)
JavaScript
7
star
63

musvox

Collaborative music listening environment for Minecraft-like voxel worlds
JavaScript
7
star
64

lang-julia

Julia language support for the CodeMirror code editor
TypeScript
7
star
65

react-dom-events

**DO NOT USE THIS**
JavaScript
7
star
66

sphinx-npm

Sphinx documentation tool launcher which builds docs for npm packages
JavaScript
6
star
67

dream-totp-auth

An example Dream app with password auth & totp
OCaml
6
star
68

extracty

a set of tools to extract metadata from HTML documents (WIP)
Python
6
star
69

bw_sphinxtheme

Sphinx theme in black and white colours.
JavaScript
6
star
70

inets_mod_proxy

Simple HTTP proxy module for erlang inets httpd service.
Erlang
6
star
71

swarm-react

JavaScript
5
star
72

esy-bsb-example

OCaml
5
star
73

stream-rpc

RPC over arbitrary streams for Node.js and a browser
CoffeeScript
5
star
74

require-assets

A library to package and re-use static assets
JavaScript
5
star
75

asyncomplete-ale.vim

LSP completion source (via ALE) for asyncomplete.vim
Vim Script
5
star
76

react-router-component-bower

Bower package for react-router-component
JavaScript
5
star
77

deps-topo-sort

Sort module-deps/dgraph output topologically
JavaScript
5
star
78

fzf-merlin

Vim Script
5
star
79

diffbot

DiffBot API wrapper (uses urllib3)
Python
5
star
80

purescript-immutable

PureScript bindings to Immutable.js library
PureScript
5
star
81

contentlet

Framework for creating composable and reusable web UI.
Python
5
star
82

aoc2021

AOC2021 in BQN
5
star
83

webpack-stylegen

JavaScript
5
star
84

backbone.module

Spine.Module but for Backbone
CoffeeScript
4
star
85

dgraph

Build and transform dependency graphs from JS, CSS or other code bases
JavaScript
4
star
86

sphinxalchemy

SphinxQL dialect for SQLAlchemy (uses MySQLdb-Python for wire protocol)
Python
4
star
87

es6-destructuring-jstransform

ES6 destructuring assignment and destructuring function arguments transformation.
JavaScript
4
star
88

reason-react-workshop

CSS
4
star
89

wall

Extremely hackable HN/Reddit clone in PostgreSQL + Node + Express + React
CoffeeScript
4
star
90

esy-solve-cudf

Makefile
4
star
91

esy-reason-graphql-server

[EXAMPLE REPO, NOT MAINTAINED] Reason + GraphQL on esy
OCaml
4
star
92

faviconr

Fast and robust favicon resolution
CoffeeScript
4
star
93

jsxx

JSX eXperimental
JavaScript
4
star
94

ipsql

Intelligent PostgreSQL shell (concept)
Python
3
star
95

pureact

PureScript
3
star
96

ppx_router

type safe routing for Dream
OCaml
3
star
97

docgen.mk

a set of utilities and make macros for static site generation
Python
3
star
98

fb.py

Python bindings for Facebook Graph API
Python
3
star
99

react-async-middleware

Connect/express middleware to serve react-async components
JavaScript
3
star
100

react-pad

Authoring tool for React components
JavaScript
3
star