Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Theme Support for Rails 3
Ruby JavaScript

This branch is 3 commits ahead, 8 commits behind lucasefe:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
doc
lib
test
.gitignore
.rspec
.rvmrc
.travis.yml
Gemfile
Gemfile.lock
LICENSE
README.textile
Rakefile
active_theme.gemspec

README.textile

ActiveTheme (Theme Support For Rails 3)

This project is forked from lucasefe/themes_for_rails

Instructions

Add active_theme to your Gemfile.

gem 'active_theme'

Add active_theme to your config/routes.rb

MySuperDuperApp::Application.routes.draw do
  # ...
  active_theme
  # ...
end

Additional Instructions for using the Rails Asset Pipeline

In order to use active_theme with the asset pipeline, you will need to configure a few settings and place your themes in the asset pipeline directory.

First, move your assets into the asset pipeline. For example:

$app_root
  app/
    assets/
      images/      <-- default asset pipeline folder
      javascripts/ <-- default asset pipeline folder
      stylesheets/ <-- default asset pipeline folder
      themes/      <-- your themes root
        [theme_name]
          images/
          stylesheets/
          javascripts/
          views/           <- you can override application views
            layouts/         <- layout .rhtml or .liquid templates

Create an initializer for themes in your {Rails.root}/config/initializers directory and set the themes_dir and assets_dir settings appropriately.

# Rails.root/config/initializers/active_theme.rb (for instance)
ActiveTheme.config do |config|
  #
  # If you have placed your themes like the example path above within the asset pipeline:
  config.themes_routes_dir = 'assets'
  config.assets_dir = ':root/app/assets/themes/:name'
  config.views_dir = ':root/app/assets/themes/:name/views'
  # ...
end

In your theme stylesheets directory, you can create an application.css file using the Sprockets require methods:

/*
 *= require global_stylesheet_name
 *= require theme_name/stylesheets/stylesheet_name
 */

As you can see, if you do not preface with the theme_name/stylesheets it will reference the root /app/assets/stylesheets path for global stylesheets (great for mixins and reset styles)

Currently, one unresolved issue with this setup is that you must pass the theme_name/images path into your sass image-url helper methods. For example, if you are including an image in the ‘default’ theme:

image-url(‘default/images/background.png’)

If you do not want to have your views inside the asset pipeline dir, you can alternatively configure your application like this:

$app_root
  app/
    assets/
      images/      <-- default asset pipeline folder
      javascripts/ <-- default asset pipeline folder
      stylesheets/ <-- default asset pipeline folder
      themes/      <-- your themes root
        [theme_name]
          images/
          stylesheets/
          javascripts/
    views/
      themes/       <-- note themes folder lives under views in this scenario
        [theme_name]
          layouts/         <- layout .rhtml or .liquid templates

and in your initializer, you will need to set the views_dir config setting like so:

# Rails.root/config/initializers/active_theme.rb (for instance)
ActiveTheme.config do |config|
  #
  # If you have placed your themes like the example path above within the asset pipeline:
  config.themes_dir = 'assets'
  config.assets_dir = ':root/app/assets/themes/:name'
  config.views_dir = ':root/app/views/themes/:name'
  # ...
end

After that, the rest of the config for asset pipeline styles and whatnot mentioned above will work.

And then?

Now you’ll be able to use themes like this:

Inside method, for some explicit action:

class MyController < ApplicationController
  def show
    theme "purple"
  end
end

Or at class level definition, in order to set a theme for more than one action. I think this is is prettier, and less invasive.

class MyController < ApplicationController
  theme "purple" # all actions will use this theme
  def show
    ...
  end
end

You could also enable a theme for some actions only

class MyController < ApplicationController
  theme "purple", :only => :show
  def show
    # with theme
  end
  def edit
    # no theme
  end
end

As a plus, you could do this to defer theme name resolution to a method:

class MyController < ApplicationController
  theme :theme_resolver
  # ...
private
  def theme_resolver
    current_user.theme # or anything else that return a string.
  end
end

As a general rule, when passing a String, that becomes the theme name, but when a Symbol is sent, it gets treated as method message.

Action Mailer integration:

As a plus, you can use it from Action Mailer too (thanks to rafaelss) like this:

class MyMailer < ActionMailer::Base

  def notify_someone
    mail :theme => "blue" , :to => "some@one.com"
  end

end

Or set the theme by default like this (thanks to maxjgon):

class MyMailer < ActionMailer::Base

  default :theme => "blue"

  def notify_someone
    mail :to => "some@one.com"
  end

end

Url Helpers

In your views you should be able to access your assets like this (given the theme ‘default’ is set):

current_theme_image_path('logo.png')   # => /themes/default/images/logo.png
current_theme_stylesheet_path('logo') # => /themes/default/stylesheets/logo.css
current_theme_javascript_path('app')   # => /themes/default/stylesheets/app.js

Or a given theme:

current_theme_image_path('logo.png', 'purple')   # => /themes/purple/images/logo.png

In your application views, there are theme specific helper tags
available to you. For ERb templates they are:

theme_image_tag
theme_image_path
theme_javascript_include_tag
theme_javascript_path
theme_stylesheet_link_tag
theme_stylesheet_path

Generators

For now, it only creates the theme folder and add the “active_theme” route in the routes.rb.

rails generate active_theme:install

Inside the themes folder, it create a structure for my_theme.

rails generate active_theme:create my_theme

Changing things

At least for now, you can change the ActiveTheme base dir in your app, in the corresponding environment file, or in your application.rb file. Do it like this:

KillerApp::Application.configure do
  #

  config.active_theme.base_dir = File.join(Rails.root, "tmp")

  #...
end

Thanks to matheusca, now you can change the name of the theme’s dir.

KillerApp::Application.configure do
  #

  config.active_theme.themes_dir = "another_themes"

  #...
end

Sass support

ActiveTheme will automatically add the themes paths to Sass, if sass is available.

For instance, everything you put inside themes/my_theme/stylesheets/sass will get compiled into themes/my_theme/stylesheets (duh, right?)

To bypass sass configuration, do this:


KillerApp::Application.configure do
#

config.active_theme.use_sass = false #…

end

Another way to change things

If you don’t like this approach and prefer something more like an initializer file, you could create one an put something like this.

# Rails.root/config/initializers/active_theme.rb (for instance)
ActiveTheme.config do |config|
  #
  config.themes_dir = 'another_themes'
  # ...
end

Notes and Warnings.

If you are running an app in production mode, and you get the static files with no content, is because you don’t have X-senfile enabled at your web server.

You can do two things:

comment out this line in your production.rb file:

config.action_dispatch.x_sendfile_header = “X-Sendfile”

or

configure your web server to use it. :)

Ideas

  • Add ActiveTheme::Railtie for configuration, so we selectively set the plugin on or off. Also to be able to change several settings.
  • Add routes to allow access to the theme’s static resources (js and cs), unless cached on public folder by capistrano / rake.
  • Extend Action View path in order to make the views accessible. Same for the layouts.
  • More tests ford edge cases. Now I am only testing the happy paths.

Things to remember.

  • Final version should be a gem. Initialization hooks doesn’t work when using this as a plugin (vendor/plugins).
  • Research about testing this kind of gem. I really don’t have a clue. Testing in place!
  • I should probably load the theme list at start time, to be able to consult it as needed. I am gonna need that when dealing with runtime theme selection. Many themes are going to be used simultaneously, so I have to be able to switch view paths as fast as I can.

Running tests

gem install bundler
bundle install
rake

Authors and contributors

  • lucasefe
  • jbarreneche
  • kule
  • matheusmoreira
  • rafaelss
  • maxjgon
Something went wrong with that request. Please try again.