Partial HAML templating in Ruby without Rails

后端 未结 5 706
Happy的楠姐
Happy的楠姐 2020-12-24 08:23

I really don’t need the overhead of Rails for my very small project, so I’m trying to achieve this just using just plain Ruby and HAML.

I want to include another HAM

相关标签:
5条回答
  • 2020-12-24 08:36

    I totally recommend the Tilt gem for these things. It provides a standard interface for rendering many different template langages with the same API, lets you set custom scope and locals, lets you use yield, and is robust and fast. Sinatra is using it for templates.

    Example:

    require 'haml'
    require 'tilt'
    
    template = Tilt.new('path/to/file.haml')
    # => #<Tilt::HAMLTemplate @file="path/to/file.haml" ...>
    layout   = Tilt.new('path/to/layout.haml')
    
    output = layout.render { template.render }
    

    This lets you yield inside the layout to get the rendered template, just like Rails. As for partials, David already described a simple and nice way to go.

    But actually, if what you're writing is going to be served over HTTP, i suggest you take a look at Sinatra, which already provides templating, and has the simplest request routing you could imagine.

    0 讨论(0)
  • 2020-12-24 08:57

    I've done this before, just for a quick-and-dirty template producer. The easiest way is to just render the HAML inside the parent object:

    %p some haml that's interesting
    = Haml::Engine.new('%p this is a test').render
    %p some more template
    

    You'll more than likely want to build some methods to make this easier--a couple of helper methods. Maybe you write one called render_file that takes a filename as an argument. That method might look something like:

    def render_file(filename)
      contents = File.read(filename)
      Haml::Engine.new(contents).render
    end
    

    Then, your template would look more like:

    %p some template
    = render_file('some_filename.haml')
    %p more template
    

    Note, you will probably need to pass self to the original Haml::Engine render so that it knows how to find your render_file method.

    0 讨论(0)
  • 2020-12-24 08:57

    I've had great success just using the instructions posted by David Richards in a concatenated way, without variables, like this:

    = Haml::Engine.new(File.read('/Volumes/Project/file_to_include.haml')).render

    There's obviously a more elegant way. But for someone who just wants to include one or two files, this should work nicely. It's a drawback that all base files using these includes have to be recompiled after some changes to the latter. It might be worthwile to just use php include if the environment allows that.

    0 讨论(0)
  • 2020-12-24 08:57
    def render_file(filename)
      contents = File.read('views/'+filename)
      Haml::Engine.new(contents).render
    end
    
    0 讨论(0)
  • 2020-12-24 09:01

    (Adding this semi-redundant answer to show how one might incorporate the techniques from other answers.)

    Include something like this in your setup code to monkey-patch the Haml library.

    module Haml::Helpers
      def render_haml(filename)
        contents = File.read(Rails.root.join("app", "assets", "templates", filename))
        Haml::Engine.new(contents).render
      end
    end
    

    Then in your Haml file

    .foo
    = render_haml('partial.haml')
    .bar
    

    Obviously this is a Rails-ish example (because I wanted to use HAML in my asset pipeline instead of as views)... You will want to replace Rails.root.join(...) with a way to find filename in your project's templates or partials directory.

    0 讨论(0)
提交回复
热议问题