comfortable_mexican_sofa 1.6.11 → 1.6.12

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.
Files changed (47) hide show
  1. data/README.md +2 -0
  2. data/VERSION +1 -1
  3. data/app/assets/stylesheets/comfortable_mexican_sofa/content.css +23 -0
  4. data/app/assets/stylesheets/comfortable_mexican_sofa/form.css +3 -0
  5. data/app/assets/stylesheets/comfortable_mexican_sofa/typography.css +3 -0
  6. data/app/controllers/cms_admin/base_controller.rb +4 -0
  7. data/app/controllers/cms_admin/sites_controller.rb +1 -1
  8. data/app/models/cms/layout.rb +1 -0
  9. data/app/models/cms/page.rb +1 -0
  10. data/app/views/cms_admin/files/edit.html.erb +1 -1
  11. data/app/views/cms_admin/files/new.html.erb +1 -1
  12. data/app/views/cms_admin/layouts/edit.html.erb +1 -1
  13. data/app/views/cms_admin/layouts/new.html.erb +1 -1
  14. data/app/views/cms_admin/pages/edit.html.erb +1 -1
  15. data/app/views/cms_admin/pages/new.html.erb +1 -1
  16. data/app/views/cms_admin/revisions/show.html.erb +1 -1
  17. data/app/views/cms_admin/sites/edit.html.erb +1 -1
  18. data/app/views/cms_admin/sites/new.html.erb +1 -1
  19. data/app/views/cms_admin/snippets/edit.html.erb +1 -1
  20. data/app/views/cms_admin/snippets/new.html.erb +1 -1
  21. data/app/views/cms_content/render_sitemap.xml.builder +1 -0
  22. data/comfortable_mexican_sofa.gemspec +4 -2
  23. data/config/initializers/comfortable_mexican_sofa.rb +20 -4
  24. data/config/routes.rb +2 -2
  25. data/lib/comfortable_mexican_sofa.rb +2 -1
  26. data/lib/comfortable_mexican_sofa/authentication/dummy_auth.rb +2 -2
  27. data/lib/comfortable_mexican_sofa/authentication/http_auth.rb +2 -1
  28. data/lib/comfortable_mexican_sofa/configuration.rb +25 -5
  29. data/lib/comfortable_mexican_sofa/fixtures.rb +11 -1
  30. data/lib/comfortable_mexican_sofa/form_builder.rb +1 -1
  31. data/lib/comfortable_mexican_sofa/render_methods.rb +0 -1
  32. data/lib/comfortable_mexican_sofa/sitemap.rb +27 -0
  33. data/lib/comfortable_mexican_sofa/tag.rb +8 -1
  34. data/lib/comfortable_mexican_sofa/tags/helper.rb +11 -0
  35. data/lib/comfortable_mexican_sofa/tags/partial.rb +9 -0
  36. data/lib/comfortable_mexican_sofa/view_methods.rb +1 -1
  37. data/test/functional/cms_content_controller_test.rb +17 -0
  38. data/test/integration/routing_extensions_test.rb +9 -0
  39. data/test/test_helper.rb +5 -1
  40. data/test/unit/configuration_test.rb +6 -1
  41. data/test/unit/fixtures_test.rb +32 -3
  42. data/test/unit/form_builder_test.rb +5 -5
  43. data/test/unit/sitemap_test.rb +20 -0
  44. data/test/unit/tag_test.rb +8 -0
  45. data/test/unit/tags/helper_test.rb +27 -0
  46. data/test/unit/tags/partial_test.rb +16 -0
  47. metadata +11 -9
data/README.md CHANGED
@@ -52,6 +52,8 @@ For more information please [see Wiki pages](https://github.com/comfy/comfortabl
52
52
 
53
53
  ![Sofa's Page Edit View](https://github.com/comfy/comfortable-mexican-sofa/raw/master/doc/preview.png)
54
54
 
55
+ ---
56
+
55
57
  ComfortableMexicanSofa is released under the [MIT license](https://github.com/comfy/comfortable-mexican-sofa/raw/master/LICENSE)
56
58
 
57
59
  Copyright 2009-2011 Oleg Khabarov, [The Working Group Inc](http://www.twg.ca)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.11
1
+ 1.6.12
@@ -175,6 +175,29 @@
175
175
  #cms_body ul.list li .item:hover {
176
176
  background-color: #fff;
177
177
  }
178
+ /* -- Tables ------------------------------------------------------------ */
179
+ #cms_body table.formatted {
180
+ width: 100%;
181
+ }
182
+ #cms_body table.formatted th, #cms_body table.formatted td {
183
+ white-space: nowrap;
184
+ padding: 6px;
185
+ background-color: #f1f1f1;
186
+ border-bottom: 2px solid #e6e6e6;
187
+ vertical-align: top;
188
+ }
189
+ #cms_body table.formatted th.main, #cms_body table.formatted td.main {
190
+ white-space: normal;
191
+ width: 100%;
192
+ }
193
+ #cms_body table.formatted th {
194
+ color: #000;
195
+ border-color: #9f9f9f;
196
+ }
197
+ #cms_body table.formatted tr:hover td {
198
+ background-color: #fff
199
+ }
200
+
178
201
  /* -- Missing Translations ---------------------------------------------- */
179
202
  #cms_body .translation_missing {
180
203
  text-decoration: blink;
@@ -176,4 +176,7 @@
176
176
  text-transform: uppercase;
177
177
  color: #fff;
178
178
  margin-bottom: 3px;
179
+ }
180
+ #cms_body .form_element.simple_field .value input {
181
+ margin-bottom: 3px;
179
182
  }
@@ -18,6 +18,9 @@ body#cms_body {
18
18
  #cms_body h1 + h2 {
19
19
  margin-top: -15px;
20
20
  }
21
+ #cms_body p {
22
+ margin-bottom: 15px;
23
+ }
21
24
  #cms_body a {
22
25
  text-decoration: none;
23
26
  color: #384E66;
@@ -13,6 +13,10 @@ class CmsAdmin::BaseController < ApplicationController
13
13
 
14
14
  layout 'cms_admin'
15
15
 
16
+ if ComfortableMexicanSofa.config.admin_cache_sweeper.present?
17
+ cache_sweeper *ComfortableMexicanSofa.config.admin_cache_sweeper
18
+ end
19
+
16
20
  def jump
17
21
  path = ComfortableMexicanSofa.config.admin_route_redirect
18
22
  return redirect_to(path) unless path.blank?
@@ -60,4 +60,4 @@ protected
60
60
  redirect_to :action => :index
61
61
  end
62
62
 
63
- end
63
+ end
@@ -77,6 +77,7 @@ protected
77
77
  end
78
78
 
79
79
  def assign_position
80
+ return if self.position.to_i > 0
80
81
  max = self.site.layouts.where(:parent_id => self.parent_id).maximum(:position)
81
82
  self.position = max ? max + 1 : 0
82
83
  end
@@ -157,6 +157,7 @@ protected
157
157
  end
158
158
  end
159
159
 
160
+ # NOTE: This can create 'phantom' page blocks as they are defined in the layout. This is normal.
160
161
  def set_cached_content
161
162
  write_attribute(:content, self.content(true))
162
163
  end
@@ -1,5 +1,5 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= cms_form_for @file, :as => :file, :url => {:action => :update} do |form| %>
3
+ <%= comfy_form_for @file, :as => :file, :url => {:action => :update} do |form| %>
4
4
  <%= render :partial => 'form', :object => form %>
5
5
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= cms_form_for @file, :as => :file, :url => {:action => :create}, :html => {:multipart => true} do |form| %>
3
+ <%= comfy_form_for @file, :as => :file, :url => {:action => :create}, :html => {:multipart => true} do |form| %>
4
4
  <%= render :partial => 'form', :object => form %>
5
5
  <% end %>
@@ -6,6 +6,6 @@
6
6
  <%= render :partial => 'cms_admin/sites/mirrors', :object => @layout %>
7
7
  <% end %>
8
8
 
9
- <%= cms_form_for @layout, :as => :layout, :url => {:action => :update} do |form| %>
9
+ <%= comfy_form_for @layout, :as => :layout, :url => {:action => :update} do |form| %>
10
10
  <%= render :partial => 'form', :object => form %>
11
11
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= cms_form_for @layout, :as => :layout, :url => {:action => :create} do |form| %>
3
+ <%= comfy_form_for @layout, :as => :layout, :url => {:action => :create} do |form| %>
4
4
  <%= render :partial => 'form', :object => form %>
5
5
  <% end %>
@@ -6,6 +6,6 @@
6
6
  <%= render :partial => 'cms_admin/sites/mirrors', :object => @page %>
7
7
  <% end %>
8
8
 
9
- <%= cms_form_for @page, :as => :page, :url => {:action => :update}, :html => {:multipart => true} do |form| %>
9
+ <%= comfy_form_for @page, :as => :page, :url => {:action => :update}, :html => {:multipart => true} do |form| %>
10
10
  <%= render :partial => 'form', :object => form %>
11
11
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= cms_form_for @page, :as => :page, :url => {:action => :create}, :html => {:multipart => true} do |form| %>
3
+ <%= comfy_form_for @page, :as => :page, :url => {:action => :create}, :html => {:multipart => true} do |form| %>
4
4
  <%= render :partial => 'form', :object => form %>
5
5
  <% end %>
@@ -10,7 +10,7 @@
10
10
  </div>
11
11
  <% end %>
12
12
 
13
- <%= cms_form_for @revision, :url => {:action => :revert} do |form| %>
13
+ <%= comfy_form_for @revision, :url => {:action => :revert} do |form| %>
14
14
  <%= form.simple_field do %>
15
15
  <div class='current'>
16
16
  <div class='title'>Current</div>
@@ -1,5 +1,5 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= cms_form_for @site, :as => :site, :url => {:action => :update} do |form| %>
3
+ <%= comfy_form_for @site, :as => :site, :url => {:action => :update} do |form| %>
4
4
  <%= render :partial => 'form', :object => form %>
5
5
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= cms_form_for @site, :as => :site, :url => {:action => :create} do |form| %>
3
+ <%= comfy_form_for @site, :as => :site, :url => {:action => :create} do |form| %>
4
4
  <%= render :partial => 'form', :object => form %>
5
5
  <% end %>
@@ -5,6 +5,6 @@
5
5
  <%= render :partial => 'cms_admin/sites/mirrors', :object => @snippet %>
6
6
  <% end %>
7
7
 
8
- <%= cms_form_for @snippet, :as => :snippet, :url => {:action => :update} do |form| %>
8
+ <%= comfy_form_for @snippet, :as => :snippet, :url => {:action => :update} do |form| %>
9
9
  <%= render :partial => 'form', :object => form %>
10
10
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= cms_form_for @snippet, :as => :snippet, :url => {:action => :create} do |form| %>
3
+ <%= comfy_form_for @snippet, :as => :snippet, :url => {:action => :create} do |form| %>
4
4
  <%= render :partial => 'form', :object => form %>
5
5
  <% end %>
@@ -11,4 +11,5 @@ xml.urlset :xmlns => 'http://www.sitemaps.org/schemas/sitemap/0.9' do
11
11
  xml.lastmod page.updated_at.strftime('%Y-%m-%d')
12
12
  end
13
13
  end
14
+ ComfortableMexicanSofa::Sitemap.process(@cms_site, self, xml)
14
15
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "comfortable_mexican_sofa"
8
- s.version = "1.6.11"
8
+ s.version = "1.6.12"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Oleg Khabarov", "The Working Group Inc"]
12
- s.date = "2012-02-08"
12
+ s.date = "2012-02-21"
13
13
  s.description = ""
14
14
  s.email = "oleg@theworkinggroup.ca"
15
15
  s.extra_rdoc_files = [
@@ -218,6 +218,7 @@ Gem::Specification.new do |s|
218
218
  "lib/comfortable_mexican_sofa/fixtures.rb",
219
219
  "lib/comfortable_mexican_sofa/form_builder.rb",
220
220
  "lib/comfortable_mexican_sofa/render_methods.rb",
221
+ "lib/comfortable_mexican_sofa/sitemap.rb",
221
222
  "lib/comfortable_mexican_sofa/tag.rb",
222
223
  "lib/comfortable_mexican_sofa/tags/asset.rb",
223
224
  "lib/comfortable_mexican_sofa/tags/collection.rb",
@@ -295,6 +296,7 @@ Gem::Specification.new do |s|
295
296
  "test/unit/models/site_test.rb",
296
297
  "test/unit/models/snippet_test.rb",
297
298
  "test/unit/revisions_test.rb",
299
+ "test/unit/sitemap_test.rb",
298
300
  "test/unit/tag_test.rb",
299
301
  "test/unit/tags/asset_test.rb",
300
302
  "test/unit/tags/collection_test.rb",
@@ -22,10 +22,9 @@ ComfortableMexicanSofa.configure do |config|
22
22
  # for example '/cms-admin/users'
23
23
  # config.admin_route_redirect = ''
24
24
 
25
- # By default you cannot have irb code inside your layouts/pages/snippets.
26
- # Generally this is to prevent putting something like this:
27
- # <% User.delete_all %> but if you really want to allow it...
28
- # config.allow_irb = false
25
+ # Normally we include default routes from https://github.com/comfy/comfortable-mexican-sofa/blob/master/config/routes.rb
26
+ # If you want to include the routes manually set this to false
27
+ # config.use_default_routes = true
29
28
 
30
29
  # File uploads use Paperclip and can support filesystem or s3 uploads. Override
31
30
  # the upload method and appropriate settings based on Paperclip. For S3 see:
@@ -71,6 +70,23 @@ ComfortableMexicanSofa.configure do |config|
71
70
  # definition in your database.yml file
72
71
  # config.database_config = nil
73
72
 
73
+ # A class that is included as a sweeper to admin base controller if it's set
74
+ # config.admin_cache_sweeper = nil
75
+
76
+ # By default you cannot have irb code inside your layouts/pages/snippets.
77
+ # Generally this is to prevent putting something like this:
78
+ # <% User.delete_all %> but if you really want to allow it...
79
+ # config.allow_irb = false
80
+
81
+ # Whitelist of all helper methods that can be used via {{cms:helper}} tag. By default
82
+ # all helpers are allowed except `eval`, `send`, `call` and few others. Empty array
83
+ # will prevent rendering of all helpers.
84
+ # config.allowed_helpers = nil
85
+
86
+ # Whitelist of partials paths that can be used via {{cms:partial}} tag. All partials
87
+ # are accessible by default. Empty array will prevent rendering of all partials.
88
+ # config.allowed_partials = nil
89
+
74
90
  end
75
91
 
76
92
  # Default credentials for ComfortableMexicanSofa::HttpAuth
data/config/routes.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  Rails.application.routes.draw do
2
-
2
+
3
3
  namespace :cms_admin, :path => ComfortableMexicanSofa.config.admin_route_prefix, :except => :show do
4
4
  get '/', :to => 'base#jump'
5
5
  resources :sites do
@@ -41,4 +41,4 @@ Rails.application.routes.draw do
41
41
  get '/' => :render_html, :as => 'cms_html', :path => "(*cms_path)"
42
42
  end
43
43
 
44
- end
44
+ end if ComfortableMexicanSofa.config.use_default_routes
@@ -13,6 +13,7 @@ end
13
13
  'comfortable_mexican_sofa/view_methods',
14
14
  'comfortable_mexican_sofa/form_builder',
15
15
  'comfortable_mexican_sofa/tag',
16
+ 'comfortable_mexican_sofa/sitemap',
16
17
  'comfortable_mexican_sofa/fixtures',
17
18
  'comfortable_mexican_sofa/extensions/rails',
18
19
  'comfortable_mexican_sofa/extensions/acts_as_tree',
@@ -66,4 +67,4 @@ module ComfortableMexicanSofa
66
67
  end
67
68
 
68
69
  end
69
- end
70
+ end
@@ -1,8 +1,8 @@
1
1
  module ComfortableMexicanSofa::DummyAuth
2
-
2
+
3
3
  # Will always let you in
4
4
  def authenticate
5
5
  true
6
6
  end
7
7
 
8
- end
8
+ end
@@ -14,4 +14,5 @@ module ComfortableMexicanSofa::HttpAuth
14
14
  username == self.username && password == self.password
15
15
  end
16
16
  end
17
- end
17
+
18
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  class ComfortableMexicanSofa::Configuration
4
4
 
5
- # Don't like Comfortable Mexican Sofa? Set it to whatever you like. :(
5
+ # Don't like ComfortableMexicanSofa? Set it to whatever you like. :(
6
6
  attr_accessor :cms_title
7
7
 
8
8
  # Module that will handle authentication to access cms-admin area
@@ -18,9 +18,10 @@ class ComfortableMexicanSofa::Configuration
18
18
  # When arriving at /cms-admin you may chose to redirect to arbirtary path,
19
19
  # for example '/cms-admin/users'
20
20
  attr_accessor :admin_route_redirect
21
-
22
- # Not allowing irb code to be run inside page content. False by default.
23
- attr_accessor :allow_irb
21
+
22
+ # Normally we include default routes from https://github.com/comfy/comfortable-mexican-sofa/blob/master/config/routes.rb
23
+ # If you want to include the routes manually set this to false
24
+ attr_accessor :use_default_routes
24
25
 
25
26
  # Upload settings
26
27
  attr_accessor :upload_file_options
@@ -49,6 +50,21 @@ class ComfortableMexicanSofa::Configuration
49
50
  # in your database.yml file
50
51
  attr_accessor :database_config
51
52
 
53
+ # A class that is included as a sweeper to admin base controller if it's set
54
+ attr_accessor :admin_cache_sweeper
55
+
56
+ # Not allowing irb code to be run inside page content. False by default.
57
+ attr_accessor :allow_irb
58
+
59
+ # Whitelist of all helper methods that can be used via {{cms:helper}} tag. By default
60
+ # all helpers are allowed except `eval`, `send`, `call` and few others. Empty array
61
+ # will prevent rendering of all helpers.
62
+ attr_accessor :allowed_helpers
63
+
64
+ # Whitelist of partials paths that can be used via {{cms:partial}} tag. All partials
65
+ # are accessible by default. Empty array will prevent rendering of all partials.
66
+ attr_accessor :allowed_partials
67
+
52
68
  # Configuration defaults
53
69
  def initialize
54
70
  @cms_title = 'ComfortableMexicanSofa CMS Engine'
@@ -57,7 +73,7 @@ class ComfortableMexicanSofa::Configuration
57
73
  @seed_data_path = nil
58
74
  @admin_route_prefix = 'cms-admin'
59
75
  @admin_route_redirect = ''
60
- @allow_irb = false
76
+ @use_default_routes = true
61
77
  @upload_file_options = { :url => '/system/:class/:id/:attachment/:style/:filename' }
62
78
  @enable_fixtures = false
63
79
  @fixtures_path = File.expand_path('db/cms_fixtures', Rails.root)
@@ -70,6 +86,10 @@ class ComfortableMexicanSofa::Configuration
70
86
  }
71
87
  @admin_locale = nil
72
88
  @database_config = nil
89
+ @admin_cache_sweeper = nil
90
+ @allow_irb = false
91
+ @allowed_helpers = nil
92
+ @allowed_partials = nil
73
93
  end
74
94
 
75
95
  end
@@ -110,10 +110,12 @@ module ComfortableMexicanSofa::Fixtures
110
110
  end
111
111
 
112
112
  # updating content
113
+ blocks_to_clear = page.blocks.collect(&:identifier)
113
114
  blocks_attributes = [ ]
114
115
  Dir.glob("#{path}/*.html").each do |file_path|
116
+ identifier = file_path.split('/').last.split('.').first
117
+ blocks_to_clear.delete(identifier)
115
118
  if page.new_record? || File.mtime(file_path) > page.updated_at
116
- identifier = file_path.split('/').last.split('.').first
117
119
  blocks_attributes << {
118
120
  :identifier => identifier,
119
121
  :content => File.open(file_path).read
@@ -121,6 +123,14 @@ module ComfortableMexicanSofa::Fixtures
121
123
  end
122
124
  end
123
125
 
126
+ # clearing removed blocks
127
+ blocks_to_clear.each do |identifier|
128
+ blocks_attributes << {
129
+ :identifier => identifier,
130
+ :content => nil
131
+ }
132
+ end
133
+
124
134
  # saving
125
135
  page.blocks_attributes = blocks_attributes if blocks_attributes.present?
126
136
  if page.changed? || blocks_attributes.present?
@@ -35,7 +35,7 @@ class ComfortableMexicanSofa::FormBuilder < ActionView::Helpers::FormBuilder
35
35
  def simple_field(label = nil, content = nil, options = {}, &block)
36
36
  content ||= @template.capture(&block) if block_given?
37
37
  %(
38
- <div class='form_element #{options.delete(:class)}'>
38
+ <div class='form_element simple_field #{options.delete(:class)}'>
39
39
  <div class='label'>#{label}</div>
40
40
  <div class='value'>#{content}</div>
41
41
  </div>
@@ -36,7 +36,6 @@ module ComfortableMexicanSofa::RenderMethods
36
36
  #
37
37
  def render(options = {}, locals = {}, &block)
38
38
 
39
- # TODO: add slug to Cms::Site as well
40
39
  if options.is_a?(Hash) && identifier = options.delete(:cms_site)
41
40
  unless @cms_site = Cms::Site.find_by_identifier(identifier)
42
41
  raise ComfortableMexicanSofa::MissingSite.new(identifier)
@@ -0,0 +1,27 @@
1
+ class ComfortableMexicanSofa::Sitemap
2
+
3
+ # we want our callback to include the cms_site and
4
+ # the view so we have whatever routes are available to us
5
+ # xml is an xml_builder which expects a sitemap url definition, e.g:
6
+ # xml.url do
7
+ # xml.loc view.url_for("http://example.org/example")
8
+ # xml.lastmod 2.days.ago.strftime('%Y-%m-%d')
9
+ # end
10
+ def self.process(cms_site, view, xml)
11
+ self.sitemap_extensions.each do |extension|
12
+ extension.call(cms_site, view, xml)
13
+ end
14
+ end
15
+
16
+ def self.register_extension(callback)
17
+ self.sitemap_extensions.push(callback)
18
+ end
19
+
20
+ private
21
+
22
+ # A list of registered sitemap extension methods
23
+ def self.sitemap_extensions
24
+ @@sitemap_extensions ||= []
25
+ end
26
+
27
+ end
@@ -31,10 +31,17 @@ module ComfortableMexicanSofa::Tag
31
31
  # First capture group in the regex is the tag identifier
32
32
  def initialize_tag(page, tag_signature)
33
33
  if match = tag_signature.match(regex_tag_signature)
34
+
35
+ params = begin
36
+ (CSV.parse_line(match[2].to_s, (RUBY_VERSION < '1.9.2' ? ':' : {:col_sep => ':'})) || []).compact
37
+ rescue
38
+ []
39
+ end.map{|p| p.gsub(/\\|'/) { |c| "\\#{c}" } }
40
+
34
41
  tag = self.new
35
42
  tag.page = page
36
43
  tag.identifier = match[1]
37
- tag.params = (CSV.parse_line(match[2].to_s, (RUBY_VERSION < '1.9.2' ? ':' : {:col_sep => ':'})) || []).compact
44
+ tag.params = params
38
45
  tag
39
46
  end
40
47
  end
@@ -1,6 +1,8 @@
1
1
  class ComfortableMexicanSofa::Tag::Helper
2
2
  include ComfortableMexicanSofa::Tag
3
3
 
4
+ BLACKLIST = %w(eval class_eval instance_eval render)
5
+
4
6
  def self.regex_tag_signature(identifier = nil)
5
7
  identifier ||= /[\w\-]+/
6
8
  /\{\{\s*cms:helper:(#{identifier}):?(.*?)\s*\}\}/
@@ -10,4 +12,13 @@ class ComfortableMexicanSofa::Tag::Helper
10
12
  "<%= #{identifier}(#{params.collect{|p| "'#{p}'"}.join(', ')}) %>"
11
13
  end
12
14
 
15
+ def render
16
+ whitelist = ComfortableMexicanSofa.config.allowed_helpers
17
+ if whitelist.is_a?(Array)
18
+ content if whitelist.map!(&:to_s).member?(identifier)
19
+ else
20
+ content unless BLACKLIST.member?(identifier)
21
+ end
22
+ end
23
+
13
24
  end
@@ -11,4 +11,13 @@ class ComfortableMexicanSofa::Tag::Partial
11
11
  "<%= render :partial => '#{identifier}'#{ps.blank?? nil : ", :locals => {#{ps}}"} %>"
12
12
  end
13
13
 
14
+ def render
15
+ whitelist = ComfortableMexicanSofa.config.allowed_partials
16
+ if whitelist.is_a?(Array)
17
+ content if whitelist.member?(identifier)
18
+ else
19
+ content
20
+ end
21
+ end
22
+
14
23
  end
@@ -1,6 +1,6 @@
1
1
  module ComfortableMexicanSofa::ViewMethods
2
2
  # Wrapper around CmsFormBuilder
3
- def cms_form_for(record_or_name_or_array, *args, &proc)
3
+ def comfy_form_for(record_or_name_or_array, *args, &proc)
4
4
  options = args.extract_options!
5
5
  form_for(record_or_name_or_array, *(args << options.merge(:builder => ComfortableMexicanSofa::FormBuilder)), &proc)
6
6
  end
@@ -182,4 +182,21 @@ class CmsContentControllerTest < ActionController::TestCase
182
182
  assert_match '<loc>http://test.host/en/child-page</loc>', response.body
183
183
  end
184
184
 
185
+ class TestRenderException
186
+ def self.callback(cms_site, view, xml)
187
+ xml.url do
188
+ # make sure we have the view
189
+ xml.loc view.url_for("http://test.host/test_render")
190
+ xml.lastmod 2.days.ago.strftime('%Y-%m-%d')
191
+ end
192
+ end
193
+ end
194
+
195
+ def test_rendering_sitemap_with_extensions
196
+ ComfortableMexicanSofa::Sitemap.register_extension(TestRenderException.method(:callback))
197
+ get :render_sitemap, :format => :xml
198
+ assert_response :success
199
+ assert_match '<loc>http://test.host/test_render</loc>', response.body
200
+ end
201
+
185
202
  end
@@ -35,4 +35,13 @@ class RoutingExtensionsTest < ActionDispatch::IntegrationTest
35
35
  assert_response 404
36
36
  end
37
37
 
38
+ def test_get_admin_with_all_routes_disabled
39
+ ComfortableMexicanSofa.config.use_default_routes = false
40
+ Rails.application.reload_routes!
41
+
42
+ assert_exception_raised ActionController::RoutingError do
43
+ http_auth :get, '/'
44
+ end
45
+ end
46
+
38
47
  end
data/test/test_helper.rb CHANGED
@@ -23,7 +23,7 @@ class ActiveSupport::TestCase
23
23
  config.public_auth = 'ComfortableMexicanSofa::DummyAuth'
24
24
  config.admin_route_prefix = 'cms-admin'
25
25
  config.admin_route_redirect = ''
26
- config.allow_irb = false
26
+ config.use_default_routes = true
27
27
  config.enable_fixtures = false
28
28
  config.fixtures_path = File.expand_path('db/cms_fixtures', Rails.root)
29
29
  config.revisions_limit = 25
@@ -35,6 +35,10 @@ class ActiveSupport::TestCase
35
35
  }
36
36
  config.admin_locale = nil
37
37
  config.upload_file_options = { :url => '/system/:class/:id/:attachment/:style/:filename' }
38
+ config.admin_cache_sweeper = nil
39
+ config.allow_irb = false
40
+ config.allowed_helpers = nil
41
+ config.allowed_partials = nil
38
42
  end
39
43
  ComfortableMexicanSofa::HttpAuth.username = 'username'
40
44
  ComfortableMexicanSofa::HttpAuth.password = 'password'
@@ -10,8 +10,9 @@ class ConfigurationTest < ActiveSupport::TestCase
10
10
  assert_equal 'ComfortableMexicanSofa::HttpAuth', config.admin_auth
11
11
  assert_equal 'ComfortableMexicanSofa::DummyAuth', config.public_auth
12
12
  assert_equal 'cms-admin', config.admin_route_prefix
13
+ assert_equal true, config.use_default_routes
13
14
  assert_equal '', config.admin_route_redirect
14
- assert_equal false, config.allow_irb
15
+
15
16
  assert_equal false, config.enable_fixtures
16
17
  assert_equal File.expand_path('db/cms_fixtures', Rails.root), config.fixtures_path
17
18
  assert_equal 25, config.revisions_limit
@@ -26,6 +27,10 @@ class ConfigurationTest < ActiveSupport::TestCase
26
27
  assert_equal ({
27
28
  :url => '/system/:class/:id/:attachment/:style/:filename'
28
29
  }), config.upload_file_options
30
+ assert_equal nil, config.admin_cache_sweeper
31
+ assert_equal false, config.allow_irb
32
+ assert_equal nil, config.allowed_helpers
33
+ assert_equal nil, config.allowed_partials
29
34
  end
30
35
 
31
36
  def test_initialization_overrides
@@ -124,7 +124,14 @@ class FixturesTest < ActiveSupport::TestCase
124
124
  end
125
125
 
126
126
  def test_import_pages_ignoring
127
- page = cms_pages(:default)
127
+ Cms::Page.destroy_all
128
+
129
+ page = cms_sites(:default).pages.create!(
130
+ :label => 'Test',
131
+ :layout => cms_layouts(:default),
132
+ :blocks_attributes => [ { :identifier => 'content', :content => 'test content' } ]
133
+ )
134
+
128
135
  page_path = File.join(ComfortableMexicanSofa.config.fixtures_path, 'example.com', 'pages', 'index')
129
136
  attr_file_path = File.join(page_path, '_index.yml')
130
137
  content_file_path = File.join(page_path, 'content.html')
@@ -134,9 +141,31 @@ class FixturesTest < ActiveSupport::TestCase
134
141
 
135
142
  ComfortableMexicanSofa::Fixtures.import_pages('test.host', 'example.com')
136
143
  page.reload
144
+
137
145
  assert_equal nil, page.slug
138
- assert_equal 'Default Page', page.label
139
- assert_equal "\nlayout_content_a\ndefault_page_text_content_a\ndefault_snippet_content\ndefault_page_text_content_b\nlayout_content_b\ndefault_snippet_content\nlayout_content_c", page.content
146
+ assert_equal 'Test', page.label
147
+ block = page.blocks.where(:identifier => 'content').first
148
+ assert_equal 'test content', block.content
149
+ end
150
+
151
+ def test_import_pages_removing_deleted_blocks
152
+ Cms::Page.destroy_all
153
+
154
+ page = cms_sites(:default).pages.create!(
155
+ :label => 'Test',
156
+ :layout => cms_layouts(:default),
157
+ :blocks_attributes => [ { :identifier => 'to_delete', :content => 'test content' } ]
158
+ )
159
+ page.update_attribute(:updated_at, 10.years.ago)
160
+
161
+ ComfortableMexicanSofa::Fixtures.import_pages('test.host', 'example.com')
162
+ page.reload
163
+
164
+ block = page.blocks.where(:identifier => 'content').first
165
+ assert_equal "Home Page Fixture Contént\n{{ cms:snippet:default }}", block.content
166
+
167
+ block = page.blocks.where(:identifier => 'to_delete').first
168
+ assert_equal nil, block.content
140
169
  end
141
170
 
142
171
  def test_import_snippets_creating
@@ -4,7 +4,7 @@ class FormBuilderTest < ActionView::TestCase
4
4
  include ComfortableMexicanSofa::ViewMethods
5
5
 
6
6
  def test_form_render_basic
7
- concat( cms_form_for(cms_pages(:child), :url => '#') do |f|
7
+ concat( comfy_form_for(cms_pages(:child), :url => '#') do |f|
8
8
  f.text_area(:label) +
9
9
  f.text_field(:slug) +
10
10
  f.select(:parent_id, [['1', 'Parent']])
@@ -27,7 +27,7 @@ class FormBuilderTest < ActionView::TestCase
27
27
  end
28
28
 
29
29
  def test_form_render_with_custom_ids
30
- concat( cms_form_for(cms_pages(:child), :url => '#') do |f|
30
+ concat( comfy_form_for(cms_pages(:child), :url => '#') do |f|
31
31
  f.text_field(:label, :id => 'slugify') +
32
32
  f.text_field(:slug)
33
33
  end )
@@ -38,13 +38,13 @@ class FormBuilderTest < ActionView::TestCase
38
38
  end
39
39
 
40
40
  def test_form_label_with_html_safe_labels
41
- cms_form_for(cms_pages(:child), :url => '#') do |f|
41
+ comfy_form_for(cms_pages(:child), :url => '#') do |f|
42
42
  assert f.label_for(:is_published).html_safe?
43
43
  end
44
44
  end
45
45
 
46
46
  def test_form_label_custom_override
47
- concat( cms_form_for(cms_pages(:child), :url => '#') do |f|
47
+ concat( comfy_form_for(cms_pages(:child), :url => '#') do |f|
48
48
  f.text_field(:slug, :label => 'Custom')
49
49
  end )
50
50
  assert_select 'label[for="cms_page_slug"]', 'Custom'
@@ -55,7 +55,7 @@ class FormBuilderTest < ActionView::TestCase
55
55
  :attributes => { :slug => "Gulsty" },
56
56
  :activerecord => { :attributes => { :'cms/page' => { :label => 'Titlumtimpin' } } }
57
57
  } do
58
- concat( cms_form_for(cms_pages(:child), :url => '#') do |f|
58
+ concat( comfy_form_for(cms_pages(:child), :url => '#') do |f|
59
59
  f.text_field(:label) +
60
60
  f.text_field(:slug) +
61
61
  f.text_field(:parent_id)
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../test_helper', File.dirname(__FILE__))
2
+
3
+ class SitemapTest < ActiveSupport::TestCase
4
+ class DummySitemapExtension
5
+ @@calls = 0
6
+ def self.calls
7
+ @@calls
8
+ end
9
+ def self.callback(cms_site, view, xml)
10
+ @@calls = @@calls + 1
11
+ end
12
+ end
13
+
14
+ def test_should_get_registered_extensions
15
+ ComfortableMexicanSofa::Sitemap.register_extension(DummySitemapExtension.method(:callback))
16
+ ComfortableMexicanSofa::Sitemap.process(cms_sites(:default), nil, "xml")
17
+ assert_equal 1, DummySitemapExtension.calls
18
+ end
19
+
20
+ end
@@ -266,4 +266,12 @@ class TagTest < ActiveSupport::TestCase
266
266
  assert_equal "<% 1 + 1 %> text <% 2 + 2 %> snippet <%= 2 + 2 %> <%= render :partial => 'path/to' %> <%= method() %> text <%= render :partial => 'partials/cms/snippets', :locals => {:model => 'Cms::Snippet', :identifier => '#{snippet.id}'} %> <%= 1 + 1 %>", page.content
267
267
  end
268
268
 
269
+ def test_escaping_of_parameters
270
+ tag = ComfortableMexicanSofa::Tag::Helper.initialize_tag(
271
+ cms_pages(:default), '{{cms:helper:h:"\'+User.first.inspect+\'"}}'
272
+ )
273
+ assert_equal %{<%= h('\\'+User.first.inspect+\\'') %>}, tag.content
274
+ assert_equal %{<%= h('\\'+User.first.inspect+\\'') %>}, tag.render
275
+ end
276
+
269
277
  end
@@ -56,4 +56,31 @@ class HelperTagTest < ActiveSupport::TestCase
56
56
  assert_equal "<%= method_name('param1', 'param2') %>", tag.render
57
57
  end
58
58
 
59
+ def test_blacklisted_methods
60
+ ComfortableMexicanSofa::Tag::Helper::BLACKLIST.each do |method|
61
+ tag = ComfortableMexicanSofa::Tag::Helper.initialize_tag(
62
+ cms_pages(:default), "{{ cms:helper:#{method}:Rails.env }}"
63
+ )
64
+ assert_equal "<%= #{method}('Rails.env') %>", tag.content
65
+ assert_equal nil, tag.render
66
+ end
67
+ end
68
+
69
+ def test_whitelisted_methods
70
+ ComfortableMexicanSofa.config.allowed_helpers = [:tester, :eval]
71
+ ComfortableMexicanSofa.config.allowed_helpers.each do |method|
72
+ tag = ComfortableMexicanSofa::Tag::Helper.initialize_tag(
73
+ cms_pages(:default), "{{ cms:helper:#{method}:Rails.env }}"
74
+ )
75
+ assert_equal "<%= #{method}('Rails.env') %>", tag.content
76
+ assert_equal "<%= #{method}('Rails.env') %>", tag.render
77
+ end
78
+
79
+ tag = ComfortableMexicanSofa::Tag::Helper.initialize_tag(
80
+ cms_pages(:default), "{{ cms:helper:invalid:Rails.env }}"
81
+ )
82
+ assert_equal "<%= invalid('Rails.env') %>", tag.content
83
+ assert_equal nil, tag.render
84
+ end
85
+
59
86
  end
@@ -57,4 +57,20 @@ class PartialTagTest < ActiveSupport::TestCase
57
57
  assert_equal "<%= render :partial => 'path/to/partial', :locals => {:param_1 => 'param1', :param_2 => 'param2'} %>", tag.render
58
58
  end
59
59
 
60
+ def test_whitelisted_paths
61
+ ComfortableMexicanSofa.config.allowed_partials = ['safe/path']
62
+
63
+ tag = ComfortableMexicanSofa::Tag::Partial.initialize_tag(
64
+ cms_pages(:default), '{{cms:partial:safe/path}}'
65
+ )
66
+ assert_equal "<%= render :partial => 'safe/path' %>", tag.content
67
+ assert_equal "<%= render :partial => 'safe/path' %>", tag.render
68
+
69
+ tag = ComfortableMexicanSofa::Tag::Partial.initialize_tag(
70
+ cms_pages(:default), '{{cms:partial:unsafe/path}}'
71
+ )
72
+ assert_equal "<%= render :partial => 'unsafe/path' %>", tag.content
73
+ assert_equal nil, tag.render
74
+ end
75
+
60
76
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comfortable_mexican_sofa
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.11
4
+ version: 1.6.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-02-08 00:00:00.000000000Z
13
+ date: 2012-02-21 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
- requirement: &70121486515260 !ruby/object:Gem::Requirement
17
+ requirement: &70366229980420 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 3.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70121486515260
25
+ version_requirements: *70366229980420
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: active_link_to
28
- requirement: &70121486514720 !ruby/object:Gem::Requirement
28
+ requirement: &70366229978160 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 1.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70121486514720
36
+ version_requirements: *70366229978160
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: paperclip
39
- requirement: &70121486514020 !ruby/object:Gem::Requirement
39
+ requirement: &70366229976420 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,7 +44,7 @@ dependencies:
44
44
  version: 2.3.0
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70121486514020
47
+ version_requirements: *70366229976420
48
48
  description: ''
49
49
  email: oleg@theworkinggroup.ca
50
50
  executables: []
@@ -254,6 +254,7 @@ files:
254
254
  - lib/comfortable_mexican_sofa/fixtures.rb
255
255
  - lib/comfortable_mexican_sofa/form_builder.rb
256
256
  - lib/comfortable_mexican_sofa/render_methods.rb
257
+ - lib/comfortable_mexican_sofa/sitemap.rb
257
258
  - lib/comfortable_mexican_sofa/tag.rb
258
259
  - lib/comfortable_mexican_sofa/tags/asset.rb
259
260
  - lib/comfortable_mexican_sofa/tags/collection.rb
@@ -331,6 +332,7 @@ files:
331
332
  - test/unit/models/site_test.rb
332
333
  - test/unit/models/snippet_test.rb
333
334
  - test/unit/revisions_test.rb
335
+ - test/unit/sitemap_test.rb
334
336
  - test/unit/tag_test.rb
335
337
  - test/unit/tags/asset_test.rb
336
338
  - test/unit/tags/collection_test.rb
@@ -364,7 +366,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
364
366
  version: '0'
365
367
  segments:
366
368
  - 0
367
- hash: 1091644248589677740
369
+ hash: -4596160239397252587
368
370
  required_rubygems_version: !ruby/object:Gem::Requirement
369
371
  none: false
370
372
  requirements: