comfortable_mexican_sofa 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/Gemfile +2 -6
  2. data/Gemfile.lock +3 -4
  3. data/VERSION +1 -1
  4. data/app/controllers/cms_admin/base_controller.rb +1 -1
  5. data/app/controllers/cms_admin/layouts_controller.rb +2 -2
  6. data/app/controllers/cms_admin/pages_controller.rb +2 -2
  7. data/app/controllers/cms_admin/revisions_controller.rb +57 -0
  8. data/app/controllers/cms_admin/sites_controller.rb +2 -2
  9. data/app/controllers/cms_admin/snippets_controller.rb +2 -2
  10. data/app/models/cms/layout.rb +2 -0
  11. data/app/models/cms/page.rb +29 -9
  12. data/app/models/cms/revision.rb +13 -0
  13. data/app/models/cms/snippet.rb +2 -5
  14. data/app/views/cms_admin/layouts/_form.html.erb +0 -1
  15. data/app/views/cms_admin/layouts/edit.html.erb +1 -0
  16. data/app/views/cms_admin/pages/_form.html.erb +0 -1
  17. data/app/views/cms_admin/pages/edit.html.erb +1 -0
  18. data/app/views/cms_admin/revisions/show.html.erb +36 -0
  19. data/app/views/cms_admin/sites/_form.html.erb +0 -1
  20. data/app/views/cms_admin/snippets/_form.html.erb +0 -1
  21. data/app/views/cms_admin/snippets/edit.html.erb +1 -0
  22. data/app/views/layouts/cms_admin/_body.html.erb +4 -0
  23. data/app/views/layouts/cms_admin/_left.html.erb +9 -7
  24. data/comfortable_mexican_sofa.gemspec +19 -12
  25. data/config/initializers/comfortable_mexican_sofa.rb +5 -0
  26. data/config/routes.rb +13 -2
  27. data/db/migrate/01_create_cms.rb +11 -0
  28. data/db/migrate/upgrades/03_upgrade_to_1_2_0.rb +15 -0
  29. data/lib/comfortable_mexican_sofa.rb +3 -1
  30. data/lib/comfortable_mexican_sofa/configuration.rb +4 -0
  31. data/lib/comfortable_mexican_sofa/form_builder.rb +0 -1
  32. data/lib/comfortable_mexican_sofa/has_revisions.rb +64 -0
  33. data/lib/comfortable_mexican_sofa/http_auth.rb +1 -0
  34. data/lib/comfortable_mexican_sofa/version.rb +7 -0
  35. data/public/stylesheets/comfortable_mexican_sofa/content.css +42 -0
  36. data/public/stylesheets/comfortable_mexican_sofa/structure.css +31 -6
  37. data/public/stylesheets/comfortable_mexican_sofa/typography.css +8 -0
  38. data/test/fixtures/cms/revisions.yml +21 -0
  39. data/test/functional/cms_admin/layouts_controller_test.rb +2 -31
  40. data/test/functional/cms_admin/pages_controller_test.rb +7 -48
  41. data/test/functional/cms_admin/revisions_controller_test.rb +135 -0
  42. data/test/functional/cms_admin/sites_controller_test.rb +4 -29
  43. data/test/functional/cms_admin/snippets_controller_test.rb +2 -31
  44. data/test/test_helper.rb +1 -0
  45. data/test/unit/configuration_test.rb +5 -0
  46. data/test/unit/models/page_test.rb +0 -1
  47. data/test/unit/models/snippet_test.rb +0 -5
  48. data/test/unit/revisions_test.rb +185 -0
  49. metadata +18 -19
  50. data/config/initializers/mime_types.rb +0 -5
@@ -47,6 +47,11 @@ ComfortableMexicanSofa.configure do |config|
47
47
  # Path where fixtures can be located.
48
48
  # config.fixtures_path = File.expand_path('db/cms_fixtures', Rails.root)
49
49
 
50
+ # Content for Layouts, Pages and Snippets has a revision history. You can revert
51
+ # a previous version using this system. You can control how many revisions per
52
+ # object you want to keep. Set it to 0 if you wish to turn this feature off.
53
+ # config.revisions_limit = 25
54
+
50
55
  end
51
56
 
52
57
  # Default credentials for ComfortableMexicanSofa::HttpAuth
data/config/routes.rb CHANGED
@@ -10,11 +10,22 @@ Rails.application.routes.draw do
10
10
  collection do
11
11
  match :reorder
12
12
  end
13
+ resources :revisions, :only => [:index, :show, :revert] do
14
+ put :revert, :on => :member
15
+ end
13
16
  end
14
17
  resources :sites
15
- resources :layouts
16
- resources :snippets
17
18
  resources :uploads, :only => [:create, :destroy]
19
+ resources :layouts do
20
+ resources :revisions, :only => [:index, :show, :revert] do
21
+ put :revert, :on => :member
22
+ end
23
+ end
24
+ resources :snippets do
25
+ resources :revisions, :only => [:index, :show, :revert] do
26
+ put :revert, :on => :member
27
+ end
28
+ end
18
29
  end
19
30
 
20
31
  scope :controller => :cms_content do
@@ -70,6 +70,16 @@ class CreateCms < ActiveRecord::Migration
70
70
  t.timestamps
71
71
  end
72
72
  add_index :cms_uploads, [:site_id, :file_file_name]
73
+
74
+ # -- Revisions -----------------------------------------------------------
75
+ create_table :cms_revisions, :force => true do |t|
76
+ t.string :record_type
77
+ t.integer :record_id
78
+ t.text :data
79
+ t.datetime :created_at
80
+ end
81
+ add_index :cms_revisions, [:record_type, :record_id, :created_at]
82
+
73
83
  end
74
84
 
75
85
  def self.down
@@ -79,5 +89,6 @@ class CreateCms < ActiveRecord::Migration
79
89
  drop_table :cms_snippets
80
90
  drop_table :cms_blocks
81
91
  drop_table :cms_uploads
92
+ drop_table :cms_revisions
82
93
  end
83
94
  end
@@ -0,0 +1,15 @@
1
+ class UpgradeTo120 < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :cms_revisions, :force => true do |t|
4
+ t.string :record_type
5
+ t.integer :record_id
6
+ t.text :data
7
+ t.datetime :created_at
8
+ end
9
+ add_index :cms_revisions, [:record_type, :record_id, :created_at]
10
+ end
11
+
12
+ def self.down
13
+ drop_table :cms_revisions
14
+ end
15
+ end
@@ -3,7 +3,8 @@ unless defined? ComfortableMexicanSofa::Application
3
3
  require File.expand_path('comfortable_mexican_sofa/engine', File.dirname(__FILE__))
4
4
  end
5
5
 
6
- [ 'comfortable_mexican_sofa/configuration',
6
+ [ 'comfortable_mexican_sofa/version',
7
+ 'comfortable_mexican_sofa/configuration',
7
8
  'comfortable_mexican_sofa/http_auth',
8
9
  'comfortable_mexican_sofa/rails_extensions',
9
10
  'comfortable_mexican_sofa/controller_methods',
@@ -11,6 +12,7 @@ end
11
12
  'comfortable_mexican_sofa/view_methods',
12
13
  'comfortable_mexican_sofa/form_builder',
13
14
  'comfortable_mexican_sofa/acts_as_tree',
15
+ 'comfortable_mexican_sofa/has_revisions',
14
16
  'comfortable_mexican_sofa/tag',
15
17
  'comfortable_mexican_sofa/fixtures'
16
18
  ].each do |path|
@@ -37,6 +37,9 @@ class ComfortableMexicanSofa::Configuration
37
37
  # Path where fixtures can be located.
38
38
  attr_accessor :fixtures_path
39
39
 
40
+ # Number of revisions kept. Default is 25. If you wish to disable: set this to 0.
41
+ attr_accessor :revisions_limit
42
+
40
43
  # Configuration defaults
41
44
  def initialize
42
45
  @cms_title = 'ComfortableMexicanSofa MicroCMS'
@@ -51,6 +54,7 @@ class ComfortableMexicanSofa::Configuration
51
54
  @upload_file_options = {}
52
55
  @enable_fixtures = false
53
56
  @fixtures_path = File.expand_path('db/cms_fixtures', Rails.root)
57
+ @revisions_limit = 25
54
58
  end
55
59
 
56
60
  end
@@ -76,7 +76,6 @@ class ComfortableMexicanSofa::FormBuilder < ActionView::Helpers::FormBuilder
76
76
  <div class='value'>
77
77
  #{field}
78
78
  #{@template.hidden_field_tag('cms_page[blocks_attributes][][label]', tag.label, :id => nil)}
79
- #{@template.hidden_field_tag('cms_page[blocks_attributes][][id]', tag.record_id, :id => nil) if tag.record_id}
80
79
  </div>
81
80
  </div>
82
81
  ).html_safe
@@ -0,0 +1,64 @@
1
+ module ComfortableMexicanSofa::HasRevisions
2
+
3
+ def self.included(base)
4
+ base.send :extend, ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+
9
+ def has_revisions_for(*fields)
10
+
11
+ include ComfortableMexicanSofa::HasRevisions::InstanceMethods
12
+
13
+ attr_accessor :revision_data
14
+
15
+ has_many :revisions,
16
+ :as => :record,
17
+ :dependent => :destroy
18
+
19
+ before_save :prepare_revision
20
+ after_save :create_revision
21
+
22
+ define_method(:revision_fields) do
23
+ fields.collect(&:to_s)
24
+ end
25
+ end
26
+ end
27
+
28
+ module InstanceMethods
29
+
30
+ # Preparing revision data. A bit of a special thing to grab page blocks
31
+ def prepare_revision
32
+ return if self.new_record?
33
+ if (self.respond_to?(:blocks_attributes_changed) && self.blocks_attributes_changed) ||
34
+ !(self.changed & revision_fields).empty?
35
+ self.revision_data = revision_fields.inject({}) do |c, field|
36
+ c[field] = self.send("#{field}_was")
37
+ c
38
+ end
39
+ end
40
+ end
41
+
42
+ # Revision is created only if relevant data changed
43
+ def create_revision
44
+ return unless self.revision_data
45
+
46
+ # creating revision
47
+ if ComfortableMexicanSofa.config.revisions_limit.to_i != 0
48
+ self.revisions.create!(:data => self.revision_data)
49
+ end
50
+
51
+ # blowing away old revisions
52
+ ids = [0] + self.revisions.limit(ComfortableMexicanSofa.config.revisions_limit.to_i).collect(&:id)
53
+ self.revisions.where('id NOT IN (?)', ids).destroy_all
54
+ end
55
+
56
+ # Assigning whatever is found in revision data and attemptint to save the object
57
+ def restore_from_revision(revision)
58
+ return unless revision.record == self
59
+ self.update_attributes!(revision.data)
60
+ end
61
+ end
62
+ end
63
+
64
+ ActiveRecord::Base.send :include, ComfortableMexicanSofa::HasRevisions
@@ -14,4 +14,5 @@ module ComfortableMexicanSofa::HttpAuth
14
14
  username == self.username && password == self.password
15
15
  end
16
16
  end
17
+
17
18
  end
@@ -0,0 +1,7 @@
1
+ module ComfortableMexicanSofa
2
+ VERSION = begin
3
+ IO.read(File.join(File.dirname(__FILE__), '/../../VERSION')).chomp
4
+ rescue
5
+ 'UNKNOWN'
6
+ end
7
+ end
@@ -182,4 +182,46 @@ form.search {
182
182
  }
183
183
  .c_cms_admin_snippets.a_index ul.list li .item .icon {
184
184
  background-image: url(/images/comfortable_mexican_sofa/icon_snippet.gif);
185
+ }
186
+
187
+ /* -- Revisions ---------------------------------------------------------- */
188
+ .c_cms_admin_revisions.a_show .form_element.submit_element .value {
189
+ margin-left: 0px;
190
+ }
191
+ .c_cms_admin_revisions.a_show .current {
192
+ width: 50%;
193
+ float: left;
194
+ }
195
+ .c_cms_admin_revisions.a_show .versioned {
196
+ width: 50%;
197
+ float: right;
198
+ }
199
+ .c_cms_admin_revisions.a_show .title,
200
+ .c_cms_admin_revisions.a_show .content {
201
+ padding: 2px 5px;
202
+ margin: 0px 3px;
203
+ }
204
+ .c_cms_admin_revisions.a_show .title {
205
+ background: #f1f1f1;
206
+ border-bottom: 2px solid #bbb;
207
+ }
208
+ .c_cms_admin_revisions.a_show .content {
209
+ min-height: 16px;
210
+ border: 1px dashed #f1f1f1;
211
+ }
212
+ .c_cms_admin_revisions.a_show .revisions a {
213
+ display: block;
214
+ background-color: #252525;
215
+ border-radius: 2px;
216
+ padding: 0px 3px;
217
+ opacity: 0.5;
218
+ margin-bottom: 2px;
219
+ color: #fff;
220
+ }
221
+ .c_cms_admin_revisions.a_show .revisions a:hover,
222
+ .c_cms_admin_revisions.a_show .revisions a.active {
223
+ opacity: 1;
224
+ }
225
+ .c_cms_admin_revisions.a_show .revisions a:last-child {
226
+ margin-bottom: 0px;
185
227
  }
@@ -11,14 +11,14 @@ html, body {
11
11
  float: left;
12
12
  }
13
13
  .center_column {
14
+ position: relative;
14
15
  margin: 0px 250px 0px 175px;
15
16
  min-height: 100%;
16
- overflow: hidden;
17
17
  background-color: #D8D8D8;
18
18
  border-left: 1px solid #484848;
19
19
  border-right: 1px solid #484848;
20
20
  }
21
- .center_column_content {
21
+ .center_column .center_column_content {
22
22
  padding: 25px;
23
23
  }
24
24
  .right_column {
@@ -35,7 +35,7 @@ html, body {
35
35
  width: 165px;
36
36
  position: fixed;
37
37
  }
38
- .left_column_content a {
38
+ .left_column_content ul.nav a {
39
39
  display: block;
40
40
  padding: 3px 10px;
41
41
  margin-bottom: 5px;
@@ -50,12 +50,16 @@ html, body {
50
50
  color: #fff;
51
51
  opacity: 0.3;
52
52
  }
53
- .left_column_content a:hover,
54
- .left_column_content a.active {
53
+ .left_column_content ul.nav a:hover,
54
+ .left_column_content ul.nav a.active {
55
55
  color: #fff;
56
56
  opacity: 1;
57
57
  }
58
-
58
+ .right_column_content h2 {
59
+ color: #d8d8d8;
60
+ text-shadow: #000 1px 1px;
61
+ margin-bottom: 5px;
62
+ }
59
63
  .right_column_content .box {
60
64
  background-color: #484848;
61
65
  padding: 5px;
@@ -125,4 +129,25 @@ input[type='file'] {
125
129
  }
126
130
  a.button.big {
127
131
  float: right;
132
+ }
133
+
134
+ .center_column .sofa {
135
+ position: absolute;
136
+ background: #000;
137
+ bottom: 0px;
138
+ left: -175px;
139
+ width: 155px;
140
+ padding: 5px 10px;
141
+ font-size: 10px;
142
+ }
143
+ .center_column .sofa a {
144
+ color: #484848;
145
+ }
146
+ .center_column .sofa a:hover {
147
+ color: #f1f1f1;
148
+ }
149
+ .center_column .sofa span.version {
150
+ color: #f1f1f1;
151
+ font-size: 9px;
152
+ margin-left: 2px;
128
153
  }
@@ -10,6 +10,14 @@ h1 {
10
10
  text-shadow: #fff 1px 1px;
11
11
  border-bottom: 2px solid #9f9f9f;
12
12
  }
13
+ h2 {
14
+ font: bold 16px/16px 'Lucida Grande', 'Tahoma', serif;
15
+ text-shadow: #fff 1px 1px;
16
+ margin-bottom: 15px;
17
+ }
18
+ h1 + h2 {
19
+ margin-top: -15px;
20
+ }
13
21
  a {
14
22
  text-decoration: none;
15
23
  color: #384E66;
@@ -0,0 +1,21 @@
1
+ layout:
2
+ record: default (Cms::Layout)
3
+ data: <%= {
4
+ 'content' => 'revision {{cms:page:default_page_text}}',
5
+ 'css' => 'revision css',
6
+ 'js' => 'revision js' }.to_yaml.inspect %>
7
+
8
+ page:
9
+ record: default (Cms::Page)
10
+ data: <%= {
11
+ 'blocks_attributes' => [
12
+ { 'label' => 'default_page_text',
13
+ 'content' => 'revision page content' },
14
+ { 'label' => 'default_field_text',
15
+ 'content' => 'revision field content'}
16
+ ]}.to_yaml.inspect %>
17
+
18
+ snippet:
19
+ record: default (Cms::Snippet)
20
+ data: <%= {
21
+ 'content' => 'revision content' }.to_yaml.inspect %>
@@ -41,7 +41,7 @@ class CmsAdmin::LayoutsControllerTest < ActionController::TestCase
41
41
  assert_equal 'Layout not found', flash[:error]
42
42
  end
43
43
 
44
- def test_creation_with_commit
44
+ def test_creation
45
45
  assert_difference 'Cms::Layout.count' do
46
46
  post :create, :cms_layout => {
47
47
  :label => 'Test Layout',
@@ -51,21 +51,6 @@ class CmsAdmin::LayoutsControllerTest < ActionController::TestCase
51
51
  assert_response :redirect
52
52
  layout = Cms::Layout.last
53
53
  assert_equal cms_sites(:default), layout.site
54
- assert_redirected_to :action => :index
55
- assert_equal 'Layout created', flash[:notice]
56
- end
57
- end
58
-
59
- def test_creation_without_commit
60
- assert_difference 'Cms::Layout.count' do
61
- post :create, :cms_layout => {
62
- :label => 'Test Layout',
63
- :slug => 'test',
64
- :content => 'Test {{cms:page:content}}'
65
- }
66
- assert_response :redirect
67
- layout = Cms::Layout.last
68
- assert_equal cms_sites(:default), layout.site
69
54
  assert_redirected_to :action => :edit, :id => layout
70
55
  assert_equal 'Layout created', flash[:notice]
71
56
  end
@@ -80,21 +65,7 @@ class CmsAdmin::LayoutsControllerTest < ActionController::TestCase
80
65
  end
81
66
  end
82
67
 
83
- def test_update_with_commit
84
- layout = cms_layouts(:default)
85
- put :update, :id => layout, :cms_layout => {
86
- :label => 'New Label',
87
- :content => 'New {{cms:page:content}}'
88
- }, :commit => 'Update Layout'
89
- assert_response :redirect
90
- assert_redirected_to :action => :index
91
- assert_equal 'Layout updated', flash[:notice]
92
- layout.reload
93
- assert_equal 'New Label', layout.label
94
- assert_equal 'New {{cms:page:content}}', layout.content
95
- end
96
-
97
- def test_update_without_commit
68
+ def test_update
98
69
  layout = cms_layouts(:default)
99
70
  put :update, :id => layout, :cms_layout => {
100
71
  :label => 'New Label',
@@ -103,8 +103,6 @@ class CmsAdmin::PagesControllerTest < ActionController::TestCase
103
103
  assert assigns(:cms_page)
104
104
  assert_template :edit
105
105
  assert_select "form[action=/cms-admin/pages/#{page.id}]"
106
- assert_select "input[name='cms_page[blocks_attributes][][id]'][value='#{cms_blocks(:default_field_text).id}']"
107
- assert_select "input[name='cms_page[blocks_attributes][][id]'][value='#{cms_blocks(:default_field_text).id}']"
108
106
  end
109
107
 
110
108
  def test_get_edit_failure
@@ -123,7 +121,7 @@ class CmsAdmin::PagesControllerTest < ActionController::TestCase
123
121
  assert assigns(:cms_page).layout
124
122
  end
125
123
 
126
- def test_creation_with_commit
124
+ def test_creation
127
125
  assert_difference 'Cms::Page.count' do
128
126
  assert_difference 'Cms::Block.count', 2 do
129
127
  post :create, :cms_page => {
@@ -141,36 +139,12 @@ class CmsAdmin::PagesControllerTest < ActionController::TestCase
141
139
  assert_response :redirect
142
140
  page = Cms::Page.last
143
141
  assert_equal cms_sites(:default), page.site
144
- assert_redirected_to :action => :index
145
- assert_equal 'Page saved', flash[:notice]
146
- end
147
- end
148
- end
149
-
150
- def test_creation_without_commit
151
- assert_difference 'Cms::Page.count' do
152
- assert_difference 'Cms::Block.count', 2 do
153
- post :create, :cms_page => {
154
- :label => 'Test Page',
155
- :slug => 'test-page',
156
- :parent_id => cms_pages(:default).id,
157
- :layout_id => cms_layouts(:default).id,
158
- :blocks_attributes => [
159
- { :label => 'default_page_text',
160
- :content => 'content content' },
161
- { :label => 'default_field_text',
162
- :content => 'title content' }
163
- ]
164
- }
165
- assert_response :redirect
166
- page = Cms::Page.last
167
- assert_equal cms_sites(:default), page.site
168
142
  assert_redirected_to :action => :edit, :id => page
169
143
  assert_equal 'Page saved', flash[:notice]
170
144
  end
171
145
  end
172
146
  end
173
-
147
+
174
148
  def test_creation_failure
175
149
  assert_no_difference ['Cms::Page.count', 'Cms::Block.count'] do
176
150
  post :create, :cms_page => {
@@ -191,21 +165,7 @@ class CmsAdmin::PagesControllerTest < ActionController::TestCase
191
165
  end
192
166
  end
193
167
 
194
- def test_update_with_commit
195
- page = cms_pages(:default)
196
- assert_no_difference 'Cms::Block.count' do
197
- put :update, :id => page, :cms_page => {
198
- :label => 'Updated Label'
199
- }, :commit => 'Update Page'
200
- page.reload
201
- assert_response :redirect
202
- assert_redirected_to :action => :index
203
- assert_equal 'Page updated', flash[:notice]
204
- assert_equal 'Updated Label', page.label
205
- end
206
- end
207
-
208
- def test_update_without_commit
168
+ def test_update
209
169
  page = cms_pages(:default)
210
170
  assert_no_difference 'Cms::Block.count' do
211
171
  put :update, :id => page, :cms_page => {
@@ -218,17 +178,16 @@ class CmsAdmin::PagesControllerTest < ActionController::TestCase
218
178
  assert_equal 'Updated Label', page.label
219
179
  end
220
180
  end
221
-
181
+
222
182
  def test_update_with_layout_change
223
183
  page = cms_pages(:default)
224
- assert_difference 'Cms::Block.count', 1 do
184
+ assert_difference 'Cms::Block.count', 2 do
225
185
  put :update, :id => page, :cms_page => {
226
186
  :label => 'Updated Label',
227
187
  :layout_id => cms_layouts(:nested).id,
228
188
  :blocks_attributes => [
229
189
  { :label => 'content',
230
- :content => 'new_page_text_content',
231
- :id => cms_blocks(:default_page_text).id },
190
+ :content => 'new_page_text_content' },
232
191
  { :label => 'header',
233
192
  :content => 'new_page_string_content' }
234
193
  ]
@@ -238,7 +197,7 @@ class CmsAdmin::PagesControllerTest < ActionController::TestCase
238
197
  assert_redirected_to :action => :edit, :id => page
239
198
  assert_equal 'Page updated', flash[:notice]
240
199
  assert_equal 'Updated Label', page.label
241
- assert_equal ['new_page_text_content', 'default_field_text_content', 'new_page_string_content'], page.blocks.collect{|b| b.content}
200
+ assert_equal ['content', 'default_field_text', 'default_page_text', 'header'], page.blocks.collect{|b| b.label}
242
201
  end
243
202
  end
244
203