Skip to content

assaydepot/smolbars

 
 

Repository files navigation

Smolbars

Gem Version Build Status Dependency Status

This uses mini_racer to bind to the actual JavaScript implementation of Handlebars.js so that you can use it from ruby. This is a fork of handlebars.rb to change out the deprecated therubyracer JS integration. 99% the same idea as the better-named minibars.

Please be mindful of how this library works: it brings in the full libv8 JS VM to your ruby environment. Each Context is a full blown JS machine (memory management, JIT, etc). This fork does not support attaching ruby functions to the JS VM.

Note on security: do not compile untrusted Handlebars templates. We compile Handlebars template by building ad-hoc javascript statements, a bad actor could perform an SQL-injection like attack using the v8 environment for bad things.

Usage

Simple stuff

require 'smolbars'
smolbars = Smolbars::Context.new
template = smolbars.compile("{{say}} {{what}}")
template.call(:say => "Hey", :what => "Yuh!") #=> "Hey Yuh!"

Helpers

You must write helpers with JavaScript. The JavaScript code should include calls to the Handlebars class registration function.

require 'smolbars'
helper = %Q{
	Handlebars.registerHelper("nthTimes", function(n, options){
	  var buffer = "";

	  for(var i = 0; i < n; i++) {
		buffer += options.fn();
	  }

	  return buffer;
	});
}
smolbars = Smolbars::Context.new
smolbars.eval(helper)
template = smolbars.compile('{{#nthTimes 2}}yep {{/nthTimes}}hurrah!')
template.call # 'yep yep hurrah!'

Partials

You must write partials with JavaScript. The JavaScript code should include calls to the Handlebars class registration function.

require 'smolbars'
partial = %Q{
	Handlebars.registerPartial("legend", "I am {{ who }}");
}
smolbars = Smolbars::Context.new
smolbars.eval(partial)
template = smolbars.compile('{{> legend}}')
template.call # 'I am Legend!'

Security

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 Smolbars::Context.

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.

You can try setting the timeout on a Smolbars::Context through kwargs that are passed to the underlying JS instance

Smolbars::Context.new(timeout: 500)

Test

rspec spec/

Tests in Docker

Building an image:

docker compose run --rm app bundle install

Running tests:

docker compose run --rm app bundle exec rspec spec/

Packages

No packages published

Languages

  • Ruby 76.4%
  • JavaScript 23.6%