Skip to content

Instantly share code, notes, and snippets.

@waj
Created December 18, 2014 21:47
Show Gist options
  • Save waj/c50a4a6abcb372f2c702 to your computer and use it in GitHub Desktop.
Save waj/c50a4a6abcb372f2c702 to your computer and use it in GitHub Desktop.
Crystal Layouts with ECR
macro embed_ecr(filename, io_name)
\{{ run("ecr/process", {{filename}}, {{io_name}}) }}
end
macro ecr_file(filename)
def to_s(__io__, section = nil)
embed_ecr {{filename}}, "__io__"
end
def to_s(__io__, &block)
embed_ecr {{filename}}, "__io__"
end
def to_s
String.build do |io|
to_s(io) do
yield io
end
end
end
end
require "ecr/macros"
class Layout
ecr_file "layout.ecr"
def render(view, io)
to_s(io) do |section|
view.to_s(io, section)
end
end
end
class View
macro content_for(section)
if section == {{section}}
{{yield}}
return
end
end
macro render_partial(ecr_name)
embed_ecr {{ecr_name}}, "__io__"
end
end
class Foo < View
ecr_file "foo.ecr"
def initialize(@name)
end
end
foo = Foo.new "world"
layout = Layout.new
layout.render(foo, STDOUT)
<% content_for(:header) do %>
<title>Foo</title>
<% end %>
<% render_partial "partial.ecr" %>
<html>
<header>
<% yield :header %>
</header>
<body>
<% yield %>
</body>
</html>
<div>Hello <%= @name %></div>
@jimbob88
Copy link

Sadly does not seem to work on Crystal 1.16.3

Crystal 1.16.3 (2025-06-04)

LLVM: 20.1.6
Default target: x86_64-pc-linux-gnu
crystal build *.cr                            
Showing last frame. Use --error-trace for full trace.

In foo.cr:7:14

 7 | to_s(io) do |section|
              ^
Error: too many block parameters (given 1, expected maximum 0)

With error trace:

In foo.cr:36:8

 36 | layout.render(foo, STDOUT)
             ^-----
Error: instantiating 'Layout#render(Foo, IO::FileDescriptor)'


In foo.cr:7:5

 7 | to_s(io) do |section|
     ^---
Error: instantiating 'to_s(IO::FileDescriptor)'


In foo.cr:7:14

 7 | to_s(io) do |section|
              ^
Error: too many block parameters (given 1, expected maximum 0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment