18

I have a simple sinatra app that uses haml and sass for the views. One of the views (located in the views folder) is a partial for my navigation menu. I am trying to render it from index.haml but I get the following error: wrong number of arguments (1 for 2)

I am trying to render it with the following lines in index.haml

.navigation
  = render :partial => "nav"
Felix
  • 4,510
  • 2
  • 31
  • 46
Ben
  • 225
  • 1
  • 3
  • 7

4 Answers4

59

You can just use Sinatra's haml function:

= haml :nav
Jason
  • 2,025
  • 2
  • 21
  • 13
13

Or you could just do this:

helpers do
  def partial(page, options={})
    haml page.to_sym, options.merge!(:layout => false)
  end
end

And include your partial with:

= partial( "something-rad" )
jm3
  • 1,986
  • 2
  • 17
  • 21
8

Here's how I do it (more simply than @kfl62's answer, more feature-rich than @jm3's answer):

module Partials
  def partial( page, variables={} )
    haml page.to_sym, {layout:false}, variables
  end
end
helpers Partials

Use it in your Haml file like:

%ul#comments
  - @comments.each do |comment|
    %li= partial :comment, comment:comment
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • I know this is *incredibly* old Phrogz, but something I wanted to point out... "haml page.to_sym, {layout:false}, variables" should probably be "haml page.to_sym, {:layout => false}, variables" – user766987 Jul 13 '11 at 02:24
  • @user766987 What you say works for old 1.8 and 1.9; my answer is using Ruby 1.9 syntax. – Phrogz Jul 13 '11 at 02:42
7

EDIT: !!! OUTDATED !!! Read Jason's answer below!

What are you trying works in rails! Sinatra has no partial method. An implementation of partial on Sinatra looks like this (source gist) from github:

module Haml
  module Helpers
    def partial(template, *args)
      template_array = template.to_s.split('/')
      template = template_array[0..-2].join('/') + "/_#{template_array[-1]}"
      options = args.last.is_a?(Hash) ? args.pop : {}
      options.merge!(:layout => false)
      if collection = options.delete(:collection) then
        collection.inject([]) do |buffer, member|
          buffer << haml(:"#{template}", options.merge(:layout =>
          false, :locals => {template_array[-1].to_sym => member}))
        end.join("\n")
      else
        haml(:"#{template}", options)
      end
    end
  end
end

Including this method, you may call partial in your .haml files, like
= partial("partial_name")

If you want to render a view in an other view syntax is
= render(:haml,:'rel_path_to_view',:locals => {:optional => option})

Notice the syntax differences between rails and sinatra regarding render method!

Community
  • 1
  • 1
kfl62
  • 2,434
  • 4
  • 29
  • 40
  • I truly don't understand why somebody would down vote an obviously outdated answer. At the time this was the right one. LoL doesn't matter :) – kfl62 Apr 20 '13 at 14:22
  • 1
    Since I see people are still linking to this answer, I took the code from the gist and made it into a gem, which [Lenary](https://github.com/lenary) (the author of the original gist) has also since contributed to. It has subsequent improvements and specs etc https://rubygems.org/gems/sinatra-partial. – ian May 07 '13 at 11:40
  • I think it would be better to be down voted so that a better answer can be listed above it. Well, I know it actually shouldn't be done like that, but instead SO should have a feature to handle an outdated answer. – Jikku Jose Sep 02 '14 at 14:30