# Extending ActionView::Base to support rendering themes
#
module ActionView
# Extending ActionView::Base to support rendering themes
class Base
alias_method :__render_file, :render_file
# Overrides the default Base#render_file to allow theme-specific views
def render_file(template_path, use_full_path = true, local_assigns = {})
search_path = [
"../themes/#{controller.current_theme}/views", # for components
"../../themes/#{controller.current_theme}/views", # for normal views
"../../themes/#{controller.current_theme}", # for layouts
"../../../themes/#{controller.current_theme}/views", # for mailer views
".", # fallback
".." # Mailer fallback
]
if use_full_path
search_path.each do |prefix|
theme_path = prefix +'/'+ template_path
begin
template_extension = pick_template_extension(theme_path)
# Prevent .rhtml (or any other template type) if force_liquid == true
if force_liquid? and
template_extension.to_s != 'liquid' and
prefix != '.'
raise ThemeError.new("Template '#{template_path}' must be a liquid document")
end
local_assigns['active_theme'] = get_current_theme(local_assigns)
rescue ActionView::ActionViewError => err
next
rescue ThemeError => err
# Should it raise an exception, or just call 'next' and revert to
# the default template?
raise err
end
return __render_file(theme_path, use_full_path, local_assigns)
end
raise ActionViewError, "No rhtml, rxml, or delegate template found for #{template_path}"
else
__render_file(template_path, use_full_path, local_assigns)
end
end
private
def force_liquid?
unless controller.nil?
if controller.respond_to?('force_liquid_template')
controller.force_liquid_template
end
else
false
end
end
def get_current_theme(local_assigns)
unless controller.nil?
if controller.respond_to?('current_theme')
return controller.current_theme || false
end
end
# Used with ActionMailers
if local_assigns.include? :current_theme
return local_assigns.delete :current_theme
end
end
end
end