radiant-sheets-extension 1.0.0.pre → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -40,15 +40,12 @@ class Admin::SheetResourceController < Admin::ResourceController
40
40
 
41
41
  def create_root
42
42
  unless @root
43
- s = model_class.new_with_defaults
44
43
  begin
45
- s.parent_id = Page.find_by_slug('/').id
44
+ model_class.create_root
46
45
  rescue Page::MissingRootPageError
47
46
  flash[:error] = t('sheets.root_required', :model => humanized_model_name)
48
47
  redirect_to welcome_path and return false
49
48
  end
50
- s.slug = model_class == StylesheetPage ? 'css' : 'js'
51
- s.save
52
49
  end
53
50
  end
54
51
  end
data/app/models/sheet.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'digest/md5'
1
2
  module Sheet
2
3
  module InvalidHomePage; end
3
4
  module Instance
@@ -9,12 +10,19 @@ module Sheet
9
10
  class_inheritable_accessor :sheet_root
10
11
 
11
12
  def self.root
12
- sheet_root ||= Page.find_by_path('/').children.first(:conditions => {:class_name => self.to_s})
13
+ Page.find_by_path('/').children.first(:conditions => {:class_name => self.to_s})
13
14
  rescue NoMethodError => e
14
15
  e.extend Sheet::InvalidHomePage
15
16
  raise e
16
17
  end
17
18
 
19
+ def self.create_root
20
+ s = self.new_with_defaults
21
+ s.parent_id = Page.find_by_slug('/').id
22
+ s.slug = self.name == 'StylesheetPage' ? 'css' : 'js'
23
+ s.save
24
+ end
25
+
18
26
  def self.default_page_parts
19
27
  PagePart.new(:name => 'body')
20
28
  end
@@ -74,8 +82,24 @@ module Sheet
74
82
  self.part('body').content = file.read
75
83
  end
76
84
  end
85
+
86
+ def digest
87
+ @generated_digest ||= digest!
88
+ end
89
+
90
+ def digest!
91
+ Digest::MD5.hexdigest(self.render)
92
+ end
93
+
94
+ def child_path(child)
95
+ clean_path(path + '/' + child.slug + '?' + child.digest)
96
+ end
77
97
 
78
98
  private
99
+
100
+ def clean_path(path)
101
+ "/#{ path.to_s.strip }".gsub(%r{//+}, '/')
102
+ end
79
103
 
80
104
  def set_title
81
105
  self.title = self.slug
@@ -46,6 +46,33 @@ Feature: Managing stylesheets
46
46
  """
47
47
  p { color: red; } /* I added this comment */
48
48
  """
49
+
50
+ Scenario: Ensuring a homepage exists
51
+ Given there are no pages
52
+ And I am logged in as "designer"
53
+ When I follow "Design"
54
+ And I follow "Stylesheets"
55
+ Then I should see "You must first publish a homepage before you may create a Stylesheet"
56
+ And I should not see "New Stylesheet"
57
+ And I should see "New Homepage"
58
+
59
+ Scenario: Creating stylesheets from scratch
60
+ Given there are no pages
61
+ And I am logged in as "designer"
62
+ When I follow "Design"
63
+ And I follow "Stylesheets"
64
+ Then I should see "You must first publish a homepage before you may create a Stylesheet"
65
+ And I follow "New Homepage"
66
+ And I fill in "Page Title" with "Home Page"
67
+ And I fill in "Slug" with "/"
68
+ And I fill in "Breadcrumb" with "Home"
69
+ And I select "Published" from "Status"
70
+ And I press "Create Page"
71
+ Then I should see "Home Page"
72
+ And I follow "Design"
73
+ And I follow "Stylesheets"
74
+ And I follow "New Stylesheet"
75
+ Then I should see "Path: /css/"
49
76
 
50
77
  Scenario: Rendering CSS
51
78
  Given I am logged in as "designer"
@@ -105,4 +132,5 @@ Feature: Managing stylesheets
105
132
  """
106
133
  p{color:red}p a{color:blue;line-height:1.9}
107
134
  """
135
+ And the "Cache-Control" header should be "max-age=2592000"
108
136
 
@@ -9,7 +9,7 @@ as one of the following:
9
9
 
10
10
  * with no @as@ value the javascript's content is rendered by default.
11
11
  * @inline@ - wraps the javascript's content in an (X)HTML @<script>@ element.
12
- * @url@ - the full path to the javascript.
12
+ * @path@ - the full path to the javascript.
13
13
  * @link@ - embeds the url in an (X)HTML @<script>@ element (creating a link to the external javascript).
14
14
 
15
15
  *Additional Options:*
@@ -38,16 +38,16 @@ The above example will produce the following:
38
38
  raise TagError.new("`javascript' tag must contain a `slug' attribute.") unless slug
39
39
  if (javascript = JavascriptPage.find_by_slug(slug))
40
40
  mime_type = tag.attr['type'] || javascript.headers['Content-Type']
41
- url = javascript.url.sub(/\/$/,'') + '?' + javascript.updated_at.to_i.to_s
41
+ path = javascript.path
42
42
  optional_attributes = tag.attr.except('slug', 'name', 'as', 'type').inject('') { |s, (k, v)| s << %{#{k}="#{v}" } }.strip
43
43
  optional_attributes = " #{optional_attributes}" unless optional_attributes.empty?
44
44
  case tag.attr['as']
45
- when 'url'
46
- url
45
+ when 'url','path'
46
+ path
47
47
  when 'inline'
48
48
  %{<script type="#{mime_type}"#{optional_attributes}>\n//<![CDATA[\n#{javascript.render_part('body')}\n//]]>\n</script>}
49
49
  when 'link'
50
- %{<script type="#{mime_type}" src="#{url}"#{optional_attributes}></script>}
50
+ %{<script type="#{mime_type}" src="#{path}"#{optional_attributes}></script>}
51
51
  else
52
52
  javascript.render_part('body')
53
53
  end
@@ -1,3 +1,3 @@
1
1
  module RadiantSheetsExtension
2
- VERSION = '1.0.0.pre'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -9,7 +9,7 @@ as one of the following:
9
9
 
10
10
  * with no @as@ value the stylesheet's content is rendered by default.
11
11
  * @inline@ - wraps the stylesheet's content in an (X)HTML @<style>@ element.
12
- * @url@ - the full path to the stylesheet.
12
+ * @path@ - the full path to the stylesheet.
13
13
  * @link@ - embeds the url in an (X)HTML @<link>@ element (creating a link to the external stylesheet).
14
14
 
15
15
  *Additional Options:*
@@ -40,17 +40,17 @@ The above example will produce the following:
40
40
  raise TagError.new("`stylesheet' tag must contain a `slug' attribute.") unless slug
41
41
  if (stylesheet = StylesheetPage.find_by_slug(slug))
42
42
  mime_type = tag.attr['type'] || stylesheet.headers['Content-Type']
43
- url = stylesheet.url.sub(/\/$/,'') + '?' + stylesheet.updated_at.to_i.to_s
43
+ path = stylesheet.path
44
44
  rel = tag.attr.delete('rel') || 'stylesheet'
45
45
  optional_attributes = tag.attr.except('slug', 'name', 'as', 'type').inject('') { |s, (k, v)| s << %{#{k}="#{v}" } }.strip
46
46
  optional_attributes = " #{optional_attributes}" unless optional_attributes.empty?
47
47
  case tag.attr['as']
48
- when 'url'
49
- url
48
+ when 'url','path'
49
+ path
50
50
  when 'inline'
51
51
  %{<style type="#{mime_type}"#{optional_attributes}>\n/*<![CDATA[*/\n#{stylesheet.render_part('body')}\n/*]]>*/\n</style>}
52
52
  when 'link'
53
- %{<link rel="#{rel}" type="#{mime_type}" href="#{url}"#{optional_attributes} />}
53
+ %{<link rel="#{rel}" type="#{mime_type}" href="#{path}"#{optional_attributes} />}
54
54
  else
55
55
  stylesheet.render_part('body')
56
56
  end
@@ -24,9 +24,4 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.add_dependency 'sass', '~>3.1.2'
26
26
  s.add_dependency 'coffee-script', '~>2.2.0'
27
-
28
- s.post_install_message = %{
29
- Add this to your radiant project with:
30
- config.gem 'radiant-sheets-extension', :version => '~>#{RadiantSheetsExtension::VERSION}'
31
- }
32
27
  end
data/sheets_extension.rb CHANGED
@@ -20,11 +20,6 @@ class SheetsExtension < Radiant::Extension
20
20
  @@javascript_filters ||= []
21
21
  @@javascript_filters << CoffeeFilter
22
22
 
23
- extension_config do |config|
24
- config.gem 'coffee-script', :version => '~> 2.2.0'
25
- config.gem 'sass', :version => '~> 3.1.2'
26
- end
27
-
28
23
  def activate
29
24
  SassFilter
30
25
  ScssFilter
@@ -76,10 +71,11 @@ class SheetsExtension < Radiant::Extension
76
71
  end
77
72
 
78
73
  SiteController.class_eval do
79
- cattr_writer :sheet_cache_timeout
80
-
81
74
  def self.sheet_cache_timeout
82
- @@sheet_cache_timeout ||= 30.days
75
+ @sheet_cache_timeout ||= 30.days
76
+ end
77
+ def self.sheet_cache_timeout=(val)
78
+ @sheet_cache_timeout = val
83
79
  end
84
80
 
85
81
  def set_cache_control_with_sheets
@@ -12,10 +12,10 @@ describe "Javascript Tags" do
12
12
  it { should render(%{<r:javascript />}).with_error("`javascript' tag must contain a `slug' attribute.") }
13
13
  it { should render(%{<r:javascript slug="bogus" />}).with_error("javascript bogus not found") }
14
14
  it { should render(%{<r:javascript slug="site.js" />}).as('alert("site!");') }
15
- it { should render(%{<r:javascript slug="site.js" as="url" />}).as("/js/site.js?#{javascript_page.updated_at.to_i}") }
16
- it { should render(%{<r:javascript slug="site.js" as="link" />}).as(%{<script type="#{javascript_page.headers['Content-Type']}" src="#{javascript_page.url.gsub(/\/$/,'')}?#{javascript_page.updated_at.to_i.to_s}"></script>}) }
17
- it { should render(%{<r:javascript slug="site.js" as="link" type="special/type" />}).as(%{<script type="special/type" src="#{javascript_page.url.gsub(/\/$/,'')}?#{javascript_page.updated_at.to_i.to_s}"></script>}) }
18
- it { should render(%{<r:javascript slug="site.js" as="link" something="custom" />}).as(%{<script type="#{javascript_page.headers['Content-Type']}" src="#{javascript_page.url.gsub(/\/$/,'')}?#{javascript_page.updated_at.to_i.to_s}" something="custom"></script>}) }
15
+ it { should render(%{<r:javascript slug="site.js" as="url" />}).as("/js/site.js?#{javascript_page.digest}") }
16
+ it { should render(%{<r:javascript slug="site.js" as="link" />}).as(%{<script type="#{javascript_page.headers['Content-Type']}" src="#{javascript_page.path}"></script>}) }
17
+ it { should render(%{<r:javascript slug="site.js" as="link" type="special/type" />}).as(%{<script type="special/type" src="#{javascript_page.path}"></script>}) }
18
+ it { should render(%{<r:javascript slug="site.js" as="link" something="custom" />}).as(%{<script type="#{javascript_page.headers['Content-Type']}" src="#{javascript_page.path}" something="custom"></script>}) }
19
19
  it { should render(%{<r:javascript slug="site.js" as="inline" />}).as(%{<script type="#{javascript_page.headers['Content-Type']}">
20
20
  //<![CDATA[
21
21
  alert("site!");
@@ -12,11 +12,11 @@ describe "Stylesheet Tags" do
12
12
  it { should render(%{<r:stylesheet />}).with_error("`stylesheet' tag must contain a `slug' attribute.") }
13
13
  it { should render(%{<r:stylesheet slug="bogus" />}).with_error("stylesheet bogus not found") }
14
14
  it { should render(%{<r:stylesheet slug="site.css" />}).as("p { color: blue; }") }
15
- it { should render(%{<r:stylesheet slug="site.css" as="url" />}).as("/css/site.css?#{site_css.updated_at.to_i}") }
16
- it { should render(%{<r:stylesheet slug="site.css" as="link" />}).as(%{<link rel="stylesheet" type="text/css" href="/css/site.css?#{site_css.updated_at.to_i.to_s}" />}) }
17
- it { should render(%{<r:stylesheet slug="site.css" as="link" type="special/type" />}).as(%{<link rel="stylesheet" type="special/type" href="/css/site.css?#{site_css.updated_at.to_i.to_s}" />}) }
18
- it { should render(%{<r:stylesheet slug="site.css" as="link" something="custom" />}).as(%{<link rel="stylesheet" type="text/css" href="/css/site.css?#{site_css.updated_at.to_i.to_s}" something="custom" />}) }
19
- it { should render(%{<r:stylesheet slug="site.css" as="link" rel="alternate" />}).as(%{<link rel="alternate" type="text/css" href="/css/site.css?#{site_css.updated_at.to_i.to_s}" />}) }
15
+ it { should render(%{<r:stylesheet slug="site.css" as="url" />}).as("/css/site.css?#{site_css.digest}") }
16
+ it { should render(%{<r:stylesheet slug="site.css" as="link" />}).as(%{<link rel="stylesheet" type="text/css" href="/css/site.css?#{site_css.digest}" />}) }
17
+ it { should render(%{<r:stylesheet slug="site.css" as="link" type="special/type" />}).as(%{<link rel="stylesheet" type="special/type" href="/css/site.css?#{site_css.digest}" />}) }
18
+ it { should render(%{<r:stylesheet slug="site.css" as="link" something="custom" />}).as(%{<link rel="stylesheet" type="text/css" href="/css/site.css?#{site_css.digest}" something="custom" />}) }
19
+ it { should render(%{<r:stylesheet slug="site.css" as="link" rel="alternate" />}).as(%{<link rel="alternate" type="text/css" href="/css/site.css?#{site_css.digest}" />}) }
20
20
  it { should render(%{<r:stylesheet slug="site.css" as="inline" />}).as(%{<style type="text/css">
21
21
  /*<![CDATA[*/
22
22
  p { color: blue; }
@@ -41,6 +41,21 @@ describe JavascriptPage do
41
41
  end
42
42
  end
43
43
 
44
+ describe '#digest' do
45
+ it 'should return an md5 hash of the rendered contents' do
46
+ site_js.digest.should == Digest::MD5.hexdigest(site_js.render)
47
+ end
48
+ end
49
+
50
+ describe '#path' do
51
+ it 'should include an md5 hash of the rendered contents' do
52
+ site_js.path.should == "/js/site.js?#{site_js.digest}"
53
+ end
54
+ it 'should not include an md5 hash of the rendered contents for the root' do
55
+ javascript.path.should == "/js/"
56
+ end
57
+ end
58
+
44
59
  context 'when validating a new page' do
45
60
  it "should automatically set the title to the given slug" do
46
61
  j = JavascriptPage.new(:slug => 'site.js')
@@ -41,6 +41,21 @@ describe StylesheetPage do
41
41
  end
42
42
  end
43
43
 
44
+ describe '#digest' do
45
+ it 'should return an md5 hash of the rendered contents' do
46
+ site_css.digest.should == Digest::MD5.hexdigest(site_css.render)
47
+ end
48
+ end
49
+
50
+ describe '#path' do
51
+ it 'should include an md5 hash of the rendered contents' do
52
+ site_css.path.should == "/css/site.css?#{site_css.digest}"
53
+ end
54
+ it 'should not include an md5 hash of the rendered contents for the root' do
55
+ css.path.should == "/css/"
56
+ end
57
+ end
58
+
44
59
  context 'when validating a new page' do
45
60
  it "should automatically set the title to the given slug" do
46
61
  j = StylesheetPage.new(:slug => 'site.css')
@@ -77,4 +92,5 @@ describe StylesheetPage do
77
92
  end
78
93
  end
79
94
  end
95
+
80
96
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radiant-sheets-extension
3
3
  version: !ruby/object:Gem::Version
4
- hash: 961915988
5
- prerelease: 6
4
+ hash: 23
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
9
  - 0
10
- - pre
11
- version: 1.0.0.pre
10
+ version: 1.0.0
12
11
  platform: ruby
13
12
  authors:
14
13
  - Radiant CMS Dev Team
@@ -16,8 +15,7 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2011-06-03 00:00:00 -04:00
20
- default_executable:
18
+ date: 2011-09-15 00:00:00 Z
21
19
  dependencies:
22
20
  - !ruby/object:Gem::Dependency
23
21
  name: sass
@@ -113,11 +111,10 @@ files:
113
111
  - spec/models/stylesheet_page_spec.rb
114
112
  - spec/spec.opts
115
113
  - spec/spec_helper.rb
116
- has_rdoc: true
117
114
  homepage: http://radiantcms.org/
118
115
  licenses: []
119
116
 
120
- post_install_message: "\n Add this to your radiant project with:\n config.gem 'radiant-sheets-extension', :version => '~>1.0.0.pre'\n "
117
+ post_install_message:
121
118
  rdoc_options: []
122
119
 
123
120
  require_paths:
@@ -134,18 +131,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
131
  required_rubygems_version: !ruby/object:Gem::Requirement
135
132
  none: false
136
133
  requirements:
137
- - - ">"
134
+ - - ">="
138
135
  - !ruby/object:Gem::Version
139
- hash: 25
136
+ hash: 3
140
137
  segments:
141
- - 1
142
- - 3
143
- - 1
144
- version: 1.3.1
138
+ - 0
139
+ version: "0"
145
140
  requirements: []
146
141
 
147
142
  rubyforge_project:
148
- rubygems_version: 1.6.2
143
+ rubygems_version: 1.8.8
149
144
  signing_key:
150
145
  specification_version: 3
151
146
  summary: Sheets for Radiant CMS