Articles tagged theme

more problem and hacks in theme_support plugin
Dorren_mii_thumb by dorren, 11/09/2007
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:
  1. added "../.." for namespaced mailer template
  2. do not pick_template_extension if extension exists in route.
  3. 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
Views: 2123   Replies: 2   Last Reply: dorren, 12/04/2007.     Tags: theme
Add theme support to rails app
Dorren_mii_thumb by dorren, 10/24/2007
If you want to add theme support to your rails app, easiest way is to use Matt McCray's theme_support plugin. just do "script/plugin install http://mattmccray.com/svn/rails/plugins/theme_support/" to get it.

1. The Problem

But it doesn't work out of box. when you start the server, you'll get error like:
theme_app/vendor/plugins/theme_support/lib/patches/routeset_ex.rb:27:in `create_theme_routes': 
undefined method `named_route' for #<actioncontroller::routing::routeset:0xb74da758> (NoMethodError)
        from theme_app/vendor/plugins/theme_support/lib/patches/routeset_ex.rb:13:in `draw'
        from ./script/../config/../config/routes.rb:1
        ...
Since the last update of the plugin was April 2006, and now is Oct 2007, so changes of rails internal must made the plugin incompatible. On Matt's blog, someone suggested a workaround, to change the route function calls in plugin's route patch (lib/patch/routeset_ex.rb). But I choose to take a more conservative approach, not to patch routing at all.

2. The Fix

So here are the changes I made to the plugin to make it futureproof.
  • Disable routing patch. comment out "require 'patches/routeset_ex'" line in theme_support/init.rb
  • Add theme routes into config/routes.rb
    
       map.theme_images "/themes/:theme/images/*filename", :controller=>'theme', :action=>'images'
       map.theme_stylesheets "/themes/:theme/stylesheets/*filename", :controller=>'theme', :action=>'stylesheets'
       map.theme_javascript "/themes/:theme/javascript/*filename", :controller=>'theme', :action=>'javascript'
    
       map.connect "/themes/*whatever", :controller=>'theme', :action=>'error'

Now start the server, and it shall work.

3. Usage

To create a new theme, do "script/generate theme YOUR_THEME_NAME", see plugin's readme for more usage.

4. Related pages

http://code.google.com/p/rails-multisite/
http://wiki.rubyonrails.org/rails/pages/View+Extensions if it's not down.
Views: 1634   Replies: 0   Tags: theme
 




login or sign up to participate.
Money_dollar moneywill