Class: MustacheRender::Mustache

Inherits:
Object
  • Object
show all
Defined in:
lib/mustache_render/mustache.rb,
lib/mustache_render/mustache/parser.rb,
lib/mustache_render/mustache/context.rb,
lib/mustache_render/mustache/template.rb,
lib/mustache_render/mustache/generator.rb

Defined Under Namespace

Classes: Context, ContextMiss, Data, Generator, Parser, Template

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#mediaObject (readonly)

模板的媒介



12
13
14
# File 'lib/mustache_render/mustache.rb', line 12

def media
  @media
end

Class Method Details

.classify(underscored) ⇒ Object

template_partial => TemplatePartial template/partial => Template::Partial



218
219
220
221
222
223
224
# File 'lib/mustache_render/mustache.rb', line 218

def self.classify(underscored)
  underscored.split('/').map do |namespace|
    namespace.split(/[-_]/).map do |part|
      part[0] = part[0].chr.upcase; part
    end.join
  end.join('::')
end

.compiled?Boolean

Has this template already been compiled? Compilation is somewhat expensive so it may be useful to check this before attempting it.

Returns:

  • (Boolean)


197
198
199
# File 'lib/mustache_render/mustache.rb', line 197

def self.compiled?
  @template.is_a? Template
end

.const_get!(name) ⇒ Object

Supercharged version of Module#const_get.

Always searches under Object and can find constants by their full name,

e.g. Mustache::Views::Index

name - The full constant name to find.

Returns the constant if found Returns nil if nothing is found



187
188
189
190
191
192
193
# File 'lib/mustache_render/mustache.rb', line 187

def self.const_get!(name)
  name.split('::').inject(Object) do |klass, name|
    klass.const_get(name)
  end
rescue NameError
  nil
end

.db_render(full_path, context = {}) ⇒ Object



69
70
71
# File 'lib/mustache_render/mustache.rb', line 69

def self.db_render(full_path, context={})
  self.new.db_render full_path, context
end

.file_render(name, context = {}) ⇒ Object

Given a file name and an optional context, attempts to load and render the file as a template.



58
59
60
# File 'lib/mustache_render/mustache.rb', line 58

def self.file_render(name, context = {})
  self.new.file_render name, context
end

.generate_template_name(name, template_extension) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/mustache_render/mustache.rb', line 83

def self.generate_template_name(name, template_extension)
  # 如果路径中以扩展名结尾,则直接去取这个文件
  name = name.to_s.strip

  if name.start_with?('/')
    name = name[1..-1]
  end

  if name.end_with?(template_extension)
    "#{name}"
  else
    "#{name}#{template_extension}"
  end
end

.inheritable_config_for(attr_name, default) ⇒ Object

Return the value of the configuration setting on the superclass, or return the default.

attr_name - Symbol name of the attribute. It should match the instance variable. default - Default value to use if the superclass does not respond.

Returns the inherited or default configuration setting.



262
263
264
# File 'lib/mustache_render/mustache.rb', line 262

def self.inheritable_config_for(attr_name, default)
  superclass.respond_to?(attr_name) ? superclass.send(attr_name) : default
end

.render(*args) ⇒ Object



8
9
10
# File 'lib/mustache_render/mustache.rb', line 8

def self.render(*args)
  new.render(*args)
end

.templateify(obj) ⇒ Object

Turns a string into a Mustache::Template. If passed a Template, returns it.



243
244
245
246
247
248
249
# File 'lib/mustache_render/mustache.rb', line 243

def self.templateify(obj)
  if obj.is_a?(Template)
    obj
  else
    Template.new(obj.to_s)
  end
end

.underscore(classified = name) ⇒ Object

TemplatePartial => template_partial Template::Partial => template/partial Takes a string but defaults to using the current class’ name.



229
230
231
232
233
234
235
236
237
238
239
# File 'lib/mustache_render/mustache.rb', line 229

def self.underscore(classified = name)
  classified = name if classified.to_s.empty?
  classified = superclass.name if classified.to_s.empty?

  string = classified.dup.split("#{view_namespace}::").last

  string.split('::').map do |part|
    part[0] = part[0].chr.downcase
    part.gsub(/[A-Z]/) { |s| "_#{s.downcase}"}
  end.join('/')
end

.view_class(name) ⇒ Object

When given a symbol or string representing a class, will try to produce an appropriate view class. e.g.

Mustache.view_namespace = Hurl::Views
Mustache.view_class(:Partial) # => Hurl::Views::Partial


154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/mustache_render/mustache.rb', line 154

def self.view_class(name)
  if name != classify(name.to_s)
    name = classify(name.to_s)
  end

  # Emptiness begets emptiness.
  if name.to_s == ''
    return Mustache
  end

  file_name = underscore(name)

  name = "#{view_namespace}::#{name}"

  if const = const_get!(name)
    const
  elsif File.exists?(file = "#{view_path}/#{file_name}.rb")
    require "#{file}".chomp('.rb')
    const_get!(name) || Mustache
  else
    Mustache
  end
end

Instance Method Details

#[](key) ⇒ Object

Context accessors.

view = Mustache.new view = “Jon” view.template = “Hi, {name}!” view.render # => “Hi, Jon!”



41
42
43
# File 'lib/mustache_render/mustache.rb', line 41

def [](key)
  context[key.to_sym]
end

#[]=(key, value) ⇒ Object



45
46
47
# File 'lib/mustache_render/mustache.rb', line 45

def []=(key, value)
  context[key.to_sym] = value
end

#compiled?Boolean

Has this instance or its class already compiled a template?

Returns:

  • (Boolean)


202
203
204
# File 'lib/mustache_render/mustache.rb', line 202

def compiled?
  (@template && @template.is_a?(Template)) || self.class.compiled?
end

#configObject



14
15
16
# File 'lib/mustache_render/mustache.rb', line 14

def config
  ::MustacheRender.config
end

#contextObject

A helper method which gives access to the context at a given time. Kind of a hack for now, but useful when you’re in an iterating section and want access to the hash currently being iterated over.



52
53
54
# File 'lib/mustache_render/mustache.rb', line 52

def context
  @context ||= Context.new(self)
end

#db_render(full_path, context = {}) ⇒ Object



73
74
75
76
# File 'lib/mustache_render/mustache.rb', line 73

def db_render(full_path, context={})
  @media = :db
  render(partial(full_path), context)
end

#escapeHTML(str) ⇒ Object

Override this to provide custom escaping.

class PersonView < Mustache

def escapeHTML(str)
  my_html_escape_method(str)
end

end

Returns a String



141
142
143
# File 'lib/mustache_render/mustache.rb', line 141

def escapeHTML(str)
  CGI.escapeHTML(str)
end

#file_render(name, context = {}) ⇒ Object

Given a file name and an optional context, attempts to load and render the file as a template.



64
65
66
67
# File 'lib/mustache_render/mustache.rb', line 64

def file_render(name, context = {})
  @media = :file
  render(partial(name), context)
end

#impl_read_db_template(name) ⇒ Object



78
79
80
81
# File 'lib/mustache_render/mustache.rb', line 78

def impl_read_db_template name
  db_template = ::MustacheRenderTemplate.find_with_full_path(name)
  db_template.try :content
end

#impl_read_file_template(name) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/mustache_render/mustache.rb', line 98

def impl_read_file_template name
  # TODO: 对路径的语法需要加强
  full_path = "#{config.file_template_root_path}/#{name}"

  begin
    File.read full_path
  rescue
    if config.raise_on_file_template_miss?
      raise ::MustacheRender::MustacheTemplateMissError.new("miss read file template error: #{full_path}")
    else
      ''
    end
  end
end

#partial(name) ⇒ Object

Override this in your subclass if you want to do fun things like reading templates from a database. It will be rendered by the context, so all you need to do is return a string.



124
125
126
127
128
129
130
# File 'lib/mustache_render/mustache.rb', line 124

def partial(name)
  name = self.class.generate_template_name name, config.file_template_extension

  # return self.read_template_from_media name, media
  @_cached_partials ||= {}
  (@_cached_partials[media] ||= {})[name] ||= self.read_template_from_media name, media
end

#read_template_from_media(name, media) ⇒ Object



113
114
115
116
117
118
119
# File 'lib/mustache_render/mustache.rb', line 113

def read_template_from_media name, media
  ::MustacheRender.logger.debug "MustacheRender render -> read template from #{media}: #{name}"
  case media
  when :file
    impl_read_file_template name
  end
end

#render(data = template, ctx = {}) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/mustache_render/mustache.rb', line 22

def render(data = template, ctx = {})
  self.template = data

  return self.template.render(context) if ctx == {}

  begin
    context.push(ctx)
    self.template.render(context)
  ensure
    context.pop
  end
end

#templateObject



206
207
208
209
210
# File 'lib/mustache_render/mustache.rb', line 206

def template
  return @template if @template

  self.template = ''
end

#template=(template) ⇒ Object



212
213
214
# File 'lib/mustache_render/mustache.rb', line 212

def template= template
  @template = templateify(template)
end

#templateify(obj) ⇒ Object



251
252
253
# File 'lib/mustache_render/mustache.rb', line 251

def templateify(obj)
  self.class.templateify(obj)
end