angry_mob_common_targets 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/README.md +38 -0
- data/lib/common_mob.rb +9 -0
- data/lib/common_mob/digest.rb +43 -0
- data/lib/common_mob/erb.rb +72 -0
- data/lib/common_mob/file.rb +55 -0
- data/lib/common_mob/patch.rb +51 -0
- data/lib/common_mob/resource_locator.rb +9 -0
- data/lib/common_mob/shell.rb +323 -0
- data/lib/common_mob/template.rb +23 -0
- data/lib/common_mob/version.rb +3 -0
- data/targets/crontab_patch.rb +37 -0
- data/targets/extract.rb +40 -0
- data/targets/fetch.rb +40 -0
- data/targets/files.rb +244 -0
- data/targets/git.rb +84 -0
- data/targets/group.rb +33 -0
- data/targets/packages.rb +94 -0
- data/targets/ruby.rb +13 -0
- data/targets/services.rb +184 -0
- data/targets/shell.rb +43 -0
- data/targets/user.rb +108 -0
- data/vendor/mustache/CONTRIBUTORS +9 -0
- data/vendor/mustache/HISTORY.md +135 -0
- data/vendor/mustache/LICENSE +20 -0
- data/vendor/mustache/README.md +405 -0
- data/vendor/mustache/Rakefile +103 -0
- data/vendor/mustache/benchmarks/complex.erb +15 -0
- data/vendor/mustache/benchmarks/complex.haml +12 -0
- data/vendor/mustache/benchmarks/helper.rb +20 -0
- data/vendor/mustache/benchmarks/simple.erb +5 -0
- data/vendor/mustache/benchmarks/speed.rb +78 -0
- data/vendor/mustache/bin/mustache +90 -0
- data/vendor/mustache/contrib/mustache-mode.el +278 -0
- data/vendor/mustache/contrib/mustache.vim +69 -0
- data/vendor/mustache/examples/hash.rb +16 -0
- data/vendor/mustache/examples/hash.yml +5 -0
- data/vendor/mustache/examples/projects.mustache +26 -0
- data/vendor/mustache/examples/projects.yml +28 -0
- data/vendor/mustache/examples/self.mustache +4 -0
- data/vendor/mustache/examples/self.yml +3 -0
- data/vendor/mustache/examples/simple.mustache +10 -0
- data/vendor/mustache/examples/simple.rb +24 -0
- data/vendor/mustache/lib/mustache.rb +358 -0
- data/vendor/mustache/lib/mustache/context.rb +108 -0
- data/vendor/mustache/lib/mustache/generator.rb +160 -0
- data/vendor/mustache/lib/mustache/parser.rb +230 -0
- data/vendor/mustache/lib/mustache/sinatra.rb +180 -0
- data/vendor/mustache/lib/mustache/template.rb +59 -0
- data/vendor/mustache/lib/mustache/version.rb +3 -0
- data/vendor/mustache/lib/rack/bug/panels/mustache_panel.rb +81 -0
- data/vendor/mustache/lib/rack/bug/panels/mustache_panel/mustache_extension.rb +27 -0
- data/vendor/mustache/lib/rack/bug/panels/mustache_panel/view.mustache +46 -0
- data/vendor/mustache/man/mustache.1 +180 -0
- data/vendor/mustache/man/mustache.1.html +204 -0
- data/vendor/mustache/man/mustache.1.ron +127 -0
- data/vendor/mustache/man/mustache.5 +576 -0
- data/vendor/mustache/man/mustache.5.html +415 -0
- data/vendor/mustache/man/mustache.5.ron +324 -0
- data/vendor/mustache/mustache.gemspec +32 -0
- data/vendor/mustache/test/autoloading_test.rb +52 -0
- data/vendor/mustache/test/fixtures/comments.mustache +1 -0
- data/vendor/mustache/test/fixtures/comments.rb +14 -0
- data/vendor/mustache/test/fixtures/complex_view.mustache +17 -0
- data/vendor/mustache/test/fixtures/complex_view.rb +34 -0
- data/vendor/mustache/test/fixtures/crazy_recursive.mustache +9 -0
- data/vendor/mustache/test/fixtures/crazy_recursive.rb +31 -0
- data/vendor/mustache/test/fixtures/delimiters.mustache +8 -0
- data/vendor/mustache/test/fixtures/delimiters.rb +23 -0
- data/vendor/mustache/test/fixtures/double_section.mustache +7 -0
- data/vendor/mustache/test/fixtures/double_section.rb +14 -0
- data/vendor/mustache/test/fixtures/escaped.mustache +1 -0
- data/vendor/mustache/test/fixtures/escaped.rb +14 -0
- data/vendor/mustache/test/fixtures/inner_partial.mustache +1 -0
- data/vendor/mustache/test/fixtures/inner_partial.txt +1 -0
- data/vendor/mustache/test/fixtures/inverted_section.mustache +7 -0
- data/vendor/mustache/test/fixtures/inverted_section.rb +14 -0
- data/vendor/mustache/test/fixtures/lambda.mustache +7 -0
- data/vendor/mustache/test/fixtures/lambda.rb +31 -0
- data/vendor/mustache/test/fixtures/namespaced.mustache +1 -0
- data/vendor/mustache/test/fixtures/namespaced.rb +25 -0
- data/vendor/mustache/test/fixtures/nested_objects.mustache +17 -0
- data/vendor/mustache/test/fixtures/nested_objects.rb +35 -0
- data/vendor/mustache/test/fixtures/node.mustache +8 -0
- data/vendor/mustache/test/fixtures/partial_with_module.mustache +3 -0
- data/vendor/mustache/test/fixtures/partial_with_module.rb +37 -0
- data/vendor/mustache/test/fixtures/passenger.conf +5 -0
- data/vendor/mustache/test/fixtures/passenger.rb +27 -0
- data/vendor/mustache/test/fixtures/recursive.mustache +4 -0
- data/vendor/mustache/test/fixtures/recursive.rb +14 -0
- data/vendor/mustache/test/fixtures/simple.mustache +5 -0
- data/vendor/mustache/test/fixtures/simple.rb +26 -0
- data/vendor/mustache/test/fixtures/template_partial.mustache +2 -0
- data/vendor/mustache/test/fixtures/template_partial.rb +18 -0
- data/vendor/mustache/test/fixtures/template_partial.txt +4 -0
- data/vendor/mustache/test/fixtures/unescaped.mustache +1 -0
- data/vendor/mustache/test/fixtures/unescaped.rb +14 -0
- data/vendor/mustache/test/fixtures/utf8.mustache +3 -0
- data/vendor/mustache/test/fixtures/utf8_partial.mustache +1 -0
- data/vendor/mustache/test/helper.rb +7 -0
- data/vendor/mustache/test/mustache_test.rb +536 -0
- data/vendor/mustache/test/parser_test.rb +54 -0
- data/vendor/mustache/test/partial_test.rb +168 -0
- metadata +167 -0
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'mustache'
|
3
|
+
|
4
|
+
class Mustache
|
5
|
+
# Support for Mustache in your Sinatra app.
|
6
|
+
#
|
7
|
+
# require 'mustache/sinatra'
|
8
|
+
#
|
9
|
+
# class Hurl < Sinatra::Base
|
10
|
+
# register Mustache::Sinatra
|
11
|
+
#
|
12
|
+
# set :mustache, {
|
13
|
+
# # Should be the path to your .mustache template files.
|
14
|
+
# :templates => "path/to/mustache/templates",
|
15
|
+
#
|
16
|
+
# # Should be the path to your .rb Mustache view files.
|
17
|
+
# :views => "path/to/mustache/views",
|
18
|
+
#
|
19
|
+
# # This tells Mustache where to look for the Views module,
|
20
|
+
# # under which your View classes should live. By default it's
|
21
|
+
# # the class of your app - in this case `Hurl`. That is, for an :index
|
22
|
+
# # view Mustache will expect Hurl::Views::Index by default.
|
23
|
+
# # If our Sinatra::Base subclass was instead Hurl::App,
|
24
|
+
# # we'd want to do `set :namespace, Hurl::App`
|
25
|
+
# :namespace => Hurl
|
26
|
+
# }
|
27
|
+
#
|
28
|
+
# get '/stats' do
|
29
|
+
# mustache :stats
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# As noted above, Mustache will look for `Hurl::Views::Index` when
|
34
|
+
# `mustache :index` is called.
|
35
|
+
#
|
36
|
+
# If no `Views::Stats` class exists Mustache will render the template
|
37
|
+
# file directly.
|
38
|
+
#
|
39
|
+
# You can indeed use layouts with this library. Where you'd normally
|
40
|
+
# <%= yield %> you instead {{{yield}}} - the body of the subview is
|
41
|
+
# set to the `yield` variable and made available to you.
|
42
|
+
module Sinatra
|
43
|
+
module Helpers
|
44
|
+
# Call this in your Sinatra routes.
|
45
|
+
def mustache(template, options={}, locals={})
|
46
|
+
# Locals can be passed as options under the :locals key.
|
47
|
+
locals.update(options.delete(:locals) || {})
|
48
|
+
|
49
|
+
# Grab any user-defined settings.
|
50
|
+
if settings.respond_to?(:mustache)
|
51
|
+
options = settings.send(:mustache).merge(options)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Find and cache the view class we want. This ensures the
|
55
|
+
# compiled template is cached, too - no looking up and
|
56
|
+
# compiling templates on each page load.
|
57
|
+
klass = mustache_class(template, options)
|
58
|
+
|
59
|
+
# If they aren't explicitly disabling layouts, try to find
|
60
|
+
# one.
|
61
|
+
if options[:layout] != false
|
62
|
+
# Let the user pass in a layout name.
|
63
|
+
layout_name = options[:layout]
|
64
|
+
|
65
|
+
# If all they said was `true` (or nothing), default to :layout.
|
66
|
+
layout_name = :layout if layout_name == true || !layout_name
|
67
|
+
|
68
|
+
# If they passed a layout name use that.
|
69
|
+
layout = mustache_class(layout_name, options)
|
70
|
+
|
71
|
+
# If it's just an anonymous subclass then don't bother, otherwise
|
72
|
+
# give us a layout instance.
|
73
|
+
if layout.name && layout.name.empty?
|
74
|
+
layout = nil
|
75
|
+
else
|
76
|
+
layout = layout.new
|
77
|
+
end
|
78
|
+
|
79
|
+
# Does the view subclass the layout? If so we'll use the
|
80
|
+
# view to render the layout so you can override layout
|
81
|
+
# methods in your view - tricky.
|
82
|
+
view_subclasses_layout = klass < layout.class if layout
|
83
|
+
end
|
84
|
+
|
85
|
+
# Create a new instance for playing with.
|
86
|
+
instance = klass.new
|
87
|
+
|
88
|
+
# Copy instance variables set in Sinatra to the view
|
89
|
+
instance_variables.each do |name|
|
90
|
+
instance.instance_variable_set(name, instance_variable_get(name))
|
91
|
+
end
|
92
|
+
|
93
|
+
# Render with locals.
|
94
|
+
rendered = instance.render(instance.template, locals)
|
95
|
+
|
96
|
+
# Now render the layout with the view we just rendered, if we
|
97
|
+
# need to.
|
98
|
+
if layout && view_subclasses_layout
|
99
|
+
rendered = instance.render(layout.template, :yield => rendered)
|
100
|
+
elsif layout
|
101
|
+
rendered = layout.render(layout.template, :yield => rendered)
|
102
|
+
end
|
103
|
+
|
104
|
+
# That's it.
|
105
|
+
rendered
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns a View class for a given template name.
|
109
|
+
def mustache_class(template, options)
|
110
|
+
@template_cache.fetch(:mustache, template) do
|
111
|
+
compile_mustache(template, options)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Given a view name and settings, finds and prepares an
|
116
|
+
# appropriate view class for this view.
|
117
|
+
def compile_mustache(view, options = {})
|
118
|
+
options[:templates] ||= settings.views if settings.respond_to?(:views)
|
119
|
+
options[:namespace] ||= self.class
|
120
|
+
|
121
|
+
factory = Class.new(Mustache) do
|
122
|
+
self.view_namespace = options[:namespace]
|
123
|
+
self.view_path = options[:views]
|
124
|
+
end
|
125
|
+
|
126
|
+
# If we were handed :"positions.atom" or some such as the
|
127
|
+
# template name, we need to remember the extension.
|
128
|
+
if view.to_s.include?('.')
|
129
|
+
view, ext = view.to_s.split('.')
|
130
|
+
end
|
131
|
+
|
132
|
+
# Try to find the view class for a given view, e.g.
|
133
|
+
# :view => Hurl::Views::Index.
|
134
|
+
klass = factory.view_class(view)
|
135
|
+
|
136
|
+
# If there is no view class, issue a warning and use the one
|
137
|
+
# we just generated to cache the compiled template.
|
138
|
+
if klass == Mustache
|
139
|
+
warn "No view class found for #{view} in #{factory.view_path}"
|
140
|
+
klass = factory
|
141
|
+
|
142
|
+
# If this is a generic view class make sure we set the
|
143
|
+
# template name as it was given. That is, an anonymous
|
144
|
+
# subclass of Mustache won't know how to find the
|
145
|
+
# "index.mustache" template unless we tell it to.
|
146
|
+
klass.template_name = view.to_s
|
147
|
+
elsif ext
|
148
|
+
# We got an ext (like "atom"), so look for an "Atom" class
|
149
|
+
# under the current View's namespace.
|
150
|
+
#
|
151
|
+
# So if our template was "positions.atom", try to find
|
152
|
+
# Positions::Atom.
|
153
|
+
if klass.const_defined?(ext_class = ext.capitalize)
|
154
|
+
# Found Positions::Atom - set it
|
155
|
+
klass = klass.const_get(ext_class)
|
156
|
+
else
|
157
|
+
# Didn't find Positions::Atom - create it by creating an
|
158
|
+
# anonymous subclass of Positions and setting that to
|
159
|
+
# Positions::Atom.
|
160
|
+
new_class = Class.new(klass)
|
161
|
+
new_class.template_name = "#{view}.#{ext}"
|
162
|
+
klass.const_set(ext_class, new_class)
|
163
|
+
klass = new_class
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Set the template path and return our class.
|
168
|
+
klass.template_path = options[:templates] if options[:templates]
|
169
|
+
klass
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Called when you `register Mustache::Sinatra` in your Sinatra app.
|
174
|
+
def self.registered(app)
|
175
|
+
app.helpers Mustache::Sinatra::Helpers
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
Sinatra.register Mustache::Sinatra
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
require 'mustache/parser'
|
4
|
+
require 'mustache/generator'
|
5
|
+
|
6
|
+
class Mustache
|
7
|
+
# A Template represents a Mustache template. It compiles and caches
|
8
|
+
# a raw string template into something usable.
|
9
|
+
#
|
10
|
+
# The idea is this: when handed a Mustache template, convert it into
|
11
|
+
# a Ruby string by transforming Mustache tags into interpolated
|
12
|
+
# Ruby.
|
13
|
+
#
|
14
|
+
# You shouldn't use this class directly, instead:
|
15
|
+
#
|
16
|
+
# >> Mustache.render(template, hash)
|
17
|
+
class Template
|
18
|
+
attr_reader :source
|
19
|
+
|
20
|
+
# Expects a Mustache template as a string along with a template
|
21
|
+
# path, which it uses to find partials.
|
22
|
+
def initialize(source)
|
23
|
+
@source = source
|
24
|
+
@tmpid = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
# Renders the `@source` Mustache template using the given
|
28
|
+
# `context`, which should be a simple hash keyed with symbols.
|
29
|
+
#
|
30
|
+
# The first time a template is rendered, this method is overriden
|
31
|
+
# and from then on it is "compiled". Subsequent calls will skip
|
32
|
+
# the compilation step and run the Ruby version of the template
|
33
|
+
# directly.
|
34
|
+
def render(context)
|
35
|
+
# Compile our Mustache template into a Ruby string
|
36
|
+
compiled = "def render(ctx) #{compile} end"
|
37
|
+
|
38
|
+
# Here we rewrite ourself with the interpolated Ruby version of
|
39
|
+
# our Mustache template so subsequent calls are very fast and
|
40
|
+
# can skip the compilation stage.
|
41
|
+
instance_eval(compiled, __FILE__, __LINE__ - 1)
|
42
|
+
|
43
|
+
# Call the newly rewritten version of #render
|
44
|
+
render(context)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Does the dirty work of transforming a Mustache template into an
|
48
|
+
# interpolation-friendly Ruby string.
|
49
|
+
def compile(src = @source)
|
50
|
+
Generator.new.compile(tokens)
|
51
|
+
end
|
52
|
+
alias_method :to_s, :compile
|
53
|
+
|
54
|
+
# Returns an array of tokens for a given template.
|
55
|
+
def tokens(src = @source)
|
56
|
+
Parser.new.compile(src)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Rack
|
2
|
+
module Bug
|
3
|
+
# MustachePanel is a Rack::Bug panel which tracks the time spent rendering
|
4
|
+
# Mustache views as well as all the variables accessed during view
|
5
|
+
# rendering.
|
6
|
+
#
|
7
|
+
# It can be used to track down slow partials and ensure you're only
|
8
|
+
# generating data you need.
|
9
|
+
#
|
10
|
+
# Also, it's fun.
|
11
|
+
class MustachePanel < Panel
|
12
|
+
require "rack/bug/panels/mustache_panel/mustache_extension"
|
13
|
+
|
14
|
+
# The view is responsible for rendering our panel. While Rack::Bug
|
15
|
+
# takes care of the nav, the content rendered by View is used for
|
16
|
+
# the panel itself.
|
17
|
+
class View < Mustache
|
18
|
+
self.path = ::File.dirname(__FILE__) + '/mustache_panel'
|
19
|
+
|
20
|
+
# We track the render times of all the Mustache views on this
|
21
|
+
# page load.
|
22
|
+
def times
|
23
|
+
MustachePanel.times.map do |key, value|
|
24
|
+
{ :key => key, :value => value }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Any variables used in this page load are collected and displayed.
|
29
|
+
def variables
|
30
|
+
vars = MustachePanel.variables.sort_by { |key, _| key.to_s }
|
31
|
+
vars.map do |key, value|
|
32
|
+
# Arrays can get too huge. Just show the first 10 to give you
|
33
|
+
# some idea.
|
34
|
+
if value.is_a?(Array) && value.size > 10
|
35
|
+
size = value.size
|
36
|
+
value = value.first(10)
|
37
|
+
value << "...and #{size - 10} more"
|
38
|
+
end
|
39
|
+
|
40
|
+
{ :key => key, :value => value.inspect }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Clear out our page load-specific variables.
|
46
|
+
def self.reset
|
47
|
+
Thread.current["rack.bug.mustache.times"] = {}
|
48
|
+
Thread.current["rack.bug.mustache.vars"] = {}
|
49
|
+
end
|
50
|
+
|
51
|
+
# The view render times for this page load
|
52
|
+
def self.times
|
53
|
+
Thread.current["rack.bug.mustache.times"] ||= {}
|
54
|
+
end
|
55
|
+
|
56
|
+
# The variables used on this page load
|
57
|
+
def self.variables
|
58
|
+
Thread.current["rack.bug.mustache.vars"] ||= {}
|
59
|
+
end
|
60
|
+
|
61
|
+
# The name of this Rack::Bug panel
|
62
|
+
def name
|
63
|
+
"mustache"
|
64
|
+
end
|
65
|
+
|
66
|
+
# The string used for our tab in Rack::Bug's navigation bar
|
67
|
+
def heading
|
68
|
+
"{{%.2fms}}" % self.class.times.values.inject(0.0) do |sum, obj|
|
69
|
+
sum + obj
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# The content of our Rack::Bug panel
|
74
|
+
def content
|
75
|
+
View.render
|
76
|
+
ensure
|
77
|
+
self.class.reset
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
if defined? Mustache
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
Mustache.class_eval do
|
5
|
+
alias_method :real_render, :render
|
6
|
+
|
7
|
+
def render(*args, &block)
|
8
|
+
out = ''
|
9
|
+
Rack::Bug::MustachePanel.times[self.class.name] = Benchmark.realtime do
|
10
|
+
out = real_render(*args, &block)
|
11
|
+
end
|
12
|
+
out
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :to_html, :render
|
16
|
+
alias_method :to_text, :render
|
17
|
+
end
|
18
|
+
|
19
|
+
Mustache::Context.class_eval do
|
20
|
+
alias_method :real_get, :[]
|
21
|
+
|
22
|
+
def [](name)
|
23
|
+
return real_get(name) if name == :yield || !@mustache.respond_to?(name)
|
24
|
+
Rack::Bug::MustachePanel.variables[name] = real_get(name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
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
|
+
|
15
|
+
<h3>Render Times</h3>
|
16
|
+
|
17
|
+
<table>
|
18
|
+
<tr>
|
19
|
+
<th>View</th>
|
20
|
+
<th>Render Time</th>
|
21
|
+
</tr>
|
22
|
+
|
23
|
+
{{# times }}
|
24
|
+
<tr>
|
25
|
+
<td>{{ key }}</td>
|
26
|
+
<td>{{ value }}</td>
|
27
|
+
</tr>
|
28
|
+
{{/ times }}
|
29
|
+
</table>
|
30
|
+
|
31
|
+
<h3>Variables</h3>
|
32
|
+
|
33
|
+
<table id="mustache_variables">
|
34
|
+
<tr>
|
35
|
+
<th>Name</th>
|
36
|
+
<th>Value</th>
|
37
|
+
</tr>
|
38
|
+
|
39
|
+
{{# variables }}
|
40
|
+
<tr>
|
41
|
+
<td>{{ key }}</td>
|
42
|
+
<td class="variable">{{ value }}</td>
|
43
|
+
</tr>
|
44
|
+
{{/ variables }}
|
45
|
+
</table>
|
46
|
+
|
@@ -0,0 +1,180 @@
|
|
1
|
+
.\" generated with Ronn/v0.5
|
2
|
+
.\" http://github.com/rtomayko/ronn/
|
3
|
+
.
|
4
|
+
.TH "MUSTACHE" "1" "May 2010" "DEFUNKT" "Mustache Manual"
|
5
|
+
.
|
6
|
+
.SH "NAME"
|
7
|
+
\fBmustache\fR \-\- Mustache processor
|
8
|
+
.
|
9
|
+
.SH "SYNOPSIS"
|
10
|
+
.
|
11
|
+
.nf
|
12
|
+
|
13
|
+
mustache <YAML> <FILE>
|
14
|
+
mustache \-\-compile <FILE>
|
15
|
+
mustache \-\-tokens <FILE>
|
16
|
+
.
|
17
|
+
.fi
|
18
|
+
.
|
19
|
+
.SH "DESCRIPTION"
|
20
|
+
Mustache is a logic\-less templating system for HTML, config files,
|
21
|
+
anything.
|
22
|
+
.
|
23
|
+
.P
|
24
|
+
The \fBmustache\fR command processes a Mustache template preceded by YAML
|
25
|
+
frontmatter from standard input and prints one or more documents to
|
26
|
+
standard output.
|
27
|
+
.
|
28
|
+
.P
|
29
|
+
YAML frontmatter beings with \fB\-\-\-\fR on a single line, followed by YAML,
|
30
|
+
ending with another \fB\-\-\-\fR on a single line, e.g.
|
31
|
+
.
|
32
|
+
.IP "" 4
|
33
|
+
.
|
34
|
+
.nf
|
35
|
+
|
36
|
+
\-\-\-
|
37
|
+
names: [ {name: chris}, {name: mark}, {name: scott} ]
|
38
|
+
\-\-\-
|
39
|
+
.
|
40
|
+
.fi
|
41
|
+
.
|
42
|
+
.IP "" 0
|
43
|
+
.
|
44
|
+
.P
|
45
|
+
If you are unfamiliar with YAML, it is a superset of JSON. Valid JSON
|
46
|
+
should work fine.
|
47
|
+
.
|
48
|
+
.P
|
49
|
+
After the frontmatter should come any valid Mustache template. See
|
50
|
+
mustache(5) for an overview of Mustache templates.
|
51
|
+
.
|
52
|
+
.P
|
53
|
+
For example:
|
54
|
+
.
|
55
|
+
.IP "" 4
|
56
|
+
.
|
57
|
+
.nf
|
58
|
+
|
59
|
+
{{#names}}
|
60
|
+
Hi {{name}}!
|
61
|
+
{{/names}}
|
62
|
+
.
|
63
|
+
.fi
|
64
|
+
.
|
65
|
+
.IP "" 0
|
66
|
+
.
|
67
|
+
.P
|
68
|
+
Now let's combine them.
|
69
|
+
.
|
70
|
+
.IP "" 4
|
71
|
+
.
|
72
|
+
.nf
|
73
|
+
|
74
|
+
$ cat data.yml
|
75
|
+
\-\-\-
|
76
|
+
names: [ {name: chris}, {name: mark}, {name: scott} ]
|
77
|
+
\-\-\-
|
78
|
+
|
79
|
+
$ cat template.mustache
|
80
|
+
{{#names}}
|
81
|
+
Hi {{name}}!
|
82
|
+
{{/names}}
|
83
|
+
|
84
|
+
$ cat data.yml template.mustache | mustache
|
85
|
+
Hi chris!
|
86
|
+
Hi mark!
|
87
|
+
Hi scott!
|
88
|
+
.
|
89
|
+
.fi
|
90
|
+
.
|
91
|
+
.IP "" 0
|
92
|
+
.
|
93
|
+
.P
|
94
|
+
If you provide multiple YAML documents (as delimited by \fB\-\-\-\fR), your
|
95
|
+
template will be rendered multiple times. Like a mail merge.
|
96
|
+
.
|
97
|
+
.P
|
98
|
+
For example:
|
99
|
+
.
|
100
|
+
.IP "" 4
|
101
|
+
.
|
102
|
+
.nf
|
103
|
+
|
104
|
+
$ cat data.yml
|
105
|
+
\-\-\-
|
106
|
+
name: chris
|
107
|
+
\-\-\-
|
108
|
+
name: mark
|
109
|
+
\-\-\-
|
110
|
+
name: scott
|
111
|
+
\-\-\-
|
112
|
+
|
113
|
+
$ cat template.mustache
|
114
|
+
Hi {{name}}!
|
115
|
+
|
116
|
+
$ cat data.yml template.mustache | mustache
|
117
|
+
Hi chris!
|
118
|
+
Hi mark!
|
119
|
+
Hi scott!
|
120
|
+
.
|
121
|
+
.fi
|
122
|
+
.
|
123
|
+
.IP "" 0
|
124
|
+
.
|
125
|
+
.SH "OPTIONS"
|
126
|
+
By default \fBmustache\fR will try to render a Mustache template using the
|
127
|
+
YAML frontmatter you provide. It can do a few other things, however.
|
128
|
+
.
|
129
|
+
.TP
|
130
|
+
\fB\-c\fR, \fB\-\-compile\fR
|
131
|
+
Print the compiled Ruby version of a given template. This is the
|
132
|
+
code that is actually used when rendering a template into a
|
133
|
+
string. Useful for debugging but only if you are familiar with
|
134
|
+
Mustache's internals.
|
135
|
+
.
|
136
|
+
.TP
|
137
|
+
\fB\-t\fR, \fB\-\-tokens\fR
|
138
|
+
Print the tokenized form of a given Mustache template. This can be
|
139
|
+
used to understand how Mustache parses a template. The tokens are
|
140
|
+
handed to a generator which compiles them into a Ruby
|
141
|
+
string. Syntax errors and confused tags, therefor, can probably be
|
142
|
+
identified by examining the tokens produced.
|
143
|
+
.
|
144
|
+
.SH "INSTALLATION"
|
145
|
+
If you have RubyGems installed:
|
146
|
+
.
|
147
|
+
.IP "" 4
|
148
|
+
.
|
149
|
+
.nf
|
150
|
+
|
151
|
+
gem install mustache
|
152
|
+
.
|
153
|
+
.fi
|
154
|
+
.
|
155
|
+
.IP "" 0
|
156
|
+
.
|
157
|
+
.SH "EXAMPLES"
|
158
|
+
.
|
159
|
+
.nf
|
160
|
+
|
161
|
+
$ mustache data.yml template.mustache
|
162
|
+
$ cat data.yml | mustache \- template.mustache
|
163
|
+
$ mustache \-c template.mustache
|
164
|
+
$ cat <<data | ruby mustache \- template.mustache
|
165
|
+
\-\-\-
|
166
|
+
name: Bob
|
167
|
+
age: 30
|
168
|
+
\-\-\-
|
169
|
+
data
|
170
|
+
.
|
171
|
+
.fi
|
172
|
+
.
|
173
|
+
.SH "COPYRIGHT"
|
174
|
+
Mustache is Copyright (C) 2009 Chris Wanstrath
|
175
|
+
.
|
176
|
+
.P
|
177
|
+
Original CTemplate by Google
|
178
|
+
.
|
179
|
+
.SH "SEE ALSO"
|
180
|
+
mustache(5), mustache(7), gem(1), \fIhttp://mustache.github.com/\fR
|