haml_coffee_assets 0.0.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +107 -42
- data/lib/haml_coffee_assets/engine.rb +12 -6
- data/lib/haml_coffee_assets/haml_coffee.rb +4 -2
- data/lib/haml_coffee_assets/haml_coffee_assets.js +41 -12
- data/lib/haml_coffee_assets/haml_coffee_template.rb +1 -1
- data/lib/haml_coffee_assets/version.rb +1 -1
- data/lib/js/haml-coffee.js +813 -269
- metadata +4 -4
data/README.md
CHANGED
@@ -1,14 +1,17 @@
|
|
1
|
-
#
|
1
|
+
# Haml Coffee Assets [![Build Status](https://secure.travis-ci.org/netzpirat/haml_coffee_assets.png)](http://travis-ci.org/netzpirat/haml_coffee_assets)
|
2
2
|
|
3
|
-
|
4
|
-
pipeline.
|
3
|
+
Haml Coffee Assets compiles [Haml CoffeeScript](https://github.com/netzpirat/haml-coffee) templates in the Rails 3.1
|
4
|
+
asset pipeline, so you can use them as JavaScript templates in your JavaScript heavy Rails application.
|
5
5
|
|
6
|
-
Tested on MRI Ruby 1.8.7, 1.9.2, REE and the latest
|
6
|
+
Tested on MRI Ruby 1.8.7, 1.9.2, 1.9.3, REE and the latest version of JRuby.
|
7
7
|
|
8
|
-
|
8
|
+
**Please note that I'm using haml-coffee from my fork until
|
9
|
+
[my pull request](https://github.com/9elements/haml-coffee/pull/7) is merged.**
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
## Haml Coffee
|
12
|
+
|
13
|
+
Haml Coffee allows you to write inline [CoffeeScript](http://jashkenas.github.com/coffee-script/) in your
|
14
|
+
[HAML](http://haml-lang.com/) JavaScript templates:
|
12
15
|
|
13
16
|
```haml
|
14
17
|
#cart
|
@@ -27,7 +30,7 @@ HamlCoffee allows you to write inline [CoffeeScript](http://jashkenas.github.com
|
|
27
30
|
|
28
31
|
## Installation
|
29
32
|
|
30
|
-
The simplest way to install
|
33
|
+
The simplest way to install Haml Coffee Assets is to use [Bundler](http://gembundler.com/).
|
31
34
|
Add `haml_coffee_assets` and `execjs` to your `Gemfile`:
|
32
35
|
|
33
36
|
```ruby
|
@@ -37,15 +40,18 @@ group :assets do
|
|
37
40
|
end
|
38
41
|
```
|
39
42
|
|
40
|
-
And require the `hamlcoffee.js` in your `application.js.coffee
|
43
|
+
And require the `hamlcoffee.js` in your `app/assets/javascripts/application.js.coffee`:
|
41
44
|
|
42
45
|
```coffeescript
|
43
46
|
#= require hamlcoffee
|
44
47
|
```
|
45
48
|
|
49
|
+
This provides the default escaping and the global context functions. Read more about it in the configuration section
|
50
|
+
below.
|
51
|
+
|
46
52
|
### JavaScript runtimes
|
47
53
|
|
48
|
-
|
54
|
+
Haml Coffee Assets uses [ExecJS](https://github.com/sstephenson/execjs) to pick the best runtime to evaluate the
|
49
55
|
CoffeeScript and generate the JavaScript template.
|
50
56
|
|
51
57
|
* With CRuby you want to use a V8 JavaScript Engine or Mozilla SpiderMonkey.
|
@@ -117,77 +123,125 @@ Windows operating systems.
|
|
117
123
|
|
118
124
|
## Usage
|
119
125
|
|
120
|
-
You should place all your
|
121
|
-
your `application.js.coffee`:
|
126
|
+
You should place all your Haml Coffee templates in the `app/assets/templates` directory and include all templates from
|
127
|
+
your `app/assets/javascripts/application.js.coffee`:
|
122
128
|
|
123
129
|
```coffeescript
|
124
130
|
#= require_tree ../templates
|
125
131
|
```
|
126
132
|
|
127
|
-
Now you can start to add your
|
128
|
-
`.hamlc` extension to be recognized by
|
133
|
+
Now you can start to add your Haml Coffee templates to your template directory. Make sure all your templates have a
|
134
|
+
`.hamlc` extension to be recognized by Haml Coffee Assets.
|
129
135
|
|
130
|
-
**Note:**
|
131
|
-
processor by using `.jst.hamlc` as extension, and if you do, the
|
136
|
+
**Note:** Haml Coffee already generates a JavaScript Template, so there is not need to pass it to the `JST` Sprocket
|
137
|
+
processor by using `.jst.hamlc` as extension, and if you do, the Haml Coffee templates will not work.
|
132
138
|
|
133
139
|
## Configuration
|
134
140
|
|
141
|
+
### Document format
|
142
|
+
|
143
|
+
By default all Haml Coffee templates are rendered to a HTML5 document. You can choose between the following output
|
144
|
+
formats:
|
145
|
+
|
146
|
+
* html
|
147
|
+
* html4
|
148
|
+
* xhtml
|
149
|
+
|
150
|
+
If you prefer another HTML format than HTML5, you can set it in your `config/application.rb`:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
config.hamlcoffee.format = 'xhtml'
|
154
|
+
```
|
155
|
+
|
135
156
|
### Template namespace
|
136
157
|
|
137
|
-
By default all
|
158
|
+
By default all Haml Coffee templates are registered under the `JST` namespace.
|
138
159
|
|
139
|
-
Example
|
160
|
+
**Example:**
|
140
161
|
|
141
|
-
A template
|
162
|
+
A template `app/assets/templates/header.hamlc` with the given content:
|
142
163
|
|
143
164
|
```haml
|
144
165
|
%header
|
145
166
|
%h2= title
|
146
167
|
```
|
147
168
|
|
148
|
-
will be accessible in your browser as `JST
|
169
|
+
will be accessible in your browser as `JST['header']`. You can now render the precompiled template and pass the data
|
170
|
+
to be rendered:
|
149
171
|
|
150
172
|
```javascript
|
151
|
-
JST
|
173
|
+
JST['header'].render({ title: 'Hello Haml Coffee' })
|
152
174
|
```
|
153
175
|
|
154
|
-
If you prefer another namespace, you can set it in your `application.rb`:
|
176
|
+
If you prefer another namespace, you can set it in your `config/application.rb`:
|
155
177
|
|
156
178
|
```ruby
|
157
|
-
config.hamlcoffee.namespace = 'HAML'
|
179
|
+
config.hamlcoffee.namespace = 'window.HAML'
|
158
180
|
```
|
159
181
|
|
182
|
+
#### Template name
|
183
|
+
|
184
|
+
The name under which the template can be addressed in the namespace depends not only from the filename, but also on
|
185
|
+
the directory name.
|
186
|
+
|
187
|
+
The following examples assumes a configured namespace `window.JST` and the asset template directory
|
188
|
+
`app/assets/templates`:
|
189
|
+
|
190
|
+
* `app/assets/templates/login.hamlc` will become `JST['login']`
|
191
|
+
* `app/assets/templates/users/new.hamlc` will become `JST['users/new']`
|
192
|
+
* `app/assets/templates/shared/form/address.hamlc` will become `JST['shared/form/address']`
|
193
|
+
|
160
194
|
### Escaping
|
161
195
|
|
162
|
-
|
163
|
-
|
196
|
+
All generated output by running CoffeeScript in your template is being escaped, but you can disable escaping of either
|
197
|
+
the attributes or the generated Html.
|
198
|
+
|
199
|
+
#### Attribute escaping
|
164
200
|
|
165
|
-
You can
|
201
|
+
You can toggle attribute escaping in your `config/application.rb`:
|
166
202
|
|
167
203
|
```ruby
|
168
|
-
config.hamlcoffee.
|
204
|
+
config.hamlcoffee.escapeAttributes = false
|
169
205
|
```
|
170
206
|
|
171
|
-
|
207
|
+
#### HTML escaping
|
208
|
+
|
209
|
+
You can toggle HTML escaping in your `config/application.rb`:
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
config.hamlcoffee.escapeHtml = false
|
213
|
+
```
|
214
|
+
|
215
|
+
#### Custom escape function
|
216
|
+
|
217
|
+
By default your code block in your Haml Coffee template will be escaped through the `HAML.escape` function that is
|
218
|
+
provided in the `hamlcoffee.js` script.
|
219
|
+
|
220
|
+
You can set another escaping function in your `config/application.rb`:
|
172
221
|
|
173
222
|
```ruby
|
174
|
-
config.hamlcoffee.
|
223
|
+
config.hamlcoffee.customHtmlEscape = 'App.myEscape'
|
175
224
|
```
|
176
225
|
|
177
|
-
Your custom escape function must take the unescaped text as parameter and returns the
|
178
|
-
The following
|
226
|
+
Your custom escape function must take the unescaped text as parameter and returns the escaped text.
|
227
|
+
The following default implementation comes with `hamlcoffee.js`:
|
179
228
|
|
180
229
|
```coffeescript
|
181
|
-
App.myEscape = (text) ->
|
230
|
+
App.myEscape = (text) ->
|
231
|
+
('' + text)
|
232
|
+
.replace(/&/g, '&')
|
233
|
+
.replace(/</g, '<')
|
234
|
+
.replace(/>/g, '>')
|
235
|
+
.replace(/"/g, '"')
|
182
236
|
```
|
183
237
|
|
184
|
-
### Global
|
238
|
+
### Global context
|
185
239
|
|
186
|
-
|
240
|
+
Haml Coffee Assets allows you to configure a global context function that gets merged into the local template context for
|
187
241
|
each template.
|
188
242
|
|
189
|
-
There is a example implementation provided in the `
|
190
|
-
from
|
243
|
+
There is a example implementation provided in the `hamlcoffee.js` that can use the `extend` like functions
|
244
|
+
from the listed frameworks to merge the global and the local conext data:
|
191
245
|
|
192
246
|
* jQuery
|
193
247
|
* Underscore.js
|
@@ -195,17 +249,28 @@ from these frameworks:
|
|
195
249
|
* MooTools
|
196
250
|
* Zepto.js
|
197
251
|
|
198
|
-
If you use one of these, than you can simply override `HAML.globals` and return the global
|
252
|
+
If you use one of these, than you can simply override `HAML.globals` and return the global context data:
|
199
253
|
|
200
254
|
```coffeescript
|
201
255
|
HAML.globals = ->
|
202
256
|
{
|
203
|
-
|
257
|
+
isAuthenticated: App.isAuthenticated()
|
204
258
|
isAdmin: App.currentUser.hasRole('admin')
|
205
259
|
}
|
206
260
|
```
|
207
261
|
|
208
|
-
|
262
|
+
Now you can use the properties from the global context in every template:
|
263
|
+
|
264
|
+
```haml
|
265
|
+
.not-found-error
|
266
|
+
%h1= I18n.t('js.app.notfound.error', { route: @route })
|
267
|
+
- if @isAuthenticated
|
268
|
+
%p= I18n.t('js.app.notfound.homepage')
|
269
|
+
- else
|
270
|
+
%p= I18n.t('js.app.notfound.login')
|
271
|
+
```
|
272
|
+
|
273
|
+
If you like to use your own implementation, simply configure your context function in your `config/application.rb`:
|
209
274
|
|
210
275
|
```ruby
|
211
276
|
config.hamlcoffee.context = 'App.globalTemplateContext'
|
@@ -217,9 +282,9 @@ or disable the global context completely:
|
|
217
282
|
config.hamlcoffee.context = false
|
218
283
|
```
|
219
284
|
|
220
|
-
Your custom context function must take the local context as parameter and returns the merged context
|
221
|
-
The following example
|
222
|
-
context:
|
285
|
+
Your custom context function must take the local context as parameter and returns the merged context data.
|
286
|
+
The following example uses the _.underscore `extend` function to merge the global context data with the
|
287
|
+
passed local context data:
|
223
288
|
|
224
289
|
```coffeescript
|
225
290
|
App.globalTemplateContext = (locals) -> _.extend({}, {
|
@@ -9,9 +9,12 @@ module HamlCoffeeAssets
|
|
9
9
|
config.hamlcoffee = ActiveSupport::OrderedOptions.new
|
10
10
|
|
11
11
|
DEFAULT_CONFIG = {
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
12
|
+
:format => 'html5',
|
13
|
+
:namespace => 'window.JST',
|
14
|
+
:escapeHtml => true,
|
15
|
+
:escapeAttributes => true,
|
16
|
+
:customHtmlEscape => 'HAML.escape',
|
17
|
+
:context => 'HAML.context'
|
15
18
|
}
|
16
19
|
|
17
20
|
# Initialize Haml Coffee Assets after Sprockets
|
@@ -26,9 +29,12 @@ module HamlCoffeeAssets
|
|
26
29
|
options = DEFAULT_CONFIG.merge(app.config.hamlcoffee)
|
27
30
|
|
28
31
|
HamlCoffee.configure do |config|
|
29
|
-
config.namespace
|
30
|
-
config.
|
31
|
-
config.
|
32
|
+
config.namespace = options[:namespace]
|
33
|
+
config.format = options[:format]
|
34
|
+
config.escapeHtml = options[:escapeHtml]
|
35
|
+
config.escapeAttributes = options[:escapeAttributes]
|
36
|
+
config.customHtmlEscape = options[:customHtmlEscape]
|
37
|
+
config.context = options[:context]
|
32
38
|
end
|
33
39
|
end
|
34
40
|
|
@@ -7,7 +7,7 @@ module HamlCoffeeAssets
|
|
7
7
|
module HamlCoffee
|
8
8
|
class << self
|
9
9
|
|
10
|
-
mattr_accessor :namespace, :
|
10
|
+
mattr_accessor :namespace, :format, :escapeHtml, :escapeAttributes, :customHtmlEscape, :context
|
11
11
|
|
12
12
|
# Configure HamlCoffee
|
13
13
|
#
|
@@ -22,7 +22,9 @@ module HamlCoffeeAssets
|
|
22
22
|
# @return [String] the compiled template in JavaScript
|
23
23
|
#
|
24
24
|
def compile(name, source)
|
25
|
-
runtime.call('HamlCoffeeAssets.compile',
|
25
|
+
runtime.call('HamlCoffeeAssets.compile',
|
26
|
+
namespace, name, source, format,
|
27
|
+
escapeHtml, escapeAttributes, customHtmlEscape, context)
|
26
28
|
end
|
27
29
|
|
28
30
|
private
|
@@ -15,15 +15,25 @@ var HamlCoffeeAssets = (function(){
|
|
15
15
|
var Compiler = require('/compiler.js');
|
16
16
|
|
17
17
|
/**
|
18
|
-
* Test if the argument is present
|
18
|
+
* Test if the string argument is present
|
19
19
|
*
|
20
|
-
* @param object [
|
20
|
+
* @param object [String] the string to test
|
21
21
|
* @return [Boolean] whether the object is present
|
22
22
|
*/
|
23
|
-
function
|
23
|
+
function isStringPresent(object) {
|
24
24
|
return toString.call(object) === '[object String]' && object.length !== 0
|
25
25
|
}
|
26
26
|
|
27
|
+
/**
|
28
|
+
* Test if the boolean argument is present
|
29
|
+
*
|
30
|
+
* @param object [Boolean] the boolean to test
|
31
|
+
* @return [Boolean] whether the object is present
|
32
|
+
*/
|
33
|
+
function isBooleanPresent(object) {
|
34
|
+
return toString.call(object) === '[object Boolean]'
|
35
|
+
}
|
36
|
+
|
27
37
|
return {
|
28
38
|
|
29
39
|
/**
|
@@ -32,28 +42,47 @@ var HamlCoffeeAssets = (function(){
|
|
32
42
|
* @param namespace [String] the template namespace
|
33
43
|
* @param name [String] the name of the template that is registered to the namespace
|
34
44
|
* @param source [String] the template source code to be compiled
|
35
|
-
* @param
|
45
|
+
* @param escapeHtml [Boolean] whether to escape HTML output by default or not
|
46
|
+
* @param escapeAttributes [Boolean] whether to escape HTML attributes output by default or not
|
47
|
+
* @param customHtmlEscape [String] the name of the function to escape the output
|
36
48
|
* @param context [String] the name of the function to merge contexts
|
37
49
|
*/
|
38
|
-
compile: function(namespace, name, source,
|
50
|
+
compile: function(namespace, name, source, format, escapeHtml, escapeAttributes, customHtmlEscape, context) {
|
39
51
|
|
40
52
|
var compiler, jst;
|
41
53
|
|
42
|
-
if (!
|
43
|
-
|
54
|
+
if (!isStringPresent(namespace)) {
|
55
|
+
namespace = 'window.HAML'
|
44
56
|
}
|
45
57
|
|
46
|
-
if (
|
47
|
-
|
48
|
-
} else {
|
49
|
-
compiler = new Compiler({ escape_html: false });
|
58
|
+
if (!isStringPresent(format)) {
|
59
|
+
format = 'html5'
|
50
60
|
}
|
51
61
|
|
62
|
+
if (!isBooleanPresent(escapeHtml)) {
|
63
|
+
escapeHtml = true
|
64
|
+
}
|
65
|
+
|
66
|
+
if (!isBooleanPresent(escapeAttributes)) {
|
67
|
+
escapeAttributes = true
|
68
|
+
}
|
69
|
+
|
70
|
+
if (!isStringPresent(customHtmlEscape)) {
|
71
|
+
customHtmlEscape = 'window.HAML.escape'
|
72
|
+
}
|
73
|
+
|
74
|
+
compiler = new Compiler({
|
75
|
+
format: format,
|
76
|
+
escapeHtml: escapeHtml,
|
77
|
+
escapeAttributes: escapeAttributes,
|
78
|
+
customHtmlEscape: customHtmlEscape
|
79
|
+
});
|
80
|
+
|
52
81
|
compiler.parse(source);
|
53
82
|
|
54
83
|
jst = CoffeeScript.compile(compiler.render(name, namespace));
|
55
84
|
|
56
|
-
if (
|
85
|
+
if (isStringPresent(context)) {
|
57
86
|
jst = jst.replace('fn.call(context);', 'fn.call(' + context +'(context));');
|
58
87
|
}
|
59
88
|
|