smolbars 0.1.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 +7 -0
- data/README.mdown +87 -0
- data/lib/smolbars/context.rb +43 -0
- data/lib/smolbars/template.rb +17 -0
- data/lib/smolbars/version.rb +3 -0
- data/lib/smolbars.rb +2 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ad4a5813703e27fae7f72ae855641b2cc72937e62658405c8799aa92e83497c1
|
4
|
+
data.tar.gz: 95985e08bf35a511003b1ea7965dd86086cbbe750e300803e3553f26a333f14a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: abe547c07dc93bddef2b1ef2ef2046443fae8cf4cf2b116dc66317f1526da8c52f06b255bfb1e4a09b2d40bd986fe3e9068595e49db35526e0c42e73676524bc
|
7
|
+
data.tar.gz: 277ebb7ff739b959d48f7730438f8bb1d522697277e2f85f08bf7c683932c64bcdc4416e4f861b9dcf686e05e7f51c2bd23e1599020d41148b2e19e62103f393
|
data/README.mdown
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
## Smolbars
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/handlebars)
|
4
|
+
[](https://travis-ci.org/cowboyd/handlebars.rb)
|
5
|
+
[](https://gemnasium.com/cowboyd/handlebars.rb)
|
6
|
+
|
7
|
+
|
8
|
+
This uses [mini_racer][1] to bind to the _actual_ JavaScript implementation of
|
9
|
+
[Handlebars.js][2] so that you can use it from ruby. This is a fork of [handlebars.rb][3] to
|
10
|
+
change out the deprecated [therubyracer][4] JS integration. 99% the same idea as the better-named
|
11
|
+
[minibars][5].
|
12
|
+
|
13
|
+
Please be mindful of how this library works: it brings in the full libv8 JS VM to your ruby environment. Each
|
14
|
+
`Context` is a full blown JS machine (memory management, JIT, etc). This fork does not support attaching ruby
|
15
|
+
functions to the JS VM.
|
16
|
+
|
17
|
+
Note on security: do not compile untrusted Handlebars templates. We compile Handlebars template by building ad-hoc
|
18
|
+
javascript statements, a bad actor could perform an SQL-injection like attack using the v8 environment for bad things.
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
### Simple stuff
|
23
|
+
|
24
|
+
require 'smolbars'
|
25
|
+
smolbars = Smolbars::Context.new
|
26
|
+
template = smolbars.compile("{{say}} {{what}}")
|
27
|
+
template.call(:say => "Hey", :what => "Yuh!") #=> "Hey Yuh!"
|
28
|
+
|
29
|
+
### Helpers
|
30
|
+
|
31
|
+
You must write helpers with JavaScript. The JavaScript code should include calls to the Handlebars class registration
|
32
|
+
function.
|
33
|
+
|
34
|
+
require 'smolbars'
|
35
|
+
helper = %Q{
|
36
|
+
Handlebars.registerHelper("nthTimes", function(n, options){
|
37
|
+
var buffer = "";
|
38
|
+
|
39
|
+
for(var i = 0; i < n; i++) {
|
40
|
+
buffer += options.fn();
|
41
|
+
}
|
42
|
+
|
43
|
+
return buffer;
|
44
|
+
});
|
45
|
+
}
|
46
|
+
smolbars = Smolbars::Context.new
|
47
|
+
smolbars.eval(helper)
|
48
|
+
template = smolbars.compile('{{#nthTimes 2}}yep {{/nthTimes}}hurrah!')
|
49
|
+
template.call # 'yep yep hurrah!'
|
50
|
+
|
51
|
+
### Partials
|
52
|
+
|
53
|
+
You must write partials with JavaScript. The JavaScript code should include calls to the Handlebars class registration
|
54
|
+
function.
|
55
|
+
|
56
|
+
require 'smolbars'
|
57
|
+
partial = %Q{
|
58
|
+
Handlebars.registerPartial("legend", "I am {{ who }}");
|
59
|
+
}
|
60
|
+
smolbars = Smolbars::Context.new
|
61
|
+
smolbars.eval(partial)
|
62
|
+
template = smolbars.compile('{{> legend}}')
|
63
|
+
template.call # 'I am Legend!'
|
64
|
+
|
65
|
+
### Security
|
66
|
+
|
67
|
+
In general, you should not trust user-provided templates: a template can call any method
|
68
|
+
(with no arguments) or access any property on any object in the `Smolbars::Context`.
|
69
|
+
|
70
|
+
If you'd like to render user-provided templates, you'd want to make sure you do so in a
|
71
|
+
sanitized Context, e.g. no filesystem access, read-only or no database access, etc.
|
72
|
+
|
73
|
+
You can try setting the timeout on a Smolbars::Context through kwargs that are passed to the
|
74
|
+
underlying JS instance
|
75
|
+
|
76
|
+
Smolbars::Context.new(timeout: 500)
|
77
|
+
|
78
|
+
## Test
|
79
|
+
|
80
|
+
rspec spec/
|
81
|
+
|
82
|
+
|
83
|
+
[1]: https://github.com/rubyjs/mini_racer "mini_racer"
|
84
|
+
[2]: https://github.com/wycats/handlebars.js "Handlebars JavaScript templating library"
|
85
|
+
[3]: https://github.com/cowboyd/handlebars.rb "Handlebars Ruby library"
|
86
|
+
[4]: https://github.com/cowboyd/therubyracer "The Ruby Racer"
|
87
|
+
[5]: https://github.com/combinaut/minibars "Minibars"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'handlebars/source'
|
2
|
+
require 'mini_racer'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module Smolbars
|
6
|
+
class Context
|
7
|
+
def initialize(**kwargs)
|
8
|
+
@@snapshot ||= MiniRacer::Snapshot.new(File.read(Handlebars::Source.bundled_path))
|
9
|
+
@js = MiniRacer::Context.new(kwargs.merge(snapshot: @@snapshot))
|
10
|
+
end
|
11
|
+
|
12
|
+
# Note that this is a hacky JS expression builder. We cannot pass JS AST in to mini_racer so we have to
|
13
|
+
# hope the template passed in does not form invalid Ruby. So don't use templates with backtick characters without
|
14
|
+
# manually escaping them
|
15
|
+
def compile(template)
|
16
|
+
if template.include?("`")
|
17
|
+
raise RuntimeError.new("template cannot contain a backtick character '`'")
|
18
|
+
end
|
19
|
+
handle = fn_handle
|
20
|
+
invocation = %Q{var #{handle} = Handlebars.compile(`#{template}`);}
|
21
|
+
@js.eval(invocation)
|
22
|
+
::Smolbars::Template.new(self, handle)
|
23
|
+
end
|
24
|
+
|
25
|
+
def eval(*args)
|
26
|
+
@js.eval(*args)
|
27
|
+
end
|
28
|
+
|
29
|
+
def load_pattern(pattern)
|
30
|
+
Dir[pattern].each{ |path| load(path) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def load(path)
|
34
|
+
@js.load(path)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def fn_handle
|
40
|
+
"js_fn_#{SecureRandom.hex}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Smolbars
|
2
|
+
class Template
|
3
|
+
def initialize(context, fn)
|
4
|
+
@context, @fn = context, fn
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(*args, **kwargs)
|
8
|
+
if args.length == 0
|
9
|
+
invocation = "%s(%s)" % [@fn, kwargs.to_json]
|
10
|
+
else
|
11
|
+
raise "unsupported"
|
12
|
+
invocation = "%s(%s)" % [@fn, args.to_json]
|
13
|
+
end
|
14
|
+
@context.eval(invocation)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/smolbars.rb
ADDED
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smolbars
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Charles Lowell
|
8
|
+
- Xavier Lange
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2022-02-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mini_racer
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.6'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0.6'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: handlebars-source
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '4'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '4'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '13'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '13'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rspec
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '2.0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2.0'
|
70
|
+
description: Uses the actual JavaScript implementation of Handlebars
|
71
|
+
email:
|
72
|
+
- cowboyd@thefrontside.net
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- README.mdown
|
78
|
+
- lib/smolbars.rb
|
79
|
+
- lib/smolbars/context.rb
|
80
|
+
- lib/smolbars/template.rb
|
81
|
+
- lib/smolbars/version.rb
|
82
|
+
homepage: https://github.com/cowboyd/smolbars.rb
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubygems_version: 3.2.22
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Ruby bindings for the smolbars.js templating library
|
105
|
+
test_files: []
|