module Curlybars

Curlybars is a view system based on Curly that uses Handlebars syntax.

Each view consists of two parts, a template and a presenter. The template is a valid Handlebars template.

{{#with invoice}}
  Hello {{recipient.first_name}},
  you owe us {{local_currency amount}}.
{{/with}}

In the example above `recipient.first_name` is a path `local_currency amount` is an helper

See Curlybars::Presenter for more information on presenters.

rubocop:disable Style/RegexpLiteral, Style/Semicolon

Constants

Position
VERSION

Attributes

cache[W]
configuration[W]

Public Class Methods

cache() click to toggle source
# File lib/curlybars.rb, line 87
def cache
  @cache ||= ActiveSupport::Cache::MemoryStore.new
end
compile(source, identifier = nil) click to toggle source

Compiles a Curlybars template to Ruby code.

source - The source HBS String that should be compiled. identifier - The the file name of the template being compiled (defaults to `nil`).

Returns a String containing the Ruby code.

# File lib/curlybars.rb, line 27
def compile(source, identifier = nil)
  cache_key = ["Curlybars.compile", identifier, Digest::SHA256.hexdigest(source)]

  cache.fetch(cache_key) do
    ast(transformed_source(source), identifier, run_processors: true).compile
  end
end
configuration() click to toggle source
# File lib/curlybars/configuration.rb, line 6
def self.configuration
  @configuration ||= Configuration.new
end
configure() { |configuration| ... } click to toggle source
# File lib/curlybars/configuration.rb, line 10
def self.configure
  yield(configuration)
end
global_helpers_dependency_tree() click to toggle source
# File lib/curlybars.rb, line 80
def global_helpers_dependency_tree
  @global_helpers_dependency_tree ||= begin
    classes = Curlybars.configuration.global_helpers_provider_classes
    classes.map(&:dependency_tree).inject({}, :merge)
  end
end
reset() click to toggle source
# File lib/curlybars/configuration.rb, line 14
def self.reset
  @configuration = Configuration.new
end
valid?(presenter_class, source, identifier = nil, **options) click to toggle source

Check if the source is valid for a given presenter.

presenter_class - the presenter class, used to check if the source is valid. source - The source HBS String that should be check to be valid. identifier - The the file name of the template being checked (defaults to `nil`).

Returns true if the template is valid, false otherwise.

# File lib/curlybars.rb, line 65
def valid?(presenter_class, source, identifier = nil, **options)
  errors = validate(presenter_class, source, identifier, **options)
  errors.empty?
end
validate(dependency_tree, source, identifier = nil, **options) click to toggle source

Validates the source against a presenter.

dependency_tree - a presenter dependency tree as defined in Curlybars::MethodWhitelist source - The source HBS String that should be validated. identifier - The the file name of the template being validated (defaults to `nil`).

Returns an array of Curlybars::Error::Validation

# File lib/curlybars.rb, line 42
def validate(dependency_tree, source, identifier = nil, **options)
  options.reverse_merge!(
    run_processors: true
  )

  errors = begin
    branches = [dependency_tree]
    ast(source, identifier, run_processors: options[:run_processors]).validate(branches)
  rescue Curlybars::Error::Base => ast_error
    [ast_error]
  end
  errors.flatten!
  errors.compact!
  errors
end
visit(visitor, source, identifier = nil) click to toggle source

Visit nodes in the AST.

visitor - An instance of a subclass of `Curlybars::Visitor`. source - The source HBS String used to generate an AST. identifier - The the file name of the template being checked (defaults to `nil`).

# File lib/curlybars.rb, line 75
def visit(visitor, source, identifier = nil)
  tree = ast(transformed_source(source), identifier, run_processors: true)
  visitor.accept(tree)
end

Private Class Methods

ast(source, identifier, run_processors:) click to toggle source
# File lib/curlybars.rb, line 102
def ast(source, identifier, run_processors:)
  tokens = Curlybars::Lexer.lex(source, identifier)

  Curlybars::Processor::Tilde.process!(tokens, identifier)

  if run_processors
    Curlybars.configuration.custom_processors.each do |processor|
      processor.process!(tokens, identifier)
    end
  end

  Curlybars::Parser.parse(tokens)
rescue RLTK::LexingError => lexing_error
  raise Curlybars::Error::Lex.new(source, identifier, lexing_error)
rescue RLTK::NotInLanguage => not_in_language_error
  raise Curlybars::Error::Parse.new(source, not_in_language_error)
end
transformed_source(source) click to toggle source
# File lib/curlybars.rb, line 95
def transformed_source(source)
  transformers = Curlybars.configuration.compiler_transformers
  transformers.inject(source) do |memo, transformer|
    transformer.transform(memo, identifier)
  end
end