1 | # react-jade
|
2 |
|
3 | Compile Jade to React JavaScript
|
4 |
|
5 | [![Build Status](https://img.shields.io/travis/jadejs/react-jade/master.svg)](https://travis-ci.org/jadejs/react-jade)
|
6 | [![Dependency Status](https://img.shields.io/gemnasium/jadejs/react-jade.svg)](https://gemnasium.com/jadejs/react-jade)
|
7 | [![NPM version](https://img.shields.io/npm/v/react-jade.svg)](https://www.npmjs.org/package/react-jade)
|
8 |
|
9 | ## Installation
|
10 |
|
11 | npm install react-jade
|
12 |
|
13 | ## Usage
|
14 |
|
15 | ### With Browserify
|
16 |
|
17 | If you are using browserify, just write a file that looks like the following, then use `react-jade` as a transform. It will then inline the result of calling `jade.compileFile` automatically.
|
18 |
|
19 | ```js
|
20 | var React = require('react');
|
21 | var jade = require('react-jade');
|
22 |
|
23 | var template = jade.compileFile(__dirname + '/template.jade');
|
24 |
|
25 | React.render(template({local: 'values'}), document.getElementById('container'));
|
26 | ```
|
27 |
|
28 | ```
|
29 | browserify index.js --transform react-jade > bundle.js
|
30 | ```
|
31 |
|
32 | ### Without Browserify
|
33 |
|
34 | If you are not using browserify, you could manually compile the jade to some client file. e.g.
|
35 |
|
36 | ```js
|
37 | var fs = require('fs');
|
38 | var jade = require('react-jade');
|
39 |
|
40 | fs.writeFileSync(__dirname + '/template.js', 'var template = ' + jade.compileFileClient(__dirname + '/template.jade'));
|
41 | ```
|
42 |
|
43 | Then on your html page:
|
44 |
|
45 | ```html
|
46 | <div id="container"></div>
|
47 | <script src="http://fb.me/react-0.10.0.js"></script>
|
48 | <script src="template.js"></script>
|
49 | <script>
|
50 | React.render(template({local: 'values'}), document.getElementById('container'));
|
51 | </script>
|
52 | ```
|
53 |
|
54 | ### Server Side
|
55 |
|
56 | You can also use react-jade to render templates on the server side via `React.renderToString`. This is especially useful for building isomorphic applications (i.e. applications that run the same on the server side and client side).
|
57 |
|
58 | ```js
|
59 | var fs = require('fs');
|
60 | var React = require('react');
|
61 | var jade = require('react-jade');
|
62 |
|
63 | var template = jade.compileFile(__dirname + '/template.jade');
|
64 |
|
65 | var html = React.renderToString(template({local: 'values'}));
|
66 | fs.writeFileSync(__dirname + '/template.html', html);
|
67 | ```
|
68 |
|
69 | ### ES6
|
70 |
|
71 | If you are using ES6 server side, or the browserify transform client side (even without any other ES6 support), you can use Tagged Literals to embed your jade code directly within your JavaScript components:
|
72 |
|
73 | ```js
|
74 | var TodoList = React.createClass({
|
75 | render: jade`
|
76 | ul
|
77 | each item in this.props.items
|
78 | `
|
79 | });
|
80 | var TodoApp = React.createClass({
|
81 | getInitialState: function() {
|
82 | return {items: [], text: ''};
|
83 | },
|
84 | onChange: function(e) {
|
85 | this.setState({text: e.target.value});
|
86 | },
|
87 | handleSubmit: function(e) {
|
88 | e.preventDefault();
|
89 | var nextItems = this.state.items.concat([this.state.text]);
|
90 | var nextText = '';
|
91 | this.setState({items: nextItems, text: nextText});
|
92 | },
|
93 | render: jade`
|
94 | h3 TODO
|
95 | TodoList(items=this.state.items)
|
96 | form(onSubmit=this.handleSubmit)
|
97 | input(onChange=this.onChange value=this.state.text)
|
98 | button= 'Add #' + (this.state.items.length + 1)
|
99 | `.locals({TodoList: TodoList})
|
100 | });
|
101 | React.render(TodoApp(), mountNode);
|
102 | ```
|
103 |
|
104 | ## API
|
105 |
|
106 | ```js
|
107 | var jade = require('react-jade');
|
108 | ```
|
109 |
|
110 | ### jade(options) / jade(file)
|
111 |
|
112 | Acts as a browseify transform to inline calls to `jade.compileFile`. The source code looks something like:
|
113 |
|
114 | ```js
|
115 | function browserify(options) {
|
116 | function transform(file) {
|
117 | return new TransformStream(); //stream to do the transform implemented here
|
118 | }
|
119 | if (typeof options === 'string') {
|
120 | var file = options;
|
121 | options = arguments[2] || {};
|
122 | return transform(file);
|
123 | } else {
|
124 | return transform;
|
125 | }
|
126 | }
|
127 | ```
|
128 |
|
129 | ### jade.compileFile(filename, options) => fn
|
130 |
|
131 | Compile a jade file into a function that takes locals and returns a React DOM node.
|
132 |
|
133 | ### jade.compileFileClient(filename, options)
|
134 |
|
135 | Compile a jade file into the source code for a function that takes locals and returns a React DOM node. The result requires either a global 'React' variable, or the ability to require 'React' as a CommonJS module.
|
136 |
|
137 | ### jade.compile(jadeString, options) => fn
|
138 |
|
139 | Same as `jade.compileFile` except you pass an inline jade string instead of a filename. You should set `options.filename` manually.
|
140 |
|
141 | ### jade.compileClient(jadeString, options)
|
142 |
|
143 | Same as `jade.compileFileClient` except you pass an inline jade string instead of a filename. You should set `options.filename` manually.
|
144 |
|
145 | ### template.locals(locals)
|
146 |
|
147 | You can set default `locals` values via the `template.locals` api. e.g.
|
148 |
|
149 | ```js
|
150 | var React = require('react');
|
151 | var jade = require('react-jade');
|
152 |
|
153 | var template = jade.compileFile(__dirname + '/template.jade').locals({title: 'React Jade'});
|
154 |
|
155 | React.render(template({local: 'values'}), document.getElementById('container'));
|
156 | ```
|
157 |
|
158 | ## Differences from jade
|
159 |
|
160 | React Jade has a few bonus features, that are not part of Jade.
|
161 |
|
162 | ### Automatic partial application of `on` functions
|
163 |
|
164 | In react, you add event listeners by setting attributes, e.g. `onClick`. For example:
|
165 |
|
166 | ```jade
|
167 | button(onClick=clicked) Click Me!
|
168 | ```
|
169 | ```js
|
170 | var fn = jade.compileFile('template.jade');
|
171 | React.render(fn({clicked: function () { alert('clicked'); }), container);
|
172 | ```
|
173 |
|
174 | Often, you may want to partially apply a function, e.g.
|
175 |
|
176 | ```jade
|
177 | input(value=view.text onChange=view.setProperty.bind(view, 'text'))
|
178 | ```
|
179 | ```js
|
180 | function View() {
|
181 | }
|
182 | View.prototype.setProperty = function (name, e) {
|
183 | this[name] = e.target.value;
|
184 | render();
|
185 | };
|
186 | var view = new View();
|
187 | function render() {
|
188 | React.renderComponent(fn({view: view}), container);
|
189 | }
|
190 | ```
|
191 |
|
192 | Because you so often want that `.bind` syntax, and it gets pretty long and cumbersome to write, react-jade lets you omit it:
|
193 |
|
194 | ```jade
|
195 | input(value=view.text onChange=view.setProperty('text'))
|
196 | ```
|
197 |
|
198 | This is then automatically re-written to do the `.bind` for you.
|
199 |
|
200 | ### Style
|
201 |
|
202 | In keeping with React, the style attribute should be an object, not a string. e.g.
|
203 |
|
204 | ```jade
|
205 | div(style={background: 'blue'})
|
206 | ```
|
207 |
|
208 | ### Unsupported Features
|
209 |
|
210 | Although a lot of jade just works, there are still some features that have yet to be implemented. Here is a list of known missing features, in order of priority for adding them. Pull requests welcome:
|
211 |
|
212 | - mixins
|
213 | - attribute extension/merging (via `&attributes`)
|
214 | - case/when
|
215 | - using each to iterate over keys of an object (rather than over items in an array)
|
216 | - interpolation
|
217 | - attribute interpollation
|
218 | - special handling of data-attributes
|
219 | - outputting unescaped html results in an extra wrapper div and doesn't work for attributes
|
220 |
|
221 | ## License
|
222 |
|
223 | MIT
|