minibars 0.0.1.alpha → 0.2.0
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 +4 -4
- data/README.md +81 -0
- data/Rakefile +0 -6
- data/lib/handlebars.rb +8 -0
- data/lib/minibars/context.rb +82 -0
- data/lib/minibars/error.rb +3 -0
- data/lib/minibars/safe_string.rb +13 -0
- data/lib/minibars/template.rb +59 -0
- data/lib/minibars/version.rb +1 -1
- data/lib/minibars.rb +14 -1
- metadata +33 -35
- data/lib/tasks/minibars_tasks.rake +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29dfecb36dae3be442ea406501052e3df52fa71578647ad1d1e74410e49ddc92
|
4
|
+
data.tar.gz: 767861cecb3604b98b8ee615148f784eb9478a13d35bb1bad531eea9a4a631c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa966dac5605965607974dcaf968f762e5b6b0644d3b67fcfd001ba8586503b164d2a593f11051c1226c2af85f2d887a762bf5335bbdf9a2688884ad6147f289
|
7
|
+
data.tar.gz: 1c2f503e4c77cfc66e01562b61138fa3d7336dca719ade8282deff74d80c292c85caaab4424befeaafd4282584e4457ba4ff4fcbecaadabd8eed343929d96e6f
|
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+

|
2
|
+
|
3
|
+
# Minibars
|
4
|
+
|
5
|
+
A (mostly) drop-in replacement for [Handlebars.rb][3] based on [MiniRacer][1] rather than [therubyracer][2].
|
6
|
+
|
7
|
+
An appropriately revised quote from the [Handlebars.rb][3] README:
|
8
|
+
|
9
|
+
> This uses ~~therubyracer~~[MiniRacer][1] to bind to the _actual_ JavaScript implementation of [Handlebars.js](https://github.com/handlebars-lang/handlebars.js) so that you can use it from ruby.
|
10
|
+
|
11
|
+
# Why?
|
12
|
+
|
13
|
+
Minibars is a stripped down implementation of [Handlerbars.rb][3] using [MiniRacer][1]. It eschews capabilities that require two-way binding with the JS runtime, making it a good choice for those with simple Handlebars templates who need an upgrade path for their ARM64 architecture.
|
14
|
+
|
15
|
+
# Usage
|
16
|
+
|
17
|
+
## Simple Stuff
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require 'minibars'
|
21
|
+
minibars = Minibars::Context.new
|
22
|
+
template = minibars.compile("{{say}} {{what}}")
|
23
|
+
template.call(say: "Hey", what: "Yuh!") #=> "Hey Yuh!"
|
24
|
+
```
|
25
|
+
|
26
|
+
## Functions as Properties
|
27
|
+
|
28
|
+
This feature differs from [Handlebars.rb][3] since Minibars templates won't pass a `this` argument to property functions.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
template.call(say: "Hey ", what: ->{ ("yo" * 2) + "!"}) #=> "Hey yoyo!"
|
32
|
+
```
|
33
|
+
|
34
|
+
## Helpers
|
35
|
+
|
36
|
+
JavaScript helpers can be loaded as individual files or as a glob
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
minibars.load_helpers("#{__dir__}/javascripts/helpers/**/*.js")
|
40
|
+
minibars.load_helper("#{__dir__}/javascripts/helpers/admin.js")
|
41
|
+
```
|
42
|
+
|
43
|
+
## Partials
|
44
|
+
|
45
|
+
You can directly register partials
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
minibars.register_partial("whoami", "I am {{who}}")
|
49
|
+
minibars.compile("{{>whoami}}").call(who: 'Legend') #=> I am Legend
|
50
|
+
```
|
51
|
+
|
52
|
+
## SafeStrings
|
53
|
+
|
54
|
+
By default, handlebars will escape strings that are returned by your block helpers. To mark a string as safe:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
template = minibars.compile("{{safe}}")
|
58
|
+
template.call(safe: Minibars::SafeString.new("<pre>Totally Safe!<pre>"))
|
59
|
+
```
|
60
|
+
|
61
|
+
## Compatibility
|
62
|
+
|
63
|
+
`Handlebars::Context` aliases `Minibars::Context` and `Handlebars::SafeString` aliases `Minibars::SafeString` unless they are already defined.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
require 'handlebars` # Applies the compatibility layer found in lib/handlebars.rb and loads minibars
|
67
|
+
```
|
68
|
+
|
69
|
+
## Limitations
|
70
|
+
|
71
|
+
- No Ruby helpers
|
72
|
+
|
73
|
+
## Security
|
74
|
+
|
75
|
+
In general, you should not trust user-provided templates: a template can call any method (with no arguments) or access any property on any object in the `Minibars::Context`.
|
76
|
+
|
77
|
+
If you'd like to render user-provided templates, you'd want to make sure you do so in a sanitized Context, e.g. no filesystem access, read-only or no database access, etc.
|
78
|
+
|
79
|
+
[1]: https://github.com/rubyjs/mini_racer
|
80
|
+
[2]: https://github.com/rubyjs/therubyracer
|
81
|
+
[3]: https://github.com/cowboyd/handlebars.rb
|
data/Rakefile
CHANGED
@@ -4,14 +4,8 @@ rescue LoadError
|
|
4
4
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
5
|
end
|
6
6
|
|
7
|
-
APP_RAKEFILE = File.expand_path("../spec/internal/Rakefile", __FILE__)
|
8
|
-
load 'rails/tasks/engine.rake'
|
9
|
-
|
10
|
-
load 'rails/tasks/statistics.rake'
|
11
|
-
|
12
7
|
Bundler::GemHelper.install_tasks
|
13
8
|
|
14
|
-
|
15
9
|
# Add Rspec tasks
|
16
10
|
require 'rspec/core/rake_task'
|
17
11
|
|
data/lib/handlebars.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# Handlebars Compatibility
|
2
|
+
# Allows Minibars to be a drop in replacement for Handlebars (minus features that are not supported)
|
3
|
+
require 'minibars'
|
4
|
+
|
5
|
+
module Handlebars
|
6
|
+
Context = Minibars::Context unless defined? Context
|
7
|
+
SafeString = Minibars::SafeString unless defined? SafeString
|
8
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minibars
|
4
|
+
# A context for compiling handlebars templates, registering partials, and loading helpers.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# minibars = Minibars::Context.new
|
8
|
+
# template = minibars.compile("{{say}} {{what}}")
|
9
|
+
# template.call(:say => "Hey", :what => "Yuh!") #=> "Hey Yuh!"
|
10
|
+
class Context
|
11
|
+
# Instantiate a new Minibars context, optionally, specify a handlebars file to load.
|
12
|
+
#
|
13
|
+
# @param handlebars_file [String]
|
14
|
+
def initialize(handlebars_file: Handlebars::Source.bundled_path)
|
15
|
+
@js = MiniRacer::Context.new.tap do |js|
|
16
|
+
js.load(handlebars_file)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Compile the given template string and return a template object.
|
21
|
+
#
|
22
|
+
# @param template [String]
|
23
|
+
# @raise [Minibars::Error] if the template is not a string
|
24
|
+
#
|
25
|
+
# @return [Minibars::Template]
|
26
|
+
def compile(template)
|
27
|
+
Template.compile(self, @js, template)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Register the partial with the given name.
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# minibars.register_partial("whoami", "I am {{who}}")
|
34
|
+
# minibars.compile("{{>whoami}}").call(:who => 'Legend') #=> I am Legend
|
35
|
+
#
|
36
|
+
# @param name [String] partial name
|
37
|
+
# @param partial [String] partial content
|
38
|
+
#
|
39
|
+
# @raise [Minibars::Error] if the name or the partial content are not strings
|
40
|
+
# @return [Minibars::Context]
|
41
|
+
def register_partial(name, partial)
|
42
|
+
raise Error, 'Partial name should be a string' unless name.is_a?(String)
|
43
|
+
raise Error, 'Partial content should be a string' unless partial.is_a?(String)
|
44
|
+
|
45
|
+
@js.eval("Handlebars.registerPartial(#{name.to_json}, #{partial.to_json})")
|
46
|
+
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Load JavaScript handlebars helpers from the directory specified by the given glob pattern.
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# minibars.load_helpers("#{__dir__}/javascripts/helpers/**/*.js")
|
54
|
+
#
|
55
|
+
# @see https://rubyapi.org/3.1/o/dir#method-c-glob Dir.glob
|
56
|
+
#
|
57
|
+
# @param helpers_pattern [String]
|
58
|
+
#
|
59
|
+
# @return [Minibars::Context]
|
60
|
+
def load_helpers(helpers_pattern)
|
61
|
+
Dir[helpers_pattern].each do |path|
|
62
|
+
load_helper(path)
|
63
|
+
end
|
64
|
+
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
# Load a handlebars helper from a single JavaScript file.
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# minibars.load_helper("#{__dir__}/javascripts/helpers/admin.js")
|
72
|
+
#
|
73
|
+
# @param path [String]
|
74
|
+
#
|
75
|
+
# @return [Minibars::Context]
|
76
|
+
def load_helper(path)
|
77
|
+
@js.load(path)
|
78
|
+
|
79
|
+
self
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Minibars
|
2
|
+
# Mark a string as safe to avoid it being escaped by Handlebars
|
3
|
+
class SafeString
|
4
|
+
def initialize(string)
|
5
|
+
@string = string
|
6
|
+
end
|
7
|
+
|
8
|
+
# @api private
|
9
|
+
def to_json(*)
|
10
|
+
"new Handlebars.SafeString(#{@string.to_json})"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minibars
|
4
|
+
# A compiled handlebars template.
|
5
|
+
class Template
|
6
|
+
attr_reader :content, :name
|
7
|
+
|
8
|
+
# @api private
|
9
|
+
def self.compile(context, js, content)
|
10
|
+
new(context, js, content).compile
|
11
|
+
end
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
def initialize(context, js, content)
|
15
|
+
@content = content
|
16
|
+
@context = context
|
17
|
+
@js = js
|
18
|
+
@name = "Minibars_Template_#{hash_combine(@context.hash, @content.hash).abs}"
|
19
|
+
end
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def compile
|
23
|
+
raise Error, 'Template content should be a string' unless content.is_a?(String)
|
24
|
+
|
25
|
+
@js.eval("#{name} = Handlebars.compile(#{content.to_json})")
|
26
|
+
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Render the template with the given parameters.
|
31
|
+
#
|
32
|
+
# @param params [Hash]
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
def call(params = EMPTY_HASH)
|
36
|
+
@js.eval("#{name}(#{JSON.generate process_params(params)})")
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def process_params(params)
|
42
|
+
return params if params.empty?
|
43
|
+
|
44
|
+
params.transform_values do |value|
|
45
|
+
if value.respond_to?(:call)
|
46
|
+
value.call
|
47
|
+
else
|
48
|
+
value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def hash_combine(seed, hash)
|
54
|
+
# a la boost, a la clojure
|
55
|
+
seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2)
|
56
|
+
seed
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/minibars/version.rb
CHANGED
data/lib/minibars.rb
CHANGED
@@ -1,4 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
4
|
+
require 'mini_racer'
|
5
|
+
require 'handlebars/source'
|
6
|
+
|
7
|
+
require 'minibars/error'
|
8
|
+
require 'minibars/context'
|
9
|
+
require 'minibars/template'
|
10
|
+
|
11
|
+
require_relative 'minibars/safe_string'
|
12
|
+
|
13
|
+
# Make use of Handlebars templates from Ruby using mini_racer
|
3
14
|
module Minibars
|
15
|
+
EMPTY_HASH = {}.freeze
|
16
|
+
private_constant :EMPTY_HASH
|
4
17
|
end
|
metadata
CHANGED
@@ -1,59 +1,46 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minibars
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Jakobsen
|
8
|
+
- Delon Newman
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2024-07-09 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: mini_racer
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
18
|
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
+
version: 0.6.4
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
25
|
- - "~>"
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
27
|
+
version: 0.6.4
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
+
name: handlebars-source
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- - "
|
32
|
+
- - ">="
|
32
33
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
-
type: :
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.3'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: mysql2
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.4.10
|
48
|
-
type: :development
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
49
36
|
prerelease: false
|
50
37
|
version_requirements: !ruby/object:Gem::Requirement
|
51
38
|
requirements:
|
52
|
-
- - "
|
39
|
+
- - ">="
|
53
40
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0
|
41
|
+
version: '0'
|
55
42
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: rspec
|
43
|
+
name: rspec
|
57
44
|
requirement: !ruby/object:Gem::Requirement
|
58
45
|
requirements:
|
59
46
|
- - "~>"
|
@@ -66,25 +53,36 @@ dependencies:
|
|
66
53
|
- - "~>"
|
67
54
|
- !ruby/object:Gem::Version
|
68
55
|
version: '3.7'
|
69
|
-
description: Minibars is a stripped down
|
56
|
+
description: Minibars is a stripped down implementation of Handlerbars using MiniRacer.
|
70
57
|
It eschews capabilities that require two-way binding with the JS runtime, making
|
71
|
-
it a good
|
72
|
-
path for their
|
58
|
+
it a good choice for those with simple Handlebars templates who need an upgrade
|
59
|
+
path for their ARM64 architecture.
|
73
60
|
email:
|
74
61
|
- nicholas@combinaut.com
|
62
|
+
- contact@delonnewman.name
|
75
63
|
executables: []
|
76
64
|
extensions: []
|
77
65
|
extra_rdoc_files: []
|
78
66
|
files:
|
79
67
|
- MIT-LICENSE
|
68
|
+
- README.md
|
80
69
|
- Rakefile
|
70
|
+
- lib/handlebars.rb
|
81
71
|
- lib/minibars.rb
|
72
|
+
- lib/minibars/context.rb
|
73
|
+
- lib/minibars/error.rb
|
74
|
+
- lib/minibars/safe_string.rb
|
75
|
+
- lib/minibars/template.rb
|
82
76
|
- lib/minibars/version.rb
|
83
|
-
- lib/tasks/minibars_tasks.rake
|
84
77
|
homepage: https://github.com/combinaut/minibars
|
85
78
|
licenses:
|
86
79
|
- MIT
|
87
|
-
metadata:
|
80
|
+
metadata:
|
81
|
+
allowed_push_host: https://rubygems.org
|
82
|
+
homepage_uri: https://github.com/combinaut/minibars
|
83
|
+
source_code_uri: https://github.com/combinaut/minibars
|
84
|
+
changelog_uri: https://github.com/combinaut/minibars/blob/master/CHANGELOG.md
|
85
|
+
documentation_uri: https://www.rubydoc.info/gems/minibars
|
88
86
|
post_install_message:
|
89
87
|
rdoc_options: []
|
90
88
|
require_paths:
|
@@ -96,12 +94,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
94
|
version: '0'
|
97
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
96
|
requirements:
|
99
|
-
- - "
|
97
|
+
- - ">="
|
100
98
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
99
|
+
version: '0'
|
102
100
|
requirements: []
|
103
|
-
rubygems_version: 3.
|
101
|
+
rubygems_version: 3.5.13
|
104
102
|
signing_key:
|
105
103
|
specification_version: 4
|
106
|
-
summary: Minibars is a stripped down
|
104
|
+
summary: Minibars is a stripped down implementation of Handlerbars using MiniRacer.
|
107
105
|
test_files: []
|