14

I'm trying to do something like this in a standalone (not rails) app:

layout.slim:

h1 Hello
.content
  = yield

show.slim:

= object.name
= object.description

I can't figure out how to specify a layout and a template. Is this possible with slim (or haml)? Thanks.

ylluminate
  • 12,102
  • 17
  • 78
  • 152
chrismealy
  • 4,830
  • 2
  • 23
  • 24

1 Answers1

23

The layout.slim file looks like:

h1 Hello
.content
  == yield

The contents.slim file looks like:

= name

This can be shortened, but I separated to individual steps for explanation purposes.

require 'slim'

# Simple class to represent an environment
class Env
  attr_accessor :name
end

# Intialize it
env = Env.new
# Set the variable we reference in contents.slim
env.name = "test this layout"

# Read the layout file in as a string
layout = File.open("layout.slim", "rb").read

# Read the contents file in as a string
contents = File.open("contents.slim", "rb").read

# Create new template object with the layout
l = Slim::Template.new { layout }

# Render the contents passing in the environment: env
# so that it can resolve: = name
c = Slim::Template.new { contents }.render(env)

# Render the layout passing it the rendered contents
# as the block. This is what yield in layout.slim will get
puts l.render{ c }

This will output:

<h1>Hello</h1><div class="content">test this layout</div>
stonean
  • 1,218
  • 1
  • 9
  • 7
  • Thanks! I got pretty close from the docs but I was confused about what scope was. I also had to do `== yield` instead of `= yield` – chrismealy Aug 14 '11 at 21:26
  • Oh yeah, sorry about that, Slim escapes HTML by default. I updated the code. – stonean Aug 14 '11 at 23:30
  • 1
    Use `File.read("layout.slim")` instead of `File.open("contents.slim", "rb").read`. The latter relies on GC/finalizer to close the file which may or may not happen whenever. – apeiros May 14 '14 at 13:04