refinerycms-theming 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/app/helpers/themes_helper.rb +34 -0
  2. data/app/models/theme.rb +7 -0
  3. data/features/step_definitions/theme_generator_steps.rb +15 -0
  4. data/features/theme_generator.feature +16 -0
  5. data/lib/gemspec.rb +29 -0
  6. data/lib/generators/refinery_theme/README +17 -0
  7. data/lib/generators/refinery_theme/Rakefile +11 -0
  8. data/lib/generators/refinery_theme/USAGE +2 -0
  9. data/lib/generators/refinery_theme/refinery_theme_generator.rb +23 -0
  10. data/lib/generators/refinery_theme/templates/stylesheets/application.css +5 -0
  11. data/lib/generators/refinery_theme/templates/stylesheets/formatting.css +7 -0
  12. data/lib/generators/refinery_theme/templates/stylesheets/home.css +5 -0
  13. data/lib/generators/refinery_theme/templates/views/layouts/application.html.erb +21 -0
  14. data/lib/generators/refinery_theme/templates/views/pages/home.html.erb +4 -0
  15. data/lib/generators/refinery_theme/templates/views/pages/show.html.erb +4 -0
  16. data/lib/refinerycms-theming.rb +47 -0
  17. data/lib/theme_server.rb +32 -0
  18. data/lib/theming.rb +2 -0
  19. data/license.md +21 -0
  20. data/readme.md +118 -0
  21. data/refinerycms-theming.gemspec +88 -0
  22. data/themes/demolicious/LICENSE +21 -0
  23. data/themes/demolicious/README +1 -0
  24. data/themes/demolicious/images/footer_background.png +0 -0
  25. data/themes/demolicious/images/header_background.png +0 -0
  26. data/themes/demolicious/stylesheets/application.css +105 -0
  27. data/themes/demolicious/stylesheets/formatting.css +36 -0
  28. data/themes/demolicious/stylesheets/home.css +5 -0
  29. data/themes/demolicious/stylesheets/ie6.css +0 -0
  30. data/themes/demolicious/stylesheets/ie7.css +0 -0
  31. data/themes/demolicious/views/layouts/application.html.erb +27 -0
  32. data/themes/demolicious/views/pages/home.html.erb +1 -0
  33. data/themes/demolicious/views/pages/show.html.erb +1 -0
  34. data/themes/hemingway/LICENSE +7 -0
  35. data/themes/hemingway/README +3 -0
  36. data/themes/hemingway/images/archives.gif +0 -0
  37. data/themes/hemingway/images/footer_black.gif +0 -0
  38. data/themes/hemingway/images/kyle-header.jpg +0 -0
  39. data/themes/hemingway/images/readon_black.gif +0 -0
  40. data/themes/hemingway/images/search.gif +0 -0
  41. data/themes/hemingway/images/spinner.gif +0 -0
  42. data/themes/hemingway/images/trackback_pingback.gif +0 -0
  43. data/themes/hemingway/stylesheets/application.css +713 -0
  44. data/themes/hemingway/stylesheets/formatting.css +1 -0
  45. data/themes/hemingway/stylesheets/home.css +1 -0
  46. data/themes/hemingway/views/layouts/application.html.erb +45 -0
  47. metadata +127 -0
@@ -0,0 +1,34 @@
1
+ module ThemesHelper
2
+ def image_tag(source, options={})
3
+ theme = (options.delete(:theme) == true)
4
+ tag = super
5
+ # inject /theme/ into the image tag src if this is themed.
6
+ tag.gsub!(/src=[\"|\']/) { |m| "#{m}/theme/" }.gsub!("//", "/") if theme
7
+ tag.gsub(/theme=(.+?)\ /, '') # we need to remove any addition of theme='false' etc.
8
+ end
9
+
10
+ def javascript_include_tag(*sources)
11
+ theme = (arguments = sources.dup).extract_options![:theme] == true # don't ruin the current sources object
12
+ tag = super
13
+ # inject /theme/ into the javascript include tag src if this is themed.
14
+ tag.gsub!(/\/javascripts\//, "/theme/javascripts/") if theme
15
+ tag.gsub(/theme=(.+?)\ /, '') # we need to remove any addition of theme='false' etc.
16
+ end
17
+
18
+ def stylesheet_link_tag(*sources)
19
+ theme = (arguments = sources.dup).extract_options![:theme] == true # don't ruin the current sources object
20
+ tag = super
21
+ # inject /theme/ into the stylesheet link tag href if this is themed.
22
+ tag.gsub!(/\/stylesheets\//, "/theme/stylesheets/") if theme
23
+ tag.gsub(/theme=(.+?)\ /, '') # we need to remove any addition of theme='false' etc.
24
+ end
25
+
26
+ def image_submit_tag(source, options = {})
27
+ theme = (options.delete(:theme) == true)
28
+
29
+ tag = super
30
+ # inject /theme/ into the image tag src if this is themed.
31
+ tag.gsub!(/src=[\"|\']/) { |m| "#{m}/theme/" }.gsub!("//", "/") if theme
32
+ tag.gsub(/theme=(.+?)\ /, '') # we need to remove any addition of theme='false' etc.
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ class Theme
2
+
3
+ def self.current_theme(env)
4
+ RefinerySetting[:theme]
5
+ end
6
+
7
+ end
@@ -0,0 +1,15 @@
1
+ Before do
2
+ @theme_generator_root = File.join(File.dirname(__FILE__), "/../../")
3
+ @tmp_refinery_app_name = "tmp_refinery_app"
4
+ @tmp_refinery_app_root = File.join(@theme_generator_root, @tmp_refinery_app_name)
5
+ @app_root = @tmp_refinery_app_root
6
+ Rails::Generator::Base.append_sources(Rails::Generator::PathSource.new(:theme, "#{@theme_generator_root}/generators/"))
7
+ end
8
+
9
+ After do
10
+ FileUtils.rm_rf(@tmp_refinery_app_root)
11
+ end
12
+
13
+ When /^I generate a theme with the name of "([^"]*)"$/ do |name|
14
+ Rails::Generator::Scripts::Generate.new.run(['refinery_theme', name], {:quiet => true, :destination => @app_root})
15
+ end
@@ -0,0 +1,16 @@
1
+ Feature: Theme generation
2
+ In order to create my own theme
3
+ As a refinery user
4
+ I want to generate a basic theme directory structure
5
+
6
+ Scenario: Generating a theme with a name
7
+ Given I have a refinery application
8
+ When I generate a theme with the name of "modern"
9
+ Then I should have a directory "themes/modern"
10
+ And I should have a file "themes/modern/stylesheets/application.css"
11
+ And I should have a file "themes/modern/stylesheets/home.css"
12
+ And I should have a file "themes/modern/stylesheets/formatting.css"
13
+ And I should have a file "themes/modern/views/layouts/application.html.erb"
14
+ And I should have a file "themes/modern/views/pages/home.html.erb"
15
+ And I should have a file "themes/modern/views/pages/show.html.erb"
16
+ And I should have a directory "themes/modern/javascripts"
data/lib/gemspec.rb ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ version = '0.9.8'
3
+ raise "Could not get version so gemspec can not be built" if version.nil?
4
+ files = Dir[%q{**/*}].flatten.reject{|f| f =~ /\.gem$/}
5
+
6
+ gemspec = <<EOF
7
+ Gem::Specification.new do |s|
8
+ s.name = %q{refinerycms-theming}
9
+ s.version = %q{#{version}}
10
+ s.description = %q{Theming functionality for the Refinery CMS project, extracted from Refinery CMS core.}
11
+ s.date = %q{#{Time.now.strftime('%Y-%m-%d')}}
12
+ s.summary = %q{Theming functionality for the Refinery CMS project.}
13
+ s.email = %q{info@refinerycms.com}
14
+ s.homepage = %q{http://refinerycms.com}
15
+ s.authors = %w(Resolve\\ Digital)
16
+ s.require_paths = %w(lib)
17
+
18
+ s.files = [
19
+ '#{files.join("',\n '")}'
20
+ ]
21
+ #{"s.test_files = [
22
+ '#{Dir.glob("test/**/*.rb").join("',\n '")}'
23
+ ]" if File.directory?("test")}
24
+
25
+ s.add_dependency('refinerycms', '>= 0.9.8')
26
+ end
27
+ EOF
28
+
29
+ File.open(File.expand_path("../../refinerycms-theming.gemspec", __FILE__), 'w').puts(gemspec)
@@ -0,0 +1,17 @@
1
+ == Refinery Theme Generator
2
+
3
+ == Description
4
+
5
+ Generate a new barebones Refinery theme.
6
+
7
+ If you want this new theme to be the current theme used, set the "theme"
8
+ setting in the Refinery backend to the name of this theme.
9
+
10
+ == Usage
11
+ rails generate refinery_theme theme_name
12
+
13
+ == Example
14
+ rails generate refinery_theme modern
15
+
16
+ Results in:
17
+ create /themes/modern/...
@@ -0,0 +1,11 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Generate documentation for the Refinery Theme Generator plugin.'
6
+ Rake::RDocTask.new(:rdoc) do |rdoc|
7
+ rdoc.rdoc_dir = 'rdoc'
8
+ rdoc.title = 'Refinery Theme Generator'
9
+ rdoc.options << '--line-numbers' << '--inline-source'
10
+ rdoc.rdoc_files.include('README')
11
+ end
@@ -0,0 +1,2 @@
1
+ Usage:
2
+ rails generate refinery_theme modern
@@ -0,0 +1,23 @@
1
+ class RefineryThemeGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('../templates', __FILE__)
3
+ argument :theme_name, :type => :string
4
+
5
+ def create_theme
6
+ copy_file "stylesheets/application.css", "themes/#{theme_name}/stylesheets/application.css"
7
+ copy_file "stylesheets/formatting.css", "themes/#{theme_name}/stylesheets/formatting.css"
8
+ copy_file "stylesheets/home.css", "themes/#{theme_name}/stylesheets/home.css"
9
+
10
+ copy_file "views/layouts/application.html.erb", "themes/#{theme_name}/views/layouts/application.html.erb"
11
+
12
+ copy_file "views/pages/show.html.erb", "themes/#{theme_name}/views/pages/show.html.erb"
13
+ copy_file "views/pages/home.html.erb", "themes/#{theme_name}/views/pages/home.html.erb"
14
+
15
+ if RefinerySetting.get(:theme).nil?
16
+ RefinerySetting.set(:theme, theme_name)
17
+ puts "NOTE: \"theme\" setting created and set to #{theme_name}"
18
+ else
19
+ puts 'NOTE: If you want this new theme to be the current theme used, set the "theme" setting in the Refinery backend to the name of this theme.' unless RAILS_ENV == "test"
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,5 @@
1
+ @import url('/stylesheets/refinery/application.css');
2
+ /*
3
+ Override default refinery application CSS below.
4
+ Formatting applies to all frontend.
5
+ */
@@ -0,0 +1,7 @@
1
+ @import url('/stylesheets/refinery/formatting.css');
2
+ /*
3
+ Override default refinery formatting below.
4
+ Formatting applies to backend WYSIWYG editors and all frontend.
5
+ This is the best place to put your heading and text related styles
6
+ like colours, fonts and line-height.
7
+ */
@@ -0,0 +1,5 @@
1
+ @import url('/stylesheets/refinery/home.css');
2
+ /*
3
+ Override default refinery homepage styles here.
4
+ These only apply to the homepage of your site.
5
+ */
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <%= render :partial => "/shared/head", :locals => {:theme => true} %>
4
+ <body>
5
+ <%= render :partial => "/shared/site_bar" %>
6
+ <div id='page_container'>
7
+ <div id='page'>
8
+ <%= render :partial => "/shared/ie6check" if request.env['HTTP_USER_AGENT'] =~ /MSIE/ -%>
9
+ <div id='header'>
10
+ <%= render :partial => "/shared/header" %>
11
+ </div>
12
+ <div id='body' class='clearfix'>
13
+ <%= yield %>
14
+ </div>
15
+ <div id='footer'>
16
+ <%= render :partial => "/shared/footer" %>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </body>
21
+ </html>
@@ -0,0 +1,4 @@
1
+ <%# For the best way to modify this page with your own markup read %>
2
+ <%# http://github.com/resolve/refinerycms-theming/blob/master/readme.md %>
3
+
4
+ <%= render :partial => "/shared/content_page" %>
@@ -0,0 +1,4 @@
1
+ <%# For the best way to modify this page with your own markup read %>
2
+ <%# http://github.com/resolve/refinerycms-theming/blob/master/readme.md %>
3
+
4
+ <%= render :partial => "/shared/content_page" %>
@@ -0,0 +1,47 @@
1
+ require File.expand_path('../theming', __FILE__)
2
+
3
+ module Refinery
4
+ class ThemingEngine < ::Rails::Engine
5
+
6
+ config.to_prepare do
7
+ ::ApplicationController.module_eval do
8
+
9
+ # Add or remove theme paths to/from Refinery application
10
+ prepend_before_filter :attach_theme_to_refinery
11
+
12
+ def attach_theme_to_refinery
13
+ # remove any paths relating to any theme.
14
+ view_paths.reject! { |v| v.to_s =~ %r{^themes/} }
15
+
16
+ # add back theme paths if there is a theme present.
17
+ if (theme = ::Theme.current_theme(request.env)).present?
18
+ # Set up view path again for the current theme.
19
+ view_paths.unshift Rails.root.join("themes", theme, "views").to_s
20
+
21
+ # Ensure that routes within the application are top priority.
22
+ # Here we grab all the routes that are under the application's view folder
23
+ # and promote them ahead of any other path.
24
+ view_paths.select{|p| p.to_s =~ %r{^#{Rails.root.join('app', 'views')}}}.each do |app_path|
25
+ view_paths.unshift app_path
26
+ end
27
+ end
28
+
29
+ # Set up menu caching for this theme or lack thereof
30
+ if RefinerySetting.table_exists? and
31
+ RefinerySetting.get(:refinery_menu_cache_action_suffix) != (suffix = "#{"#{theme}_" if theme.present?}site_menu")
32
+ RefinerySetting.set(:refinery_menu_cache_action_suffix, suffix)
33
+ end
34
+ end
35
+ protected :attach_theme_to_refinery
36
+
37
+ end
38
+
39
+ ::ApplicationHelper.send :include, ::ThemesHelper
40
+ end
41
+
42
+ initializer 'themes.middleware' do |app|
43
+ app.config.middleware.insert_before ::ActionDispatch::Static, ::Refinery::ThemeServer
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ # Allow the metal piece to run in isolation
2
+ require File.expand_path('../../../config/environment', __FILE__) unless defined?(Rails)
3
+
4
+ # Serves theme files from the theme directory without touching Rails too much
5
+ module Refinery
6
+ class ThemeServer
7
+
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ if env["PATH_INFO"] =~ /^\/theme\/(stylesheets|javascripts|images)/ and (theme = Theme.current_theme(env)).present?
14
+ env["PATH_INFO"].gsub!(/^\/theme\//, '')
15
+ if (file_path = (dir = Rails.root.join("themes", theme)).join(env["PATH_INFO"])).exist?
16
+ etag = Digest::MD5.hexdigest("#{file_path.to_s}#{file_path.mtime}")
17
+ unless (etag == env["HTTP_IF_NONE_MATCH"])
18
+ status, headers, body = Rack::File.new(dir).call(env)
19
+ [status, headers.update({"ETag" => etag}), body]
20
+ else
21
+ [304, {"ETag" => etag}, []]
22
+ end
23
+ else
24
+ [404, {}, []]
25
+ end
26
+ else
27
+ @app.call(env)
28
+ end
29
+ end
30
+
31
+ end
32
+ end
data/lib/theming.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Before the application gets setup this will fail badly if there's no database.
2
+ require File.expand_path('../theme_server', __FILE__)
data/license.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2005-2010 [Resolve Digital Ltd.](http://www.resolvedigital.co.nz)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,118 @@
1
+ # Themes
2
+
3
+ ## Introduction
4
+
5
+ __Themes allow you to wrap up the design of your Refinery site into a single folder that is portable.__
6
+
7
+ Refinery doesn't force you to learn a special templating language, but rather just uses the regular
8
+ ERB views you're used to in Rails. This means creating a theme from your existing site is extremely easy.
9
+
10
+ Think of a theme as your ``app/views`` directory with a few extra things like images, css and javascript.
11
+
12
+ It's worth noting you don't need to use a theme if you don't want to. Placing files in the ``app/views`` directory like any other Rails app will work just fine. It's only if you want to wrap your design up into a single location that you would use a theme or allow your client to easily change between designs.
13
+
14
+ ## The Structure of a Theme
15
+
16
+ Themes sit in your Rails app like this
17
+
18
+ app/
19
+ config/
20
+ db/
21
+ lib/
22
+ public/
23
+ themes/
24
+ |- mytheme/
25
+ |- othertheme/
26
+ plugins/
27
+ tests/
28
+
29
+ Let's take the ``mytheme`` example theme shown above. This is how the theme is structured:
30
+
31
+ mytheme/
32
+ |- images
33
+ | |- whatever.png
34
+ | |- foo.jpg
35
+ |- javascripts
36
+ | |- whatever.js
37
+ |- LICENSE
38
+ |- README
39
+ |- stylesheets/
40
+ | |- application.css
41
+ | |- whatever.css
42
+ |- views
43
+ |- pages
44
+ | |- show.html.erb
45
+ | |- index.html.erb
46
+ |- layouts
47
+ |- application.html.erb
48
+
49
+
50
+ ### Images
51
+
52
+ Usually this would be just what you have in ``public/images`` except we move that to the theme instead.
53
+
54
+ ### Javascripts
55
+
56
+ Same with javascripts, just what you normally have in ``public/javascripts`` but in this theme directory instead.
57
+
58
+ ### Readme
59
+
60
+ The ``README`` file is just a description of your theme.
61
+
62
+ ### Views
63
+
64
+ This is exactly the same as how you lay your views out in ``app/views/`` just instead of putting them in ``app/views/`` you put them into ``themes/mytheme/views/``
65
+
66
+ ## How do I make my own Theme?
67
+
68
+ Simply use the Theme generator to make the basic structure of a new theme.
69
+
70
+ rails generate refinery_theme name_of_theme
71
+
72
+ Don't forget to "activate" this new theme by setting the theme setting to the name of this new theme.
73
+
74
+ ## How do I select which Theme Refinery should use?
75
+
76
+ In the admin area of Refinery go to the "Settings" area, locate the setting called "theme" and edit it.
77
+
78
+ Set the value of that setting to the name of your themes folder. For example, if your theme is sitting in:
79
+
80
+ themes/my_theme
81
+
82
+ set it to ``my_theme`` and hit save.
83
+
84
+ ## How do I install someone else's Theme?
85
+
86
+ Just copy their theme directory into your themes folder and Refinery will see it.
87
+
88
+ ## How can I Convert my Current Views into a Theme?
89
+
90
+ This should be fairly straightforward, just follow the directory structure outlined in 'The structure of a Theme'.
91
+
92
+ But there is one important difference that need to be addressed to convert your current site into a theme.
93
+
94
+ If you have some CSS which refers to an image or URL:
95
+
96
+ #footer {
97
+ background: url('/images/footer_background.png') repeat-x;
98
+ }
99
+
100
+ You need to update the URL so it requests ``/theme/images/`` instead of just ``/images``. This tells Refinery we need to actually load this image from the theme and not just the public directory.
101
+
102
+ So the result is simply:
103
+
104
+ #footer {
105
+ background: url('/theme/images/footer_background.png') repeat-x;
106
+ }
107
+
108
+ This is the same with linking to Javascript and Stylesheets in your view. Say our ``application.html.erb`` layout had something like this:
109
+
110
+ <%= stylesheet_link_tag 'application' %>
111
+
112
+ You just need to change that to:
113
+
114
+ <%= stylesheet_link_tag 'application', :theme => true %>
115
+
116
+ ## I'm Stuck, is there an Example Theme?
117
+
118
+ Yep, there is an example theme called "demolicious" that comes with Refinery located in ``/themes/demolicious``. If you find yourself getting stuck, just check out that theme and get a feel for how it works.