views:

176

answers:

2

I'm using Haml (Haml/Sass 3.0.9 - Classy Cassidy) stand-alone to generate static HTML. I want to create a shared layout template that all my other templates inherit.

Layout.haml

%html
  %head
    %title Test Template
  %body
    .Content

Content.haml

SOMEHOW INHERIT Layout.haml
SOMEHOW Change the title of the page "My Content".
  %p This is my content

To produce:

Content.html

<html>
  <head>
    <title>My Content</title>
  </head>
  <body>
    <div class="Content">
      <p>This is my content</p>
    </div>
  </body>
</html>

But this doesn't seem possible. I have seen the use of rendering partials when using Haml with Rails but can't find any solution when using Haml stand-alone.

Having to put the layout code in all of my templates would be a maintenance nightmare; so my question is how do I avoid doing this? Is there a standard way to solve this problem? Have I missed something fundamental?

I found a similar question: Rendering HAML partials from within HAMLoutside of Rails

+1  A: 

Haml is built with the assumption that it'll be used alongside some Ruby framework that provides things like partials and layouts. If you want a simple way to render static Haml code with layouts and partials, check out StaticMatic.

nex3
+1 Thanks, been looking at StaticMatic. It provides exactly what I want for layout templates but raises issues in other areas.
kjfletch
+2  A: 

I've created a prototype that does what I need. I just need to create this as a module and allow it to accept the layout template and content template as arguments (along with a dataset).

require "haml"

layoutTemplate = File.read('layout.haml')
layoutEngine = Haml::Engine.new(layoutTemplate)
layoutScope = Object.new

output = layoutEngine.render(scope=layoutScope) { |x|
  case x
    when :title
      scope.instance_variable_get("@haml_buffer").buffer << "My Title\n"
    when :content
       contentTemplate = File.read('page.haml')
       contentEngine = Haml::Engine.new(contentTemplate)
       contentOutput = contentEngine.render
      scope.instance_variable_get("@haml_buffer").buffer << contentOutput
  end
}

puts output

layout.haml

%html
  %head
    %title
      - yield :title
  %body
    .content
      - yield :content

page.haml

%h1 Testing
%p This is my test page.

Output

<html>
  <head>
    <title>
My Title
    </title>
  </head>
  <body>
    <div class='content'>
<h1>Testing</h1>
<p>This is my test page.</p>
    </div>
  </body>
</html>
kjfletch