radiant-sheets-extension 1.0.0.pre → 1.0.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.
@@ -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