Alex Rivera | Logout

Is there a way to add a custom folder to the "partials path"?

Asked 2011-09-03T15:01:54.700
9

I have several of my partials in a folder named partials, and I render them into my view using render 'partials/name_of_my_partial' and that's okay.

Anyhow, is it possible to set up things in a way than I could just use render 'name_of_my_partial' and rails automatically check this partials folder?

Right now, I'm having a Missing partial error.

Edit
Report

1 Answer

10

In rails 3.0 this a bit of a challenge, but looking into it I found that in rails 3.1, they've changed how path lookup works, making it much simpler. (I don't know what exact version they changed it though, it may have been much earlier).

In 3.1, this is relatively simple because they've introduced a way to send multiple prefixes to the path lookup. They are retrieved via the instance method _prefixes.

It's easy to tack on an arbitrary prefix to this, for all controllers, by simply overriding it in the base controller (or in a module you include in your base controller, whichever).

So in 3.1.x (where lookup uses multiple prefixes):

class ApplicationController
  ...
  protected
  def _prefixes
    @_prefixes_with_partials ||= super | %w(partials)
  end
end 

Prior to this change, a single prefix was used for lookup, which made this a lot more complicated. This may have not been the best way, but I solved this problem in the past by rescuing from missing template errors with an attempt to look up the same path with my "fallback" prefix.

In 3.0.x (where lookup uses a single path prefix)

# in an initializer
module YourAppPaths
  extend ActiveSupport::Concern

  included do
    # override the actionview base class method to wrap its paths with your
    # custom pathset class
    def self.process_view_paths(value)
      value.is_a?(::YourAppPaths::PathSet) ?
        value.dup : ::YourAppPaths::PathSet.new(Array.wrap(value))
    end
  end

  class PathSet < ::ActionView::PathSet
    # our simple subclass of pathset simply rescues and attempts to
    # find the same path under "partials", throwing out the original prefix
    def find(path, prefix, *args)
      super
    rescue ::ActionView::MissingTemplate
      super(path, "partials", *args)
    end
  end
end

ActionView::Base.end(:include, YourAppPaths)
answered 2011-09-03T16:46:42.873

Your Answer