erb_cr

Version, currently 0.1.24 versions

github.com/OrelSokolov/erb.cr

ERB syntax support for Crystal

0 stars
3 dependents
License: not declared

Nothing has been indexed for 0.1.2 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.

Installation

# Add this to your shard.yml
dependencies:
  erb_cr:
    github: OrelSokolov/erb.cr
    version: ~> 0.1.2

Then run:

shards install

shard.yml

No shard.yml has been indexed for 0.1.2. You can read it on the repository.

Dependencies

Unknown: the shard.yml for this version has not been read yet.

README

This README is the one indexed from the repository at its latest ref, not from the tag for this version.

erb.cr

Rails-compatible ERB for Crystal, compiled at build time. Templates keep ERB syntax and are compiled into native render methods via a run() template processor (the same trick as the stdlib's ECR) — no runtime parsing, no runtime interpolation.

Extracted from action_view.cr, where parity with the real ActionView 8.1.4 is verified with oracle specs (151 examples, 0 failures).

⚠️ EXPERIMENTAL FRAMEWORK, DO NOT USE IN PRODUCTION YET.

Rails semantics

  • <%= expr %> auto-escapes String; a SafeString (the SafeBuffer analog — Crystal's String cannot be subclassed) is appended raw
  • <% stmt %> is control code; <%# ... %> comments are dropped
  • Erubi trim: a newline directly after a <% %> code tag is removed
  • Block helpers work: <%= helper do %> ... <% end %> keeps the whole call as the escaped expression, the block body appends to the shared output buffer (the capture/content_for machinery)
  • Layouts use <%= yield %>; partials get typed locals and collection rendering with a 0-based <name>_counter

The expression language inside the tags is Crystal, not Ruby.

Installation

dependencies:
  erb_cr:
    github: OrelSokolov/erb.cr
shards install

Requires Crystal >= 1.21.0; no other dependencies.

Usage

Include ERB::Rendering and compile templates into methods:

require "erb_cr"

class View
  include ERB::Rendering

  getter title : String

  def initialize(@title = "Hello & welcome")
  end

  compile_template "page", "app/views/page.html.erb"
end

View.new.page.to_s # template compiled into #page at build time

Layouts (the compiled method takes a block for <%= yield %>):

compile_layout "application", "app/views/layouts/application.html.erb"

def render_in_layout(content : String) : String
  application { content }.to_s
end

Partials — locals are declared with types at compile time and become real local variables inside the compiled method:

compile_partials({
  "post" => {path: "app/views/_post.html.erb", locals: {"post" => Post}},
})

render("post", {"post" => post})                  # render partial:, locals:
render("post", collection: posts)                 # + post_counter, 0-based
render("post", collection: posts, spacer_template: "gap")

Output safety:

"<b>x</b>".html_safe?          # => false
"<b>x</b>".html_safe           # => ERB::SafeString, appended raw by <%= %>
ERB::SafeString.new("<b>") + " plain" # SafeString#+ keeps the wrapper

Why not stdlib ECR?

ECR does not escape <%= %>, has no safe-string contract, no block helpers, no trim/partials machinery. erb.cr reconstructs the ERB slice of Rails ActionView — including capture/content_for — behind a compile-time pipeline.

License

Part of the rails.cr monorepo experiments; see the repository.