theme_generator 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/USAGE ADDED
@@ -0,0 +1,21 @@
1
+ NAME
2
+ theme - Initializes the application to support themes and creates a new theme
3
+ folder structure.
4
+
5
+ SYNOPSIS
6
+ theme [theme name]
7
+
8
+ DESCRIPTION
9
+ This generator creates general purpose theme support. It's designed to leverage
10
+ webservers for the static content of the theme (images, stylesheets, javascripts,
11
+ etc).
12
+
13
+ Included:
14
+ - Abstraction of Typo style theme support
15
+ - New View Tag Helpers for accessing themed content
16
+
17
+ EXAMPLE
18
+ ./script/generate theme default
19
+
20
+ This will generate the file structure for a theme named 'default' and prepare
21
+ the rails application for theme support.
data/templates/README ADDED
@@ -0,0 +1,55 @@
1
+ == Usage
2
+
3
+ You can specify the current theme the same way you would a layout:
4
+
5
+ class ApplicationController < ActionController::Base
6
+
7
+ layout 'default'
8
+ theme 'blue'
9
+
10
+ end
11
+
12
+ If your application supports per-user themes, and the user's selected theme is
13
+ stored in the user object, you could implement that like this:
14
+
15
+ class ApplicationController < ActionController::Base
16
+
17
+ layout 'default'
18
+ theme :get_user_theme
19
+
20
+ # If a user is logged in, use their theme choice, otherwise
21
+ # use the theme named 'default'
22
+ def get_user_theme
23
+ return @session[:user].theme unless @session[:user].nil?
24
+ 'default'
25
+ end
26
+
27
+ end
28
+
29
+ In the views, there are theme specific helper tags available to you.
30
+
31
+ - theme_image_tag
32
+ - theme_image_path
33
+ - theme_javascript_include_tag
34
+ - theme_javascript_path
35
+ - theme_stylesheet_link_tag
36
+ - theme_stylesheet_path
37
+
38
+
39
+ == In the future...
40
+
41
+ - Add a rake task to pre-cache all static theme files (stylesheets, images, and javascript)
42
+ - Add a rake task to remove all cached theme files
43
+
44
+
45
+ == Changelog
46
+
47
+ 1.0.0 - Initial release
48
+ 1.0.1 - Added 'themes' directory, theme definition file, and symlinks
49
+ to the appropriate directories on supported platforms.
50
+ 1.0.2 - The current_theme is now retrieved from the controller. Where
51
+ symlinks are created on *nix systems, shortcuts are created
52
+ on Windows if Win32Utils is installed.
53
+ 1.1.0 - [Breaking] Abstraction of the Typo theme system. The themes are
54
+ now the same as is used in Typo. The theme engine itself is a
55
+ combination of plugins and a component.
@@ -0,0 +1,3 @@
1
+ ### <%= class_name %>
2
+
3
+ This description can be found in themes/<%= class_name %>/about.markdown
@@ -0,0 +1,45 @@
1
+ # Extend the Base ActionController to support themes
2
+ #
3
+ ActionController::Base.class_eval do
4
+
5
+ attr_accessor :current_theme
6
+
7
+ def self.theme(theme_name, conditions = {})
8
+ # TODO: Allow conditions... (?)
9
+ write_inheritable_attribute "theme", theme_name
10
+ end
11
+
12
+ # You need to override this in your +ApplicationController+
13
+ # This should return the current theme name
14
+ def current_theme(passed_theme=nil)
15
+ theme = passed_theme || self.class.read_inheritable_attribute("theme")
16
+
17
+ active_theme = case theme
18
+ when Symbol then send(theme)
19
+ when Proc then theme.call(self)
20
+ when String then theme
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ alias_method :__active_layout, :active_layout
27
+
28
+ def active_layout(passed_layout = nil)
29
+ unless current_theme.nil?
30
+ puts "THEME LAYOUT"
31
+ layout = passed_layout || self.class.read_inheritable_attribute("layout")
32
+
33
+ active_layout = case layout
34
+ when Symbol then send(layout)
35
+ when Proc then layout.call(self)
36
+ when String then layout
37
+ end
38
+
39
+ active_layout.include?("/") ? active_layout : Theme.new(current_theme).layout(active_layout) if active_layout
40
+ else
41
+ __active_layout(passed_layout)
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,21 @@
1
+ module ActionView
2
+ class Base
3
+ alias_method :__render_file, :render_file
4
+
5
+ def render_file(template_path, use_full_path = true, local_assigns = {})
6
+ if use_full_path
7
+ begin
8
+ theme_path = "../../themes/#{controller.current_theme}/views/#{template_path}"
9
+ template_extension = pick_template_extension(theme_path)
10
+ __render_file(theme_path, use_full_path, local_assigns)
11
+ rescue => err
12
+ __render_file(template_path, use_full_path, local_assigns)
13
+ end
14
+ else
15
+ __render_file(template_path, use_full_path, local_assigns)
16
+ end
17
+ end
18
+ end
19
+
20
+
21
+ end
data/templates/init.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'actionview_ex'
2
+ require 'actioncontroller_ex'
3
+ require 'routeset_ex'
4
+ require 'theme_helpers'
5
+
6
+ ActionController::Routing::Routes.create_theme_routes
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html>
4
+ <head>
5
+ <title></title>
6
+ <%%= theme_stylesheet_link_tag %>
7
+ </head>
8
+ <body>
9
+ <%%= @content_for_layout %>
10
+ </body>
11
+ </html>
Binary file
@@ -0,0 +1,22 @@
1
+
2
+ class ActionController::Routing::RouteSet
3
+
4
+ alias_method :__reload, :reload
5
+
6
+ def reload
7
+ __reload
8
+ create_theme_routes
9
+ end
10
+
11
+ def create_theme_routes
12
+ named_route 'theme_images', "/themes/:theme/images/:filename", :controller=>'theme_system/theme', :action=>'images'
13
+ named_route 'theme_stylesheets', "/themes/:theme/stylesheets/:filename", :controller=>'theme_system/theme', :action=>'stylesheets'
14
+ named_route 'theme_javascript', "/themes/:theme/javascript/:filename", :controller=>'theme_system/theme', :action=>'javascript'
15
+
16
+ connect "/themes/*", :controller=>'theme_system/theme', :action=>'error'
17
+
18
+ write_generation
19
+ write_recognition
20
+ ActionController::Routing::NamedRoutes.install
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ /*
2
+ Main StyleSheet for the '<%= class_name %>' theme
3
+ */
4
+
5
+ /* Your CSS here... */
@@ -0,0 +1,59 @@
1
+ class Theme
2
+ cattr_accessor :cache_theme_lookup
3
+ @@cache_theme_lookup = false
4
+
5
+ attr_accessor :name, :path, :description_html
6
+
7
+ def initialize(name, path=nil)
8
+ @name = name
9
+ @path = path ||= Theme.path_to_theme(name)
10
+ end
11
+
12
+ def layout(layout='default')
13
+ "../../themes/#{name}/layouts/#{layout}"
14
+ end
15
+
16
+ def description
17
+ File.read("#{path}/about.markdown") rescue "### #{name}"
18
+ end
19
+
20
+ def self.themes_root
21
+ RAILS_ROOT + "/themes"
22
+ end
23
+
24
+ # DEPRECATED: There is no 'current' theme, at least, not from here...
25
+ def self.current_theme_path
26
+ raise 'DEPRECATED: The current theme is set in the controller'
27
+ "#{themes_root}/#{config[:theme]}"
28
+ end
29
+ # DEPRECATED: There is no 'current' theme, at least, not from here...
30
+ def self.current
31
+ theme_from_path(current_theme_path)
32
+ end
33
+
34
+
35
+ def self.path_to_theme(theme)
36
+ "#{themes_root}/#{theme}"
37
+ end
38
+
39
+ def self.theme_from_path(path)
40
+ name = path.scan(/[-\w]+$/i).flatten.first
41
+ self.new(name, path)
42
+ end
43
+
44
+ def self.find_all
45
+ installed_themes.inject([]) do |array, path|
46
+ array << theme_from_path(path)
47
+ end
48
+ end
49
+
50
+ def self.installed_themes
51
+ cache_theme_lookup ? @theme_cache ||= search_theme_directory : search_theme_directory
52
+ end
53
+
54
+ def self.search_theme_directory
55
+ Dir.glob("#{themes_root}/[-_a-zA-Z0-9]*").collect do |file|
56
+ file if File.directory?(file)
57
+ end.compact
58
+ end
59
+ end
@@ -0,0 +1,59 @@
1
+ class ThemeSystem::ThemeController < ActionController::Base
2
+
3
+ after_filter :cache_theme_files
4
+
5
+ def stylesheets
6
+ render_theme_item(:stylesheets, params[:filename], params[:theme], 'text/css')
7
+ end
8
+
9
+ def javascript
10
+ render_theme_item(:javascript, params[:filename], params[:theme], 'text/javascript')
11
+ end
12
+
13
+ def images
14
+ render_theme_item(:images, params[:filename], params[:theme])
15
+ end
16
+
17
+ def error
18
+ render :nothing => true, :status => 404
19
+ end
20
+
21
+ private
22
+
23
+ def render_theme_item(type, file, theme, mime = mime_for(file))
24
+ render :text => "Not Found", :status => 404 and return if file.split(%r{[\\/]}).include?("..")
25
+ send_file "#{Theme.path_to_theme(theme)}/#{type}/#{file}", :type => mime, :disposition => 'inline', :stream => false
26
+ end
27
+
28
+ def cache_theme_files
29
+ path = request.request_uri
30
+ begin
31
+ ThemeSystem::ThemeController.cache_page( response.body, path )
32
+ rescue
33
+ #STERR.puts "Cache Exception: #{$!}"
34
+ end
35
+ end
36
+
37
+
38
+ def mime_for(filename)
39
+ case filename.downcase
40
+ when /\.js$/
41
+ 'text/javascript'
42
+ when /\.css$/
43
+ 'text/css'
44
+ when /\.gif$/
45
+ 'image/gif'
46
+ when /(\.jpg|\.jpeg)$/
47
+ 'image/jpeg'
48
+ when /\.png$/
49
+ 'image/png'
50
+ when /\.swf$/
51
+ 'application/x-shockwave-flash'
52
+ else
53
+ 'application/binary'
54
+ end
55
+ end
56
+
57
+
58
+ end
59
+
@@ -0,0 +1,69 @@
1
+ #
2
+ # These are theme helper tags
3
+ #
4
+ module ActionView
5
+ module Helpers
6
+ module AssetTagHelper
7
+
8
+ # TODO: Convert these to user the named route helpers (?)
9
+
10
+ # returns the public path to a theme stylesheet
11
+ def theme_stylesheet_path( source=nil, theme=nil )
12
+ theme = theme || controller.current_theme
13
+ compute_public_path(source || "theme", "themes/#{theme}/stylesheets", 'css')
14
+ end
15
+
16
+ # returns the path to a theme image
17
+ def theme_image_path( source, theme=nil )
18
+ theme = theme || controller.current_theme
19
+ compute_public_path(source, "themes/#{theme}/images", 'png')
20
+ end
21
+
22
+ # returns the path to a theme javascript
23
+ def theme_javascript_path( source, theme=nil )
24
+ theme = theme || controller.current_theme
25
+ compute_public_path(source, "themes/#{theme}/javascript", 'js')
26
+ end
27
+
28
+
29
+ # This tag it will automatially include the 'theme' css, plus any other
30
+ # stylesheets you include in the params...
31
+ # This doesn't support overriding the Theme -- it will use the current theme
32
+ def theme_stylesheet_link_tag(*sources)
33
+ sources << controller.current_theme.to_s
34
+ sources.uniq!
35
+ options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { }
36
+ sources.collect { |source|
37
+ source = theme_stylesheet_path(source)
38
+ tag("link", { "rel" => "Stylesheet", "type" => "text/css", "media" => "screen", "href" => source }.merge(options))
39
+ }.join("\n")
40
+ end
41
+
42
+ # This tag will return a theme-specific IMG
43
+ def theme_image_tag(source, options = {})
44
+ options.symbolize_keys
45
+
46
+ options[:src] = theme_image_path(source)
47
+ options[:alt] ||= File.basename(options[:src], '.*').split('.').first.capitalize
48
+
49
+ if options[:size]
50
+ options[:width], options[:height] = options[:size].split("x")
51
+ options.delete :size
52
+ end
53
+
54
+ tag("img", options)
55
+ end
56
+
57
+ # This tag can be used to return theme-specific javscripts
58
+ def theme_javascript_include_tag(*sources)
59
+ options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { }
60
+ sources = ['prototype', 'effects', 'controls', 'dragdrop'] if sources.first == :defaults
61
+ sources.collect { |source|
62
+ source = theme_javascript_path(source)
63
+ content_tag("script", "", { "type" => "text/javascript", "src" => source }.merge(options))
64
+ }.join("\n")
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,37 @@
1
+ class ThemeGenerator < Rails::Generator::NamedBase
2
+ def manifest
3
+ record do |m|
4
+ # Readme file
5
+ m.template 'README', "README_THEMES"
6
+
7
+ # Theme folder(s)
8
+ m.directory File.join( "themes", file_name )
9
+ m.template 'about.markdown', File.join( 'themes', file_name, 'about.markdown' )
10
+ m.template 'preview.png', File.join( 'themes', file_name, 'preview.png' )
11
+
12
+ m.directory File.join( "themes", file_name, "stylesheets" )
13
+ m.template "theme.css", File.join( "themes", file_name, "stylesheets", "#{file_name}.css" )
14
+
15
+ m.directory File.join( "themes", file_name, "layouts" )
16
+ m.template 'layout.rhtml', File.join( 'themes', file_name, 'layouts', 'default.rhtml' )
17
+
18
+ m.directory File.join( "themes", file_name, "views" )
19
+ m.directory File.join( "themes", file_name, "images" )
20
+ m.directory File.join( "themes", file_name, "javascript" )
21
+
22
+ # The ThemeEngine plugins
23
+ m.directory File.join( "vendor", "plugins", "theme_engine" )
24
+ m.template 'init.rb', File.join( 'vendor', 'plugins', 'theme_engine', 'init.rb' )
25
+ m.directory File.join( "vendor", "plugins", "theme_engine", "lib" )
26
+ m.template 'actioncontroller_ex.rb', File.join( 'vendor', 'plugins', 'theme_engine', 'lib', 'actioncontroller_ex.rb' )
27
+ m.template 'actionview_ex.rb', File.join( 'vendor', 'plugins', 'theme_engine', 'lib', 'actionview_ex.rb' )
28
+ m.template 'routeset_ex.rb', File.join( 'vendor', 'plugins', 'theme_engine', 'lib', 'routeset_ex.rb' )
29
+ m.template 'theme_helpers.rb', File.join( 'vendor', 'plugins', 'theme_engine', 'lib', 'theme_helpers.rb' )
30
+
31
+ # The ThemeSystem Component
32
+ m.directory File.join( "components", "theme_system" )
33
+ m.template 'theme.rb', File.join( 'components', 'theme_system', 'theme.rb' )
34
+ m.template 'theme_controller.rb', File.join( 'components', 'theme_system', 'theme_controller.rb' )
35
+ end
36
+ end
37
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: theme_generator
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.1.0
7
+ date: 2005-10-27 00:00:00 -05:00
8
+ summary: "[Rails] Theme generator adds support for themes into Rails applications"
9
+ require_paths:
10
+ - lib
11
+ email: darthapo@gmail.com
12
+ homepage: http://www.mattmccray.com
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - M@ McCray
31
+ files:
32
+ - templates/README
33
+ - templates/actionview_ex.rb
34
+ - templates/preview.png
35
+ - templates/theme.rb
36
+ - templates/about.markdown
37
+ - templates/init.rb
38
+ - templates/routeset_ex.rb
39
+ - templates/theme_controller.rb
40
+ - templates/actioncontroller_ex.rb
41
+ - templates/layout.rhtml
42
+ - templates/theme.css
43
+ - templates/theme_helpers.rb
44
+ - USAGE
45
+ - theme_generator.rb
46
+ test_files: []
47
+ rdoc_options: []
48
+ extra_rdoc_files: []
49
+ executables: []
50
+ extensions: []
51
+ requirements: []
52
+ dependencies:
53
+ - !ruby/object:Gem::Dependency
54
+ name: rails
55
+ version_requirement:
56
+ version_requirements: !ruby/object:Gem::Version::Requirement
57
+ requirements:
58
+ -
59
+ - ">"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.0
62
+ version: