handlebars-engine 0.1.0 → 0.3.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5687452a43187e2eb02f0f14b8cdfbb9326f7a45324aff57036ca6f40f1e3f1b
4
- data.tar.gz: f6f11a588f3db269fd34beb13e5c74ed0c8d15e8533e6dca1f99d6fa6737ae8f
3
+ metadata.gz: 93107a1a86ac4a02cadbbfd8221cba9515ff839e948e39dc37c61a3de1d15400
4
+ data.tar.gz: '0091362554954a3f86ab24b7c0bc701595818b9b72af4b8780bccd3d6e4193ec'
5
5
  SHA512:
6
- metadata.gz: 19f3131b68bb2b4062e30c730becb77efdf9d62b057863d2b2e2c97369ddab4216c1d08eb370070b1f9e5950ff75015414a72c6b04d8c0df277954ee2beedc9a
7
- data.tar.gz: b28fbad17ce848de5b10a6a023a6ee227c0c2175d996587338f726f320b9e9f75995b3927662005c35d3460b8c5fc2d9f27f40c962e6b4fd628f8355035b457d
6
+ metadata.gz: 7cd86ebb6fbeb64acd29dc3c4cb0f6853a7193983c53e05d32e42490a38b70f37c8d99ae7b214e3f76923c7931b46c1d3dcda1326339dfcdfa00ec29be745ae9
7
+ data.tar.gz: 6f5fd77a08e73e9f2b9f40c1c769f2eca5a0359a35e9aa02ca9fd7d430e83e8f61d6c26541f0b2bbaf5caf3ff990663962cdedfc5dd61e8892c842a8b6404fec
data/CHANGELOG.md CHANGED
@@ -6,3 +6,51 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ## [Unreleased]
9
+
10
+ ## [0.3.2] - 2022-02-17
11
+
12
+ ### Changed
13
+ - `engine`: fixed issue with memory leak ([#15](https://github.com/gi/handlebars-ruby/pull/15))
14
+
15
+ ## [0.3.1] - 2022-02-04
16
+
17
+ ### Added
18
+ - `engine`: added `Error` class
19
+ - `specs`: added tests for (pre)compiling with options
20
+
21
+ ### Changed
22
+ - `gem`/`readme`: updated description
23
+
24
+ ## [0.3.0] - 2022-01-31
25
+
26
+ ### Added
27
+ - `initialize`: add path parameter ([#5](https://github.com/gi/handlebars-ruby/pull/5))
28
+ - `register_helper`: accept multiple helpers as keyword parameters ([#6](https://github.com/gi/handlebars-ruby/pull/6))
29
+ - `register_helper`: accept javascript function as string ([#7](https://github.com/gi/handlebars-ruby/pull/7))
30
+ - `ci`: verify gem builds ([#8](https://github.com/gi/handlebars-ruby/pull/8))
31
+ - `require`: allow loading from `handlebars-engine` and `handlebars/engine` ([#8](https://github.com/gi/handlebars-ruby/pull/8))
32
+
33
+ ## [0.2.0] - 2022-01-27
34
+
35
+ This is the initial implementation, wrapping the JavaScript Handlebars.
36
+
37
+ ### Added
38
+ - `Handlebars::Engine#compile`
39
+ - `Handlebars::Engine#precompile`
40
+ - `Handlebars::Engine#template`
41
+ - `Handlebars::Engine#register_helper`
42
+ - `Handlebars::Engine#unregister_helper`
43
+ - `Handlebars::Engine#register_partial`
44
+ - `Handlebars::Engine#unregister_partial`
45
+ - `Handlebars::Engine#register_helper_missing`
46
+ - `Handlebars::Engine#unregister_helper_missing`
47
+ - `Handlebars::Engine#register_partial_missing`
48
+ - `Handlebars::Engine#unregister_partial_missing`
49
+ - `Handlebars::Engine#version`
50
+
51
+ ## [0.1.0] - 2022-01-13
52
+
53
+ This is the initial package.
54
+
55
+ ### Added
56
+ - gem init
data/README.md CHANGED
@@ -1,12 +1,22 @@
1
1
  # Handlebars::Engine
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/handlebars-engine.svg)](https://rubygems.org/gems/handlebars-engine)
4
- [![Build Status](https://github.com/gi/handlebars-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/gi/handlebars-ruby/actions/workflows/ci.yml)
4
+ [![CI Status](https://github.com/gi/handlebars-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/gi/handlebars-ruby/actions/workflows/ci.yml)
5
5
  [![Test Coverage](https://api.codeclimate.com/v1/badges/45d98ad9e12ee3384161/test_coverage)](https://codeclimate.com/github/gi/handlebars-ruby/test_coverage)
6
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/45d98ad9e12ee3384161/maintainability)](https://codeclimate.com/github/gi/handlebars-ruby/maintainability)
7
7
  [![MIT License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.txt)
8
8
 
9
- A simple interface to [Handlebars.js](https://handlebarsjs.com) for Ruby.
9
+ A complete interface to [Handlebars.js](https://handlebarsjs.com) for Ruby.
10
+
11
+ `Handlebars::Engine` provides a complete Ruby API for the official JavaScript
12
+ version of Handlebars, including the abilities to register Ruby blocks/procs as
13
+ Handlebars helper functions and to dynamically register partials.
14
+
15
+ It uses [MiniRacer](https://github.com/rubyjs/mini_racer) for the bridge between
16
+ Ruby and the V8 JavaScript engine.
17
+
18
+ `Handlebars::Engine` was created as a replacement for
19
+ [handlebars.rb](https://github.com/cowboyd/handlebars.rb).
10
20
 
11
21
  ## Installation
12
22
 
@@ -26,7 +36,170 @@ Or install it yourself as:
26
36
 
27
37
  ## Usage
28
38
 
29
- TODO: Write usage instructions here
39
+ ### Quick Start
40
+
41
+ ```ruby
42
+ handlebars = Handlebars::Engine.new
43
+ template = handlebars.compile("{{firstname}} {{lastname}}")
44
+ template.call({ firstname: "Yehuda", lastname: "Katz" })
45
+ # => "Yehuda Katz"
46
+ ```
47
+
48
+ ### Custom Helpers
49
+
50
+ Handlebars helpers can be accessed from any context in a template. You can
51
+ register a helper with the `register_helper` method:
52
+
53
+ ```ruby
54
+ handlebars = Handlebars::Engine.new
55
+ handlebars.register_helper(:loud) do |ctx, arg, opts|
56
+ arg.upcase
57
+ end
58
+ template = handlebars.compile("{{firstname}} {{loud lastname}}")
59
+ template.call({ firstname: "Yehuda", lastname: "Katz" })
60
+ # => "Yehuda KATZ"
61
+ ```
62
+
63
+ #### Helper Arguments
64
+
65
+ Helpers receive the current context as the first argument of the block.
66
+
67
+ ```ruby
68
+ handlebars = Handlebars::Engine.new
69
+ handlebars.register_helper(:full_name) do |ctx, opts|
70
+ "#{ctx["firstname"]} #{ctx["lastname"]}"
71
+ end
72
+ template = handlebars.compile("{{full_name}}")
73
+ template.call({ firstname: "Yehuda", lastname: "Katz" })
74
+ # => "Yehuda Katz"
75
+ ```
76
+
77
+ Any arguments to the helper are included as individual positional arguments.
78
+
79
+ ```ruby
80
+ handlebars = Handlebars::Engine.new
81
+ handlebars.register_helper(:join) do |ctx, *args, opts|
82
+ args.join(" ")
83
+ end
84
+ template = handlebars.compile("{{join firstname lastname}}")
85
+ template.call({ firstname: "Yehuda", lastname: "Katz" })
86
+ # => "Yehuda Katz"
87
+ ```
88
+
89
+ The last argument is a hash of options.
90
+
91
+ See https://handlebarsjs.com/guide/#custom-helpers.
92
+
93
+ ### Block Helpers
94
+
95
+ Block helpers make it possible to define custom iterators and other
96
+ functionality that can invoke the passed block with a new context.
97
+
98
+ Currently, there is a limitation with the underlying JavaScript engine: it does
99
+ not allow for reentrant calls from within attached Ruby functions: see
100
+ [MiniRacer#225](https://github.com/rubyjs/mini_racer/issues/225). Thus, the
101
+ block function returned to the helper (in `options.fn`) cannot be invoked.
102
+
103
+ Thus, for block helpers, a string of JavaScript must define the helper function:
104
+ ```ruby
105
+ handlebars = Handlebars::Engine.new
106
+ handlebars.register_helper(map: <<~JS)
107
+ function(...args) {
108
+ const ctx = this;
109
+ const opts = args.pop();
110
+ const items = args[0];
111
+ const separator = args[1];
112
+ const mapped = items.map((item) => opts.fn(item));
113
+ return mapped.join(separator);
114
+ }
115
+ JS
116
+ template = handlebars.compile("{{#map items '|'}}'{{this}}'{{/map}}")
117
+ template.call({ items: [1, 2, 3] })
118
+ # => "'1'|2'|'3'"
119
+ ```
120
+
121
+ See https://handlebarsjs.com/guide/#block-helpers.
122
+
123
+ ### Partials
124
+
125
+ Handlebars partials allow for code reuse by creating shared templates.
126
+
127
+ You can register a partial using the `register_partial` method:
128
+
129
+ ```ruby
130
+ handlebars = Handlebars::Engine.new
131
+ handlebars.register_partial(:person, "{{person.name}} is {{person.age}}.")
132
+ template = handlebars.compile("{{> person person=.}}")
133
+ template.call({ name: "Yehuda Katz", age: 20 })
134
+ # => "Yehuda Katz is 20."
135
+ ```
136
+
137
+ See https://handlebarsjs.com/guide/#partials.
138
+ See https://handlebarsjs.com/guide/partials.html.
139
+
140
+ ### Hooks
141
+
142
+ #### Helper Missing
143
+
144
+ This hook is called for a mustache or a block-statement when
145
+ * a simple mustache-expression is not a registered helper, *and*
146
+ * it is not a property of the current evaluation context.
147
+
148
+ You can add custom handling for those situations by registering a helper with
149
+ the `register_helper_missing` method:
150
+
151
+ ```ruby
152
+ handlebars = Handlebars::Engine.new
153
+ handlebars.register_helper_missing do |ctx, *args, opts|
154
+ "Missing: #{opts["name"]}(#{args.join(", ")})"
155
+ end
156
+
157
+ template = handlebars.compile("{{foo 2 true}}")
158
+ template.call
159
+ # => "Missing: foo(2, true)"
160
+
161
+ template = handlebars.compile("{{#foo true}}{{/foo}}")
162
+ template.call
163
+ # => "Missing: foo(true)"
164
+ ```
165
+
166
+ See https://handlebarsjs.com/guide/hooks.html#helpermissing.
167
+
168
+ ##### Blocks
169
+
170
+ This hook is called for a block-statement when
171
+ * a block-expression calls a helper that is not registered, *and*
172
+ * the name is a property of the current evaluation context.
173
+
174
+ You can add custom handling for those situations by registering a helper with
175
+ the `register_helper_missing` method (with a `:block` argument):
176
+
177
+ ```ruby
178
+ handlebars = Handlebars::Engine.new
179
+ handlebars.register_helper_missing(:block) do |ctx, *args, opts|
180
+ "Missing: #{opts["name"]}(#{args.join(", ")})"
181
+ end
182
+
183
+ template = handlebars.compile("{{#person}}{{name}}{{/person}}")
184
+ template.call({ person: { name: "Yehuda Katz" } })
185
+ # => "Missing: person"
186
+ ```
187
+
188
+ See https://handlebarsjs.com/guide/hooks.html#blockhelpermissing.
189
+
190
+ #### Partial Missing
191
+
192
+ This hook is called for a partial that is not registered.
193
+
194
+ ```ruby
195
+ handlebars = Handlebars::Engine.new
196
+ handlebars.register_partial_missing do |name|
197
+ "partial: #{name}"
198
+ end
199
+ ```
200
+
201
+ Note: This is not a part of the offical Handlebars API. It is provided for
202
+ convenience.
30
203
 
31
204
  ## Changelog
32
205
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Handlebars
4
+ class Engine
5
+ # A proxy for a JavaScript function defined in the context.
6
+ class Function
7
+ def initialize(context, name)
8
+ @context = context
9
+ @name = name
10
+ ObjectSpace.define_finalizer(self, self.class.finalizer(context, name))
11
+ end
12
+
13
+ def call(*args)
14
+ @context.call(@name, *args)
15
+ end
16
+
17
+ def self.finalizer(context, name)
18
+ proc {
19
+ begin
20
+ context.eval("delete #{name}")
21
+ rescue ThreadError # rubocop:disable Lint/SuppressedException
22
+ end
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,43 @@
1
+ var {
2
+ compile,
3
+ precompile,
4
+ registerPartial,
5
+ unregisterPartial,
6
+ registerHelper,
7
+ unregisterHelper,
8
+ VERSION,
9
+ } = Handlebars;
10
+
11
+ var template = (spec) => {
12
+ eval(`spec = ${spec}`);
13
+ return Handlebars.template(spec);
14
+ };
15
+
16
+ var registerPartial = Handlebars.registerPartial.bind(Handlebars);
17
+ var unregisterPartial = Handlebars.unregisterPartial.bind(Handlebars);
18
+
19
+ var registerHelper = (...args) => {
20
+ const fn = args[args.length - 1];
21
+ function wrapper(...args) {
22
+ args.unshift(this);
23
+ return fn(...args);
24
+ }
25
+ args[args.length - 1] = wrapper;
26
+ return Handlebars.registerHelper(...args);
27
+ };
28
+
29
+ var unregisterHelper = Handlebars.unregisterHelper.bind(Handlebars);
30
+
31
+ var partialMissing;
32
+
33
+ const partialsHandler = {
34
+ get(partials, name) {
35
+ const partial = partials[name] ?? partialMissing?.(name);
36
+ if (partial) {
37
+ partials[name] = partial;
38
+ }
39
+ return partial;
40
+ },
41
+ };
42
+
43
+ Handlebars.partials = new Proxy(Handlebars.partials, partialsHandler);
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Handlebars
4
- module Engine
5
- VERSION = "0.1.0"
4
+ class Engine
5
+ VERSION = "0.3.2"
6
6
  end
7
7
  end
@@ -1,9 +1,236 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "handlebars/source"
4
+ require "json"
5
+ require "mini_racer"
6
+ require "securerandom"
7
+ require_relative "engine/function"
3
8
  require_relative "engine/version"
4
9
 
5
10
  module Handlebars
6
11
  # The Handlebars engine.
7
- module Engine
12
+ #
13
+ # This API follows the JavaScript API as closely as possible:
14
+ # https://handlebarsjs.com/api-reference/.
15
+ class Engine
16
+ Error = MiniRacer::RuntimeError
17
+
18
+ # Creates a new instance.
19
+ #
20
+ # @param lazy [true, false] immediately loads and initializes the JavaScript
21
+ # environment.
22
+ # @param path [String, nil] the path to the version of Handlebars to load.
23
+ # If `nil`, the contents of `Handlebars::Source.bundled_path` is loaded.
24
+ def initialize(lazy: false, path: nil)
25
+ @path = path
26
+ init! unless lazy
27
+ end
28
+
29
+ ###################################
30
+ # Compilation
31
+ ###################################
32
+
33
+ # Compiles a template so it can be executed immediately.
34
+ #
35
+ # @param template [String] the template string to compile
36
+ # @param options [Hash] the options
37
+ # @return [Proc] the template function to call
38
+ # @see https://handlebarsjs.com/api-reference/compilation.html#handlebars-compile-template-options
39
+ def compile(*args)
40
+ call(__method__, args, assign: true)
41
+ end
42
+
43
+ # Precompiles a given template so it can be executed without compilation.
44
+ #
45
+ # @param template [String] the template string to precompiled
46
+ # @param options [Hash] the options
47
+ # @return [String] the precompiled template spec
48
+ # @see https://handlebarsjs.com/api-reference/compilation.html#handlebars-precompile-template-options
49
+ def precompile(*args)
50
+ call(__method__, args)
51
+ end
52
+
53
+ # Sets up a template that was precompiled with `precompile`.
54
+ #
55
+ # @param spec [String] the precompiled template spec
56
+ # @return [Proc] the template function to call
57
+ # @see #precompile
58
+ # @see https://handlebarsjs.com/api-reference/compilation.html#handlebars-template-templatespec
59
+ def template(*args)
60
+ call(__method__, args, assign: true)
61
+ end
62
+
63
+ ###################################
64
+ # Runtime
65
+ ###################################
66
+
67
+ # Registers helpers accessible by any template in the environment.
68
+ #
69
+ # The function can be either a proc or a string:
70
+ # * When the function is a proc, it can be either passed in as a normal
71
+ # parameter or as a block.
72
+ # * When the function is a string, it is interpreted as a JavaScript
73
+ # function.
74
+ #
75
+ # @param name [String, Symbol] the name of the helper
76
+ # @param function [Proc, String] the helper function
77
+ # @yieldparam context [Hash] the current context
78
+ # @yieldparam arguments [Object] the arguments (optional)
79
+ # @yieldparam options [Hash] the options hash (optional)
80
+ # @see https://handlebarsjs.com/api-reference/runtime.html#handlebars-registerhelper-name-helper
81
+ def register_helper(name = nil, function = nil, **helpers, &block)
82
+ helpers[name] = block || function if name
83
+ helpers.each do |n, f|
84
+ case f
85
+ when Proc
86
+ attach(n, &f)
87
+ evaluate("registerHelper('#{n}', #{n})")
88
+ when String, Symbol
89
+ evaluate("Handlebars.registerHelper('#{n}', #{f})")
90
+ end
91
+ end
92
+ end
93
+
94
+ # Unregisters a previously registered helper.
95
+ #
96
+ # @param name [String, Symbol] the name of the helper
97
+ # @see https://handlebarsjs.com/api-reference/runtime.html#handlebars-unregisterhelper-name
98
+ def unregister_helper(name)
99
+ call(:unregisterHelper, [name])
100
+ end
101
+
102
+ # Registers partials accessible by any template in the environment.
103
+ #
104
+ # @param name [String, Symbol] the name of the partial
105
+ # @param partial [String] the partial template
106
+ # @see https://handlebarsjs.com/api-reference/runtime.html#handlebars-registerpartial-name-partial
107
+ def register_partial(name = nil, partial = nil, **partials)
108
+ partials[name] = partial if name
109
+ call(:registerPartial, [partials])
110
+ end
111
+
112
+ # Unregisters a previously registered partial.
113
+ #
114
+ # @param name [String, Symbol] the name of the partial
115
+ # @see https://handlebarsjs.com/api-reference/runtime.html#handlebars-unregisterpartial-name
116
+ def unregister_partial(name)
117
+ call(:unregisterPartial, [name])
118
+ end
119
+
120
+ ###################################
121
+ # Hooks
122
+ ###################################
123
+
124
+ # Registers the hook called when a mustache or a block-statement is missing.
125
+ #
126
+ # @param type [Symbol] the type of hook to register (`:basic` or `:block`)
127
+ # @yieldparam arguments [Object] the arguments (optional)
128
+ # @yieldparam options [Hash] the options hash (optional)
129
+ # @see https://handlebarsjs.com/guide/hooks.html#helpermissing
130
+ def register_helper_missing(type = :basic, &block)
131
+ name = helper_missing_name(type)
132
+ register_helper(name, &block)
133
+ end
134
+
135
+ # Unregisters the previously registered hook.
136
+ #
137
+ # @param type [Symbol] the type of hook to register (`:basic` or `:block`)
138
+ # @see https://handlebarsjs.com/guide/hooks.html#helpermissing
139
+ def unregister_helper_missing(type = :basic)
140
+ name = helper_missing_name(type)
141
+ unregister_helper(name)
142
+ end
143
+
144
+ # Registers the hook called when a partial is missing.
145
+ #
146
+ # Note: This is not a part of the offical Handlebars API. It is provided for
147
+ # convenience.
148
+ #
149
+ # @yieldparam name [String] the name of the undefined partial
150
+ def register_partial_missing(&block)
151
+ attach(:partialMissing, &block)
152
+ end
153
+
154
+ # Unregisters the previously registered hook.
155
+ def unregister_partial_missing
156
+ evaluate("delete partialMissing")
157
+ end
158
+
159
+ ###################################
160
+ # Miscellaneous
161
+ ###################################
162
+
163
+ # Returns the version of Handlebars.
164
+ #
165
+ # @return [String] the Handlebars version.
166
+ def version
167
+ evaluate("VERSION")
168
+ end
169
+
170
+ ###################################
171
+ # Private
172
+ ###################################
173
+
174
+ private
175
+
176
+ def attach(name, &block)
177
+ init!
178
+ @context.attach(name.to_s, block)
179
+ end
180
+
181
+ def call(name, args, assign: false, eval: false)
182
+ init!
183
+ name = name.to_s
184
+
185
+ if assign || eval
186
+ call_via_eval(name, args, assign: assign)
187
+ else
188
+ @context.call(name, *args)
189
+ end
190
+ end
191
+
192
+ def call_via_eval(name, args, assign: false)
193
+ args = js_args(args)
194
+
195
+ var = assign ? "v#{SecureRandom.alphanumeric}" : nil
196
+
197
+ code = "#{name}(#{args.join(", ")})"
198
+ code = "#{var} = #{code}" if var
199
+
200
+ result = evaluate(code)
201
+
202
+ if var && result.is_a?(MiniRacer::JavaScriptFunction)
203
+ result = Function.new(@context, var)
204
+ end
205
+
206
+ result
207
+ end
208
+
209
+ def evaluate(code)
210
+ @context.eval(code)
211
+ end
212
+
213
+ def helper_missing_name(type)
214
+ case type
215
+ when :basic
216
+ :helperMissing
217
+ when :block
218
+ :blockHelperMissing
219
+ end
220
+ end
221
+
222
+ def init!
223
+ return if @init
224
+
225
+ @context = MiniRacer::Context.new
226
+ @context.load(@path || ::Handlebars::Source.bundled_path)
227
+ @context.load(File.absolute_path("engine/init.js", __dir__))
228
+
229
+ @init = true
230
+ end
231
+
232
+ def js_args(args)
233
+ args.map { |arg| JSON.generate(arg) }
234
+ end
8
235
  end
9
236
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "handlebars/engine"
metadata CHANGED
@@ -1,18 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: handlebars-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Gianos
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-13 00:00:00.000000000 Z
12
- dependencies: []
13
- description: " A simple interface to Handlebars.js for Ruby.\n"
11
+ date: 2022-02-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: handlebars-source
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mini_racer
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |2
42
+ A complete interface to Handlebars.js for Ruby.
43
+
44
+ Handlebars::Engine provides a complete Ruby API for the official JavaScript
45
+ version of Handlebars, including the abilities to register Ruby blocks/procs
46
+ as Handlebars helper functions and to dynamically register partials.
47
+
48
+ It uses MiniRacer for the bridge between Ruby and the V8 JavaScript engine.
49
+
50
+ Handlebars::Engine was created as a replacement for handlebars.rb.
14
51
  email:
15
- - zach.gianos@gmail.com
52
+ - zach.gianos+git@gmail.com
16
53
  executables:
17
54
  - handlebars
18
55
  extensions: []
@@ -22,17 +59,20 @@ files:
22
59
  - LICENSE
23
60
  - README.md
24
61
  - exe/handlebars
62
+ - lib/handlebars-engine.rb
25
63
  - lib/handlebars/engine.rb
64
+ - lib/handlebars/engine/function.rb
65
+ - lib/handlebars/engine/init.js
26
66
  - lib/handlebars/engine/version.rb
27
67
  homepage: https://github.com/gi/handlebars-ruby
28
68
  licenses:
29
69
  - MIT
30
70
  metadata:
31
71
  changelog_uri: https://github.com/gi/handlebars-ruby/CHANGELOG.md
72
+ github_repo: https://github.com/gi/handlebars-ruby
32
73
  homepage_uri: https://github.com/gi/handlebars-ruby
33
- rubygems_mfa_required: 'true'
34
74
  source_code_uri: https://github.com/gi/handlebars-ruby
35
- post_install_message:
75
+ post_install_message:
36
76
  rdoc_options: []
37
77
  require_paths:
38
78
  - lib
@@ -47,8 +87,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
87
  - !ruby/object:Gem::Version
48
88
  version: '0'
49
89
  requirements: []
50
- rubygems_version: 3.2.22
51
- signing_key:
90
+ rubygems_version: 3.3.3
91
+ signing_key:
52
92
  specification_version: 4
53
- summary: A simple interface to Handlebars.js for Ruby.
93
+ summary: A complete interface to Handlebars.js for Ruby.
54
94
  test_files: []