theme_generator 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: