mustache 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/HISTORY.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.4.1 (2009-10-27)
2
+
3
+ * Partials now respect the `view_namespace` setting.
4
+ * Added tpl-mode.el to contrib/ for us Emacs users.
5
+ * Rack::Bug bugfix: ensure benchmark is required before using it
6
+ * Rack::Bug: truncate too-large variables (click expands them)
7
+
1
8
  ## 0.4.0 (2009-10-27)
2
9
 
3
10
  * Stopped raising context miss exceptions by default
data/README.md CHANGED
@@ -399,6 +399,14 @@ Thanks to [Juvenn Woo](http://github.com/juvenn) for mustache.vim. It
399
399
  is included under the contrib/ directory.
400
400
 
401
401
 
402
+ Emacs
403
+ ----
404
+
405
+ tpl-mode.el is included under the contrib/ directory for any Emacs users.
406
+ Based on Google's tpl-mode for ctemplates, it adds support for Mustache's
407
+ more lenient tag values and includes a few commands for your editing pleasure.
408
+
409
+
402
410
  Installation
403
411
  ------------
404
412
 
@@ -0,0 +1,274 @@
1
+ ;;; tpl-mode.el -- a major mode for editing Google CTemplate files.
2
+ ;;; By Tony Gentilcore, July 2006
3
+ ;;;
4
+ ;;; Very minor, backwards compatible changes added for Mustache compatibility
5
+ ;;; by Chris Wanstrath, October 2009
6
+ ;;;
7
+ ;;; TO USE:
8
+ ;;; 1) Copy this file somewhere you in emacs load-path. To see what
9
+ ;;; your load-path is, run inside emacs: C-h v load-path<RET>
10
+ ;;; 2) Add the following two lines to your .emacs file:
11
+ ;;; (setq auto-mode-alist (cons '("\\.tpl$" . tpl-mode) auto-mode-alist))
12
+ ;;; (autoload 'tpl-mode "tpl-mode" "Major mode for editing CTemplate files." t)
13
+ ;;; 3) Optionally (but recommended), add this third line as well:
14
+ ;;; (add-hook 'tpl-mode-hook '(lambda () (font-lock-mode 1)))
15
+ ;;; ---
16
+ ;;;
17
+ ;;; While the CTemplate language can be used for any types of text,
18
+ ;;; this mode is intended for using CTemplate to write HTML.
19
+ ;;;
20
+ ;;; The indentation still has minor bugs due to the fact that
21
+ ;;; templates do not require valid HTML.
22
+ ;;;
23
+ ;;; It would be nice to be able to highlight attributes of HTML tags,
24
+ ;;; however this is difficult due to the presence of CTemplate symbols
25
+ ;;; embedded within attributes.
26
+
27
+ (eval-when-compile
28
+ (require 'font-lock))
29
+
30
+ (defgroup tpl-mode nil
31
+ "Major mode for editing Google CTemplate and Mustache files"
32
+ :group 'languages)
33
+
34
+ (defvar tpl-mode-version "1.1"
35
+ "Version of `tpl-mode.el'.")
36
+
37
+ (defvar tpl-mode-abbrev-table nil
38
+ "Abbrev table for use in tpl-mode buffers.")
39
+
40
+ (define-abbrev-table 'tpl-mode-abbrev-table ())
41
+
42
+ (defcustom tpl-mode-hook nil
43
+ "*Hook that runs upon entering tpl-mode."
44
+ :type 'hook)
45
+
46
+ (defvar tpl-mode-map nil
47
+ "Keymap for tpl-mode major mode")
48
+
49
+ (if tpl-mode-map
50
+ nil
51
+ (setq tpl-mode-map (make-sparse-keymap)))
52
+
53
+ (define-key tpl-mode-map "\t" 'tpl-indent-command)
54
+ (define-key tpl-mode-map "\C-m" 'reindent-then-newline-and-indent)
55
+ (define-key tpl-mode-map "\C-ct" 'tpl-insert-tag)
56
+ (define-key tpl-mode-map "\C-cv" 'tpl-insert-variable)
57
+ (define-key tpl-mode-map "\C-cs" 'tpl-insert-section)
58
+
59
+
60
+ (defvar tpl-mode-syntax-table nil
61
+ "Syntax table in use in tpl-mode buffers.")
62
+
63
+ ;; Syntax table.
64
+ (if tpl-mode-syntax-table
65
+ nil
66
+ (setq tpl-mode-syntax-table (make-syntax-table text-mode-syntax-table))
67
+ (modify-syntax-entry ?< "(> " tpl-mode-syntax-table)
68
+ (modify-syntax-entry ?> ")< " tpl-mode-syntax-table)
69
+ (modify-syntax-entry ?\" ". " tpl-mode-syntax-table)
70
+ (modify-syntax-entry ?\\ ". " tpl-mode-syntax-table)
71
+ (modify-syntax-entry ?' "w " tpl-mode-syntax-table))
72
+
73
+ (defvar tpl-basic-offset 2
74
+ "The basic indentation offset.")
75
+
76
+ ;; Constant regular expressions to identify template elements.
77
+ (defconst tpl-mode-tpl-token "[a-zA-Z][a-zA-Z0-9_:=\?!-]*?")
78
+ (defconst tpl-mode-section (concat "\\({{[#/]\s*"
79
+ tpl-mode-tpl-token
80
+ "\s*}}\\)"))
81
+ (defconst tpl-mode-open-section (concat "\\({{#\s*"
82
+ tpl-mode-tpl-token
83
+ "\s*}}\\)"))
84
+ (defconst tpl-mode-close-section (concat "{{/\\(\s*"
85
+ tpl-mode-tpl-token
86
+ "\s*\\)}}"))
87
+ ;; TODO(tonyg) Figure out a way to support multiline comments.
88
+ (defconst tpl-mode-comment "\\({{!.*?}}\\)")
89
+ (defconst tpl-mode-include (concat "\\({{>\s*"
90
+ tpl-mode-tpl-token
91
+ "\s*}}\\)"))
92
+ (defconst tpl-mode-variable (concat "\\({{\s*"
93
+ tpl-mode-tpl-token
94
+ "\s*}}\\)"))
95
+ (defconst tpl-mode-builtins
96
+ (concat
97
+ "\\({{\\<\s*"
98
+ (regexp-opt
99
+ '("BI_NEWLINE" "BI_SPACE")
100
+ t)
101
+ "\s*\\>}}\\)"))
102
+ (defconst tpl-mode-close-section-at-start (concat "^[ \t]*?"
103
+ tpl-mode-close-section))
104
+
105
+ ;; Constant regular expressions to identify html tags.
106
+ ;; Taken from HTML 4.01 / XHTML 1.0 Reference found at:
107
+ ;; http://www.w3schools.com/tags/default.asp.
108
+ (defconst tpl-mode-html-constant "\\(&#?[a-z0-9]\\{2,5\\};\\)")
109
+ (defconst tpl-mode-pair-tag
110
+ (concat
111
+ "\\<"
112
+ (regexp-opt
113
+ '("a" "abbr" "acronym" "address" "applet" "area" "b" "bdo"
114
+ "big" "blockquote" "body" "button" "caption" "center" "cite"
115
+ "code" "col" "colgroup" "dd" "del" "dfn" "dif" "div" "dl"
116
+ "dt" "em" "fieldset" "font" "form" "frame" "frameset" "h1"
117
+ "h2" "h3" "h4" "h5" "h6" "head" "html" "i" "iframe" "ins"
118
+ "kbd" "label" "legend" "li" "link" "map" "menu" "noframes"
119
+ "noscript" "object" "ol" "optgroup" "option" "p" "pre" "q"
120
+ "s" "samp" "script" "select" "small" "span" "strike"
121
+ "strong" "style" "sub" "sup" "table" "tbody" "td" "textarea"
122
+ "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var")
123
+ t)
124
+ "\\>"))
125
+ (defconst tpl-mode-standalone-tag
126
+ (concat
127
+ "\\<"
128
+ (regexp-opt
129
+ '("base" "br" "hr" "img" "input" "meta" "param")
130
+ t)
131
+ "\\>"))
132
+ (defconst tpl-mode-open-tag (concat "<\\("
133
+ tpl-mode-pair-tag
134
+ "\\)"))
135
+ (defconst tpl-mode-close-tag (concat "</\\("
136
+ tpl-mode-pair-tag
137
+ "\\)>"))
138
+ (defconst tpl-mode-close-tag-at-start (concat "^[ \t]*?"
139
+ tpl-mode-close-tag))
140
+
141
+ (defconst tpl-mode-blank-line "^[ \t]*?$")
142
+ (defconst tpl-mode-dangling-open (concat "\\("
143
+ tpl-mode-open-section
144
+ "\\)\\|\\("
145
+ tpl-mode-open-tag
146
+ "\\)[^/]*$"))
147
+
148
+ (defun tpl-indent-command ()
149
+ "Command for indenting text. Just calls tpl-indent."
150
+ (interactive)
151
+ (tpl-indent))
152
+
153
+ (defun tpl-insert-tag (tag)
154
+ "Inserts an HTML tag."
155
+ (interactive "sTag: ")
156
+ (tpl-indent)
157
+ (insert (concat "<" tag ">"))
158
+ (insert "\n\n")
159
+ (insert (concat "</" tag ">"))
160
+ (tpl-indent)
161
+ (forward-line -1)
162
+ (tpl-indent))
163
+
164
+ (defun tpl-insert-variable (variable)
165
+ "Inserts a tpl variable."
166
+ (interactive "sVariable: ")
167
+ (insert (concat "{{" variable "}}")))
168
+
169
+ (defun tpl-insert-section (section)
170
+ "Inserts a tpl section."
171
+ (interactive "sSection: ")
172
+ (tpl-indent)
173
+ (insert (concat "{{#" section "}}\n"))
174
+ (insert "\n")
175
+ (insert (concat "{{/" section "}}"))
176
+ (tpl-indent)
177
+ (forward-line -1)
178
+ (tpl-indent))
179
+
180
+ ;; Function to control indenting.
181
+ (defun tpl-indent ()
182
+ "Indent current line"
183
+ ;; Set the point to beginning of line.
184
+ (beginning-of-line)
185
+ ;; If we are at the beginning of the file, indent to 0.
186
+ (if (bobp)
187
+ (indent-line-to 0)
188
+ (let ((tag-stack 1) (close-tag "") (cur-indent 0) (old-pnt (point-marker))
189
+ (close-at-start) (open-token) (dangling-open))
190
+ (progn
191
+ ;; Determine if this is a template line or an html line.
192
+ (if (looking-at "^[ \t]*?{{")
193
+ (setq close-at-start tpl-mode-close-section-at-start
194
+ open-token "{{#")
195
+ (setq close-at-start tpl-mode-close-tag-at-start
196
+ open-token "<"))
197
+ ;; If there is a closing tag at the start of the line, search back
198
+ ;; for its opener and indent to that level.
199
+ (if (looking-at close-at-start)
200
+ (progn
201
+ (save-excursion
202
+ (setq close-tag (match-string 1))
203
+ ;; Keep searching for a match for the close tag until
204
+ ;; the tag-stack is 0.
205
+ (while (and (not (bobp))
206
+ (> tag-stack 0)
207
+ (re-search-backward (concat open-token
208
+ "\\(/?\\)"
209
+ close-tag) nil t))
210
+ (if (string-equal (match-string 1) "/")
211
+ ;; We found another close tag, so increment tag-stack.
212
+ (setq tag-stack (+ tag-stack 1))
213
+ ;; We found an open tag, so decrement tag-stack.
214
+ (setq tag-stack (- tag-stack 1)))
215
+ (setq cur-indent (current-indentation))))
216
+ (if (> tag-stack 0)
217
+ (save-excursion
218
+ (forward-line -1)
219
+ (setq cur-indent (current-indentation)))))
220
+ ;; This was not a closing tag, so we check if the previous line
221
+ ;; was an opening tag.
222
+ (save-excursion
223
+ ;; Keep moving back until we find a line that is not blank
224
+ (while (progn
225
+ (forward-line -1)
226
+ (and (not (bobp)) (looking-at tpl-mode-blank-line))))
227
+ (setq cur-indent (current-indentation))
228
+ (if (re-search-forward tpl-mode-dangling-open old-pnt t)
229
+ (setq cur-indent (+ cur-indent tpl-basic-offset)))))
230
+ ;; Finally, we execute the actual indentation.
231
+ (if (> cur-indent 0)
232
+ (indent-line-to cur-indent)
233
+ (indent-line-to 0))))))
234
+
235
+ ;; controls highlighting
236
+ (defconst tpl-mode-font-lock-keywords
237
+ (list
238
+ (list tpl-mode-section
239
+ '(1 font-lock-keyword-face))
240
+ (list tpl-mode-comment
241
+ '(1 font-lock-comment-face))
242
+ (list tpl-mode-include
243
+ '(1 font-lock-builtin-face))
244
+ (list tpl-mode-builtins
245
+ '(1 font-lock-variable-name-face))
246
+ (list tpl-mode-variable
247
+ '(1 font-lock-reference-face))
248
+ (list (concat "</?\\(" tpl-mode-pair-tag "\\)")
249
+ '(1 font-lock-function-name-face))
250
+ (list (concat "<\\(" tpl-mode-standalone-tag "\\)")
251
+ '(1 font-lock-function-name-face))
252
+ (list tpl-mode-html-constant
253
+ '(1 font-lock-variable-name-face))))
254
+
255
+ (put 'tpl-mode 'font-lock-defaults '(tpl-font-lock-keywords nil t))
256
+
257
+ (defun tpl-mode ()
258
+ "Major mode for editing Google CTemplate file."
259
+ (interactive)
260
+ (kill-all-local-variables)
261
+ (use-local-map tpl-mode-map)
262
+ (setq major-mode 'tpl-mode)
263
+ (setq mode-name "tpl-mode")
264
+ (setq local-abbrev-table tpl-mode-abbrev-table)
265
+ (setq indent-tabs-mode nil)
266
+ (set-syntax-table tpl-mode-syntax-table)
267
+ ;; show trailing whitespace, but only when the user can fix it
268
+ (setq show-trailing-whitespace (not buffer-read-only))
269
+ (make-local-variable 'indent-line-function)
270
+ (setq indent-line-function 'tpl-indent)
271
+ (setq font-lock-defaults '(tpl-mode-font-lock-keywords))
272
+ (run-hooks 'tpl-mode-hook))
273
+
274
+ (provide 'tpl-mode)
@@ -9,8 +9,19 @@ module TestViews
9
9
  "Dragon < Tiger"
10
10
  end
11
11
  end
12
- end
13
12
 
13
+ class NamespacedWithPartial < Mustache
14
+ self.template = "My opinion: {{<MyPartial}}"
15
+ end
16
+
17
+ class MyPartial < Mustache
18
+ self.template = "{{exclamation}}!"
19
+
20
+ def exclamation
21
+ :Victory
22
+ end
23
+ end
24
+ end
14
25
 
15
26
  if $0 == __FILE__
16
27
  puts TestViews::Namespaced.to_html
@@ -131,8 +131,8 @@ class Mustache
131
131
 
132
132
  # Partials are basically a way to render views from inside other views.
133
133
  def compile_partial(name)
134
- klass = Mustache.classify(name)
135
- if Object.const_defined?(klass)
134
+ klass = Mustache.view_class(name)
135
+ if klass != Mustache
136
136
  ev("#{klass}.render")
137
137
  else
138
138
  src = File.read("#{@template_path}/#{name}.#{@template_extension}")
@@ -1,3 +1,3 @@
1
1
  class Mustache
2
- Version = '0.4.0'
2
+ Version = '0.4.1'
3
3
  end
@@ -1,4 +1,6 @@
1
1
  if defined? Mustache
2
+ require 'benchmark'
3
+
2
4
  Mustache.class_eval do
3
5
  alias_method :real_render, :render
4
6
 
@@ -1,3 +1,17 @@
1
+ <script type="text/javascript">
2
+ $(function() {
3
+ $('#mustache_variables .variable').each(function() {
4
+ var el = $(this)
5
+ if (el.text().length > 500) {
6
+ var txt = el.text()
7
+ el.click(function() {
8
+ $(this).text(txt)
9
+ }).text( el.text().slice(0, 500) + '...' )
10
+ }
11
+ })
12
+ });
13
+ </script>
14
+
1
15
  <h3>Render Times</h3>
2
16
 
3
17
  <table>
@@ -16,7 +30,7 @@
16
30
 
17
31
  <h3>Variables</h3>
18
32
 
19
- <table>
33
+ <table id="mustache_variables">
20
34
  <tr>
21
35
  <th>Name</th>
22
36
  <th>Value</th>
@@ -25,7 +39,7 @@
25
39
  {{# variables }}
26
40
  <tr>
27
41
  <td>{{ key }}</td>
28
- <td>{{ value }}</td>
42
+ <td class="variable">{{ value }}</td>
29
43
  </tr>
30
44
  {{/ variables }}
31
45
  </table>
@@ -33,6 +33,15 @@ class AutoloadingTest < Test::Unit::TestCase
33
33
  assert_equal TestViews::Namespaced, klass
34
34
  assert_equal <<-end_render.strip, klass.render
35
35
  <h1>Dragon &lt; Tiger</h1>
36
+ end_render
37
+ end
38
+
39
+ def test_namespaced_partial_autoload
40
+ Mustache.view_namespace = TestViews
41
+ klass = Mustache.view_class(:namespaced_with_partial)
42
+ assert_equal TestViews::NamespacedWithPartial, klass
43
+ assert_equal <<-end_render.strip, klass.render
44
+ My opinion: Victory!
36
45
  end_render
37
46
  end
38
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mustache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
@@ -36,6 +36,7 @@ files:
36
36
  - benchmarks/simple.erb
37
37
  - benchmarks/speed.rb
38
38
  - contrib/mustache.vim
39
+ - contrib/tpl-mode.el
39
40
  - examples/comments.mustache
40
41
  - examples/comments.rb
41
42
  - examples/complex_view.mustache