Class: Tina4::Template::TwigEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/tina4/template.rb

Constant Summary collapse

FILTERS =
{
  "upper" => ->(v) { v.to_s.upcase },
  "lower" => ->(v) { v.to_s.downcase },
  "capitalize" => ->(v) { v.to_s.capitalize },
  "title" => ->(v) { v.to_s.split.map(&:capitalize).join(" ") },
  "trim" => ->(v) { v.to_s.strip },
  "length" => ->(v) { v.respond_to?(:length) ? v.length : v.to_s.length },
  "reverse" => ->(v) { v.respond_to?(:reverse) ? v.reverse : v.to_s.reverse },
  "first" => ->(v) { v.respond_to?(:first) ? v.first : v.to_s[0] },
  "last" => ->(v) { v.respond_to?(:last) ? v.last : v.to_s[-1] },
  "join" => ->(v, sep) { v.respond_to?(:join) ? v.join(sep || ", ") : v.to_s },
  "default" => ->(v, d) { (v.nil? || v.to_s.empty?) ? d : v },
  "escape" => ->(v) { TwigEngine.escape_html(v.to_s) },
  "e" => ->(v) { TwigEngine.escape_html(v.to_s) },
  "nl2br" => ->(v) { v.to_s.gsub("\n", "<br>") },
  "number_format" => ->(v, d) { format("%.#{d || 0}f", v.to_f) },
  "raw" => ->(v) { v },
  "striptags" => ->(v) { v.to_s.gsub(/<[^>]+>/, "") },
  "sort" => ->(v) { v.respond_to?(:sort) ? v.sort : v },
  "keys" => ->(v) { v.respond_to?(:keys) ? v.keys : [] },
  "values" => ->(v) { v.respond_to?(:values) ? v.values : [v] },
  "abs" => ->(v) { v.to_f.abs },
  "round" => ->(v, p) { v.to_f.round(p&.to_i || 0) },
  "url_encode" => ->(v) { URI.encode_www_form_component(v.to_s) },
  "json_encode" => ->(v) { JSON.generate(v) rescue v.to_s },
  "slice" => ->(v, s, e) { v.to_s[(s.to_i)..(e ? e.to_i : -1)] },
  "merge" => ->(v, o) { v.respond_to?(:merge) ? v.merge(o || {}) : v },
  "batch" => ->(v, s) { v.respond_to?(:each_slice) ? v.each_slice(s.to_i).to_a : [v] },
  "date" => ->(v, fmt) { TwigEngine.format_date(v, fmt) },
  "to_json" => ->(v) { JSON.generate(v).gsub("<", "\\u003c").gsub(">", "\\u003e").gsub("&", "\\u0026") rescue v.to_s },
  "tojson" => ->(v) { JSON.generate(v).gsub("<", "\\u003c").gsub(">", "\\u003e").gsub("&", "\\u0026") rescue v.to_s },
  "js_escape" => ->(v) { v.to_s.gsub("\\", "\\\\").gsub("'", "\\'").gsub('"', '\\"').gsub("\n", "\\n").gsub("\r", "\\r") }
}.freeze
HTML_ESCAPE =
{ "&" => "&amp;", "<" => "&lt;", ">" => "&gt;", '"' => "&quot;", "'" => "&#39;" }.freeze
HTML_ESCAPE_PATTERN =
/[&<>"']/

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context = {}, base_dir = nil) ⇒ TwigEngine

Returns a new instance of TwigEngine.



183
184
185
186
187
188
# File 'lib/tina4/template.rb', line 183

def initialize(context = {}, base_dir = nil)
  @context = context
  @base_dir = base_dir || Dir.pwd
  @blocks = {}
  @parent_template = nil
end

Class Method Details

.escape_html(str) ⇒ Object



214
215
216
# File 'lib/tina4/template.rb', line 214

def self.escape_html(str)
  str.gsub(HTML_ESCAPE_PATTERN, HTML_ESCAPE)
end

.format_date(value, fmt) ⇒ Object



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

def self.format_date(value, fmt)
  require "date"
  d = value.is_a?(String) ? DateTime.parse(value) : value
  d.respond_to?(:strftime) ? d.strftime(fmt || "%Y-%m-%d") : value.to_s
rescue
  value.to_s
end

Instance Method Details

#render(content) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/tina4/template.rb', line 198

def render(content)
  content = process_extends(content)
  content = process_blocks(content)
  content = process_includes(content)
  content = process_for_loops(content)
  content = process_conditionals(content)
  content = process_set(content)
  content = process_expressions(content)
  content = content.gsub(/\{%.*?%\}/m, "")
  content = content.gsub(/\{#.*?#\}/m, "")
  content
end

#reset_context(context) ⇒ Object

Reset context and blocks for reuse (avoids creating new instances in loops)



191
192
193
194
195
196
# File 'lib/tina4/template.rb', line 191

def reset_context(context)
  @context = context
  @blocks = {}
  @parent_template = nil
  self
end