refinerycms-theming 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/app/helpers/themes_helper.rb +34 -0
- data/app/models/theme.rb +7 -0
- data/features/step_definitions/theme_generator_steps.rb +15 -0
- data/features/theme_generator.feature +16 -0
- data/lib/gemspec.rb +29 -0
- data/lib/generators/refinery_theme/README +17 -0
- data/lib/generators/refinery_theme/Rakefile +11 -0
- data/lib/generators/refinery_theme/USAGE +2 -0
- data/lib/generators/refinery_theme/refinery_theme_generator.rb +23 -0
- data/lib/generators/refinery_theme/templates/stylesheets/application.css +5 -0
- data/lib/generators/refinery_theme/templates/stylesheets/formatting.css +7 -0
- data/lib/generators/refinery_theme/templates/stylesheets/home.css +5 -0
- data/lib/generators/refinery_theme/templates/views/layouts/application.html.erb +21 -0
- data/lib/generators/refinery_theme/templates/views/pages/home.html.erb +4 -0
- data/lib/generators/refinery_theme/templates/views/pages/show.html.erb +4 -0
- data/lib/refinerycms-theming.rb +47 -0
- data/lib/theme_server.rb +32 -0
- data/lib/theming.rb +2 -0
- data/license.md +21 -0
- data/readme.md +118 -0
- data/refinerycms-theming.gemspec +88 -0
- data/themes/demolicious/LICENSE +21 -0
- data/themes/demolicious/README +1 -0
- data/themes/demolicious/images/footer_background.png +0 -0
- data/themes/demolicious/images/header_background.png +0 -0
- data/themes/demolicious/stylesheets/application.css +105 -0
- data/themes/demolicious/stylesheets/formatting.css +36 -0
- data/themes/demolicious/stylesheets/home.css +5 -0
- data/themes/demolicious/stylesheets/ie6.css +0 -0
- data/themes/demolicious/stylesheets/ie7.css +0 -0
- data/themes/demolicious/views/layouts/application.html.erb +27 -0
- data/themes/demolicious/views/pages/home.html.erb +1 -0
- data/themes/demolicious/views/pages/show.html.erb +1 -0
- data/themes/hemingway/LICENSE +7 -0
- data/themes/hemingway/README +3 -0
- data/themes/hemingway/images/archives.gif +0 -0
- data/themes/hemingway/images/footer_black.gif +0 -0
- data/themes/hemingway/images/kyle-header.jpg +0 -0
- data/themes/hemingway/images/readon_black.gif +0 -0
- data/themes/hemingway/images/search.gif +0 -0
- data/themes/hemingway/images/spinner.gif +0 -0
- data/themes/hemingway/images/trackback_pingback.gif +0 -0
- data/themes/hemingway/stylesheets/application.css +713 -0
- data/themes/hemingway/stylesheets/formatting.css +1 -0
- data/themes/hemingway/stylesheets/home.css +1 -0
- data/themes/hemingway/views/layouts/application.html.erb +45 -0
- 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
|
data/app/models/theme.rb
ADDED
@@ -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,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,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,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,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
|
data/lib/theme_server.rb
ADDED
@@ -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
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.
|