Looks like theme_support doesn't work if route ends with an extension, like "/blog/rss.rxml", nor does it work with namespaced action mailer templates. So I had to change the actionview_ex.rb quite a bit to make it to work. here the updated code:
Changes are:
- added "../.." for namespaced mailer template
- do not pick_template_extension if extension exists in route.
- Move __render_file() into try catch block.
Updates, ActionView::TemplateError check
cool, somebody actually read my stuff! well, yes, above hack returns a very bad exception message if you have a error anywhere in ruby code or in rhtml template. Below is the code I should've put up earlier, just never got time to do it. Now here it is.
# 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/", # I don't use components
"../../themes/#{controller.current_theme}/views/", # for normal views
"../../themes/#{controller.current_theme}/", # for layouts
# "../../../themes/#{controller.current_theme}/views/", # for mailer views, not using now.
"", # fallback
"../", # Mailer fallback
"../../" # namespaced Mailer fallback
]
if use_full_path
search_path.each do |prefix|
theme_path = prefix + template_path
begin
template_path_without_extension, template_extension = path_and_extension(theme_path)
template_extension = pick_template_extension(theme_path).to_s if !template_extension
# 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)
return __render_file(theme_path, use_full_path, local_assigns)
rescue ActionView::TemplateError => err
next if err.message =~ /No such file or directory/ # for rxml templates
raise err
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
end
raise ActionViewError, "No rhtml, rxml, or delegate template found for #{template_path} in #{@base_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