webficient-browsercms 3.0.1 → 3.0.2

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 (34) hide show
  1. data/app/controllers/cms/content_block_controller.rb +25 -2
  2. data/app/controllers/cms/content_controller.rb +2 -1
  3. data/app/controllers/cms/dashboard_controller.rb +2 -1
  4. data/app/controllers/cms/error_handling.rb +3 -3
  5. data/app/controllers/cms/sections_controller.rb +5 -2
  6. data/app/models/attachment.rb +9 -1
  7. data/app/models/content_type.rb +2 -2
  8. data/app/models/link.rb +2 -2
  9. data/app/models/page.rb +10 -0
  10. data/app/models/user.rb +34 -16
  11. data/app/views/cms/blocks/_toolbar_for_member.html.erb +3 -3
  12. data/app/views/cms/blocks/index.html.erb +10 -6
  13. data/app/views/cms/content/show.html.erb +0 -1
  14. data/app/views/cms/dashboard/_recently_updated.html.erb +50 -0
  15. data/app/views/cms/dashboard/index.html.erb +9 -1
  16. data/app/views/cms/sections/_form.html.erb +36 -34
  17. data/app/views/layouts/_page_toolbar.html.erb +5 -5
  18. data/browsercms.gemspec +1289 -1283
  19. data/lib/cms/acts/content_block.rb +1 -1
  20. data/lib/cms/behaviors/publishing.rb +11 -1
  21. data/lib/cms/behaviors/versioning.rb +8 -2
  22. data/lib/cms/routes.rb +8 -1
  23. data/lib/tasks/db.rake +1 -1
  24. data/public/stylesheets/cms/dashboard.css +18 -1
  25. data/test/functional/cms/content_block_controller_test.rb +120 -0
  26. data/test/functional/cms/content_controller_test.rb +10 -1
  27. data/test/functional/cms/links_controller_test.rb +5 -0
  28. data/test/functional/cms/pages_controller_test.rb +8 -0
  29. data/test/functional/cms/sections_controller_test.rb +29 -3
  30. data/test/unit/lib/routes_test.rb +57 -0
  31. data/test/unit/models/content_type_test.rb +22 -1
  32. data/test/unit/models/page_test.rb +19 -2
  33. data/test/unit/models/user_test.rb +114 -40
  34. metadata +8 -5
@@ -33,6 +33,7 @@ class Cms::ContentBlockController < Cms::BaseController
33
33
  after_create_on_failure
34
34
  end
35
35
  rescue Exception => @exception
36
+ raise @exception if @exception.is_a?(Cms::Errors::AccessDenied)
36
37
  after_create_on_error
37
38
  end
38
39
 
@@ -50,6 +51,7 @@ class Cms::ContentBlockController < Cms::BaseController
50
51
  rescue ActiveRecord::StaleObjectError => @exception
51
52
  after_update_on_edit_conflict
52
53
  rescue Exception => @exception
54
+ raise @exception if @exception.is_a?(Cms::Errors::AccessDenied)
53
55
  after_update_on_error
54
56
  end
55
57
 
@@ -127,15 +129,18 @@ class Cms::ContentBlockController < Cms::BaseController
127
129
  options[:order] = params[:order] unless params[:order].blank?
128
130
  scope = model_class.respond_to?(:list) ? model_class.list : model_class
129
131
  @blocks = scope.searchable? ? scope.search(params[:search]).paginate(options) : scope.paginate(options)
132
+ check_permissions
130
133
  end
131
134
 
132
135
  def load_block
133
136
  @block = model_class.find(params[:id])
137
+ check_permissions
134
138
  end
135
139
 
136
140
  def load_block_draft
137
- load_block
141
+ @block = model_class.find(params[:id])
138
142
  @block = @block.as_of_draft_version if model_class.versioned?
143
+ check_permissions
139
144
  end
140
145
 
141
146
  # path related methods - available in the view as helpers
@@ -162,6 +167,7 @@ class Cms::ContentBlockController < Cms::BaseController
162
167
 
163
168
  def build_block
164
169
  @block = model_class.new(params[model_name])
170
+ check_permissions
165
171
  end
166
172
 
167
173
  def set_default_category
@@ -244,6 +250,23 @@ class Cms::ContentBlockController < Cms::BaseController
244
250
  false
245
251
  end
246
252
  end
253
+
254
+ # Use a "whitelist" approach to access to avoid mistakes
255
+ # By default everyone can create new block and view them and their properties,
256
+ # but blocks can only be modified based on the permissions of the pages they
257
+ # are connected to.
258
+ def check_permissions
259
+ case action_name
260
+ when "index", "show", "new", "create", "version", "versions", "usages"
261
+ # Allow
262
+ when "edit", "update"
263
+ raise Cms::Errors::AccessDenied unless current_user.able_to_edit?(@block)
264
+ when "destroy", "publish", "revert_to"
265
+ raise Cms::Errors::AccessDenied unless current_user.able_to_publish?(@block)
266
+ else
267
+ raise Cms::Errors::AccessDenied
268
+ end
269
+ end
247
270
 
248
271
  # methods to setup the view
249
272
 
@@ -259,4 +282,4 @@ class Cms::ContentBlockController < Cms::BaseController
259
282
  "cms/blocks"
260
283
  end
261
284
 
262
- end
285
+ end
@@ -173,7 +173,8 @@ class Cms::ContentController < Cms::ApplicationController
173
173
  send_file(@file,
174
174
  :filename => @attachment.file_name,
175
175
  :type => @attachment.file_type,
176
- :disposition => "inline"
176
+ :disposition => "inline",
177
+ :x_sendfile => Attachment.use_x_sendfile
177
178
  )
178
179
  end
179
180
  end
@@ -5,5 +5,6 @@ class Cms::DashboardController < Cms::BaseController
5
5
  @incomplete_tasks = current_user.tasks.incomplete.all(
6
6
  :include => :page,
7
7
  :order => "tasks.due_date desc, pages.name")
8
+ @recent_updates = Page::Version.recent_updates
8
9
  end
9
- end
10
+ end
@@ -2,8 +2,8 @@ module Cms
2
2
  module ErrorHandling
3
3
  def self.included(controller)
4
4
  controller.class_eval do
5
- rescue_from Exception, :with => :handle_server_error
6
- rescue_from Cms::Errors::AccessDenied, :with => :handle_access_denied
5
+ rescue_from Exception, :with => :handle_server_error unless RAILS_ENV == "test"
6
+ rescue_from Cms::Errors::AccessDenied, :with => :handle_access_denied
7
7
  end
8
8
  end
9
9
 
@@ -18,7 +18,7 @@ module Cms
18
18
  def handle_access_denied(exception)
19
19
  render :layout => 'cms/application',
20
20
  :template => 'cms/shared/access_denied',
21
- :status => 403
21
+ :status => 403
22
22
  end
23
23
  end
24
24
  end
@@ -17,11 +17,12 @@ class Cms::SectionsController < Cms::BaseController
17
17
 
18
18
  def new
19
19
  @section = @parent.sections.build
20
- @section.groups = public_groups + cms_groups
20
+ @section.groups = @parent.groups
21
21
  end
22
22
 
23
23
  def create
24
24
  @section = Section.new(params[:section])
25
+ @section.groups = @parent.groups unless current_user.able_to?(:administrate)
25
26
  @section.parent = @parent
26
27
  if @section.save
27
28
  flash[:notice] = "Section '#{@section.name}' was created"
@@ -35,7 +36,9 @@ class Cms::SectionsController < Cms::BaseController
35
36
  end
36
37
 
37
38
  def update
38
- if @section.update_attributes(params[:section])
39
+ @section.attributes = params[:section]
40
+ @section.groups = @section.parent.groups unless current_user.able_to?(:administrate)
41
+ if @section.save
39
42
  flash[:notice] = "Section '#{@section.name}' was updated"
40
43
  redirect_to [:cms, @section]
41
44
  else
@@ -147,6 +147,14 @@ class Attachment < ActiveRecord::Base
147
147
  Attachment.published.not_archived.first(:conditions => {:file_path => file_path})
148
148
  end
149
149
 
150
+ def self.use_x_sendfile
151
+ @use_x_sendfile ||= false
152
+ end
153
+
154
+ def self.use_x_sendfile=(use_x_sendfile)
155
+ @use_x_sendfile = use_x_sendfile
156
+ end
157
+
150
158
  #----- Instance Methods ------------------------------------------------------
151
159
 
152
160
  def file_name
@@ -190,4 +198,4 @@ class Attachment < ActiveRecord::Base
190
198
  self.updated_at = Time.now
191
199
  end
192
200
 
193
- end
201
+ end
@@ -19,7 +19,7 @@ class ContentType < ActiveRecord::Base
19
19
  # Given a 'key' like 'html_blocks' or 'portlet'
20
20
  # Raises exception if nothing was found.
21
21
  def self.find_by_key(key)
22
- class_name = key.classify
22
+ class_name = key.tableize.classify
23
23
  content_type = find_by_name(class_name)
24
24
  if content_type.nil?
25
25
  if class_name.constantize.ancestors.include?(Portlet)
@@ -54,7 +54,7 @@ class ContentType < ActiveRecord::Base
54
54
  end
55
55
 
56
56
  def model_class
57
- name.classify.constantize
57
+ name.tableize.classify.constantize
58
58
  end
59
59
 
60
60
  # Allows models to show additional columns when being shown in a list.
data/app/models/link.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class Link < ActiveRecord::Base
2
- acts_as_content_block
2
+ acts_as_content_block :connectable => false
3
3
 
4
4
  named_scope :named, lambda{|name| {:conditions => ['links.name = ?', name]}}
5
5
 
@@ -32,4 +32,4 @@ class Link < ActiveRecord::Base
32
32
  url
33
33
  end
34
34
 
35
- end
35
+ end
data/app/models/page.rb CHANGED
@@ -48,6 +48,7 @@ class Page < ActiveRecord::Base
48
48
 
49
49
  before_validation :append_leading_slash_to_path
50
50
  before_destroy :delete_connectors
51
+ before_destroy :delete_section_node
51
52
 
52
53
  validates_presence_of :name, :path
53
54
  validates_uniqueness_of :path
@@ -194,6 +195,10 @@ class Page < ActiveRecord::Base
194
195
  end
195
196
  end
196
197
 
198
+ def delete_section_node
199
+ section_node.destroy if section_node
200
+ end
201
+
197
202
  def public?
198
203
  section ? section.public? : false
199
204
  end
@@ -262,6 +267,11 @@ class Page < ActiveRecord::Base
262
267
  (a[1..a.size].map{|a| a.name} + [name]).join(" / ")
263
268
  end
264
269
 
270
+ # returns current page name, lowercase, with spaces replaced by underscores
271
+ def internal_name
272
+ name.downcase.gsub(/ /, '_')
273
+ end
274
+
265
275
  # This will return the "top level section" for a page, which is the section directly
266
276
  # below the root (a.k.a My Site) that this page is in. If this page is in root,
267
277
  # then this will return root.
data/app/models/user.rb CHANGED
@@ -89,12 +89,12 @@ class User < ActiveRecord::Base
89
89
  @viewable_sections ||= Section.find(:all, :include => {:groups => :users}, :conditions => ["users.id = ?", id])
90
90
  end
91
91
 
92
- def editable_sections
93
- @editable_sections ||= Section.find(:all, :include => {:groups => [:group_type, :users]}, :conditions => ["users.id = ? and group_types.cms_access = ?", id, true])
92
+ def modifiable_sections
93
+ @modifiable_sections ||= Section.find(:all, :include => {:groups => [:group_type, :users]}, :conditions => ["users.id = ? and group_types.cms_access = ?", id, true])
94
94
  end
95
95
 
96
- #Expects a list of names of Permissions
97
- #true if the user has any of the permissions
96
+ # Expects a list of names of Permissions
97
+ # true if the user has any of the permissions
98
98
  def able_to?(*required_permissions)
99
99
  perms = required_permissions.map(&:to_sym)
100
100
  permissions.any? do |p|
@@ -102,25 +102,43 @@ class User < ActiveRecord::Base
102
102
  end
103
103
  end
104
104
 
105
- #Expects object to be an object or a section
106
- #If it's a section, that will be used
107
- #If it's not a section, it will call section on the object
108
- #returns true if any of the sections of the groups the user is in matches the page's section.
105
+ # Expects object to be an object or a section
106
+ # If it's a section, that will be used
107
+ # If it's not a section, it will call section on the object
108
+ # returns true if any of the sections of the groups the user is in matches the page's section.
109
109
  def able_to_view?(object)
110
110
  section = object.is_a?(Section) ? object : object.section
111
- !!(viewable_sections.include?(section) || groups.cms_access.count > 0)
111
+ viewable_sections.include?(section) || groups.cms_access.count > 0
112
112
  end
113
113
 
114
- #Expects node to be a Section, Page or Link
115
- #Returns true if the specified node, or any of its ancestor sections, is editable by any of
116
- #the user's 'CMS User' groups.
117
- def able_to_edit?(node)
118
- section = node.is_a?(Section) ? node : node.section
119
- !!(able_to?(:edit_content) && section.with_ancestors.any? { |section| editable_sections.include?(section) })
114
+ def able_to_modify?(object)
115
+ case object
116
+ when Section
117
+ object.with_ancestors.any? { |section| modifiable_sections.include?(section) }
118
+ when Page, Link
119
+ object.section.with_ancestors.any? { |section| modifiable_sections.include?(section) }
120
+ else
121
+ if object.class.respond_to?(:connectable?) && object.class.connectable?
122
+ object.connected_pages.all? { |page| able_to_modify?(page) }
123
+ else
124
+ true
125
+ end
126
+ end
127
+ end
128
+
129
+ # Expects node to be a Section, Page or Link
130
+ # Returns true if the specified node, or any of its ancestor sections, is editable by any of
131
+ # the user's 'CMS User' groups.
132
+ def able_to_edit?(object)
133
+ able_to?(:edit_content) && able_to_modify?(object)
134
+ end
135
+
136
+ def able_to_publish?(object)
137
+ able_to?(:publish_content) && able_to_modify?(object)
120
138
  end
121
139
 
122
140
  def able_to_edit_or_publish_content?
123
141
  able_to?(:edit_content, :publish_content)
124
142
  end
125
143
 
126
- end
144
+ end
@@ -1,7 +1,7 @@
1
1
  <% able_to? :publish_content do -%>
2
2
  <% if @block.respond_to?(:live?) && !@block.live? %>
3
3
  <%= link_to span_tag('Publish'), block_path(:publish),
4
- :class => "http_put button left",
4
+ :class => "http_put button left#{' disabled' unless current_user.able_to_publish?(@block)}",
5
5
  :id => "publish_button" %>
6
6
  <% else %>
7
7
  <%= link_to span_tag('Publish'), "#",
@@ -15,7 +15,7 @@
15
15
  :id => "view_button" %>
16
16
 
17
17
  <%= link_to span_tag('Edit Content'), block_path(:edit),
18
- :class => "button right#{ ' off' if action_name == 'edit'}",
18
+ :class => "button right#{ ' off' if action_name == 'edit'}#{' disabled' unless current_user.able_to_edit?(@block)}",
19
19
  :id => "edit_button" %>
20
20
 
21
21
  <%= link_to span_tag("Add New Content"), new_block_path,
@@ -33,6 +33,6 @@
33
33
  <% end %>
34
34
 
35
35
  <%= link_to span_tag("<span class=\"delete_img\">&nbsp;</span>Delete"), block_path,
36
- :class => "http_delete confirm_with_title button",
36
+ :class => "http_delete confirm_with_title button#{' disabled' unless current_user.able_to_publish?(@block)}",
37
37
  :title => "Are you sure you want to delete '#{@block.name}'?",
38
38
  :id => "delete_button" %>
@@ -11,12 +11,14 @@
11
11
  var match = this.id.match(/(.*)_(\d+)/)
12
12
  var type = match[1]
13
13
  var id = match[2]
14
+ var editable = !$(this).hasClass("non-editable")
15
+ var publishable = !$(this).hasClass("non-publishable")
14
16
  $('table.data tbody tr').removeClass('selected')
15
17
  $(this).addClass('selected')
16
18
  $('#functions .button').addClass('disabled').attr('href','#')
17
19
  $('#add_button').removeClass('disabled').attr('href', '/cms/'+collectionName+'/new')
18
20
  $('#view_button').removeClass('disabled').attr('href', '/cms/'+collectionName+'/'+id)
19
- $('#edit_button').removeClass('disabled').attr('href', '/cms/'+collectionName+'/'+id+'/edit')
21
+ if (editable) $('#edit_button').removeClass('disabled').attr('href', '/cms/'+collectionName+'/'+id+'/edit')
20
22
  <% if content_type.model_class.versioned? %>
21
23
  $('#revisions_button').removeClass('disabled').attr('href', '/cms/'+collectionName+'/'+id+'/versions')
22
24
  <% else %>
@@ -28,12 +30,14 @@
28
30
  $('#delete_button').addClass('disabled')
29
31
  .attr('title', $.trim(cannot_be_deleted_message.text()))
30
32
  } else {
31
- $('#delete_button').removeClass('disabled')
32
- .attr('href', '/cms/'+collectionName+'/'+id)
33
- .attr('title', 'Are You Sure You Want To Delete This Record?')
33
+ if (publishable) {
34
+ $('#delete_button').removeClass('disabled')
35
+ .attr('href', '/cms/'+collectionName+'/'+id)
36
+ .attr('title', 'Are You Sure You Want To Delete This Record?')
37
+ }
34
38
  }
35
39
  <% able_to? :publish_content do -%>
36
- if($(this).hasClass('draft')) {
40
+ if($(this).hasClass('draft') && publishable) {
37
41
  $('#publish_button').removeClass('disabled').attr('href', '/cms/'+collectionName+'/'+id+'/publish?_redirect_to='+location.href)
38
42
  }
39
43
  <% end %>
@@ -85,7 +89,7 @@
85
89
  col_ct += 1 if content_type.model_class.publishable? %>
86
90
  <% @blocks.each do |b| %>
87
91
  <% block = b.class.versioned? ? b.as_of_draft_version : b %>
88
- <tr id="<%= block.class.name.underscore %>_<%= block.id %>" class="<%= block.class.name.underscore %> <%= block.class.publishable? && !block.published? ? 'draft' : 'published' %>">
92
+ <tr id="<%= block.class.name.underscore %>_<%= block.id %>" class="<%= block.class.name.underscore %> <%= block.class.publishable? && !block.published? ? 'draft' : 'published' %> <%= 'non-editable' unless current_user.able_to_edit?(block) %> <%= 'non-publishable' unless current_user.able_to_publish?(block) %>">
89
93
  <td class="first"></td>
90
94
  <% content_type.columns_for_index.each_with_index do |column, i| %>
91
95
  <td class="<%= column[:label].gsub(' ', '').underscore %>">
@@ -1,6 +1,5 @@
1
1
  <% page_title @page.page_title -%>
2
2
  <% if @show_toolbar -%>
3
- <% content_for :html_head, stylesheet_link_tag('cms/page') -%>
4
3
  <% flash.keep -%>
5
4
  <iframe src="<%=h cms_toolbar_path(:page_id => @page.id, :page_version => @page.version, :mode => @mode, :page_toolbar => @show_page_toolbar ? 1 : 0) %>" width="100%" height="<%= @show_page_toolbar ? 159 : 100 %>px" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" name="cms_toolbar"></iframe>
6
5
  <% end -%>
@@ -0,0 +1,50 @@
1
+ <div class="dashboard_unit wide" id="recent_changes">
2
+ <h2>Recent Changes</h2>
3
+
4
+ <div class="roundedcorners" style="position: relative">
5
+ <table class="data">
6
+ <thead>
7
+ <tr>
8
+ <th class="name first unbordered" colspan="2"><div class="dividers">Page</div></th>
9
+ <th><div class="dividers">Version</div></th>
10
+ <th><div class="dividers">Comment</div></th>
11
+ <th><div class="dividers">Date</div></th>
12
+ <th class="last" colspan="2"><div class="dividers">Editor</div></th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <% @recent_updates.each do |r| %>
17
+ <tr>
18
+ <td class="first"></td>
19
+ <td class="name">
20
+ <div class="dividers">
21
+ <%= link_to h(r.page.name_with_section_path), r.page.path %>
22
+ </div>
23
+ </td>
24
+ <td>
25
+ <div class="dividers">
26
+ <%= "v.#{r.version}" %>
27
+ <%= '(LIVE)' if r.page.version == r.version %>
28
+ <%= '(CURRENT)' if r.page.draft == r %>
29
+ </div>
30
+ </td>
31
+ <td>
32
+ <div class="dividers"><%=h r.version_comment %></div>
33
+ </td>
34
+ <td>
35
+ <div class="dividers"><%= r.created_at.strftime("%b %d, %Y %I:%M %p") if r.created_at %></div>
36
+ </td>
37
+ <td>
38
+ <div><%= r.updated_by.login if r.updated_by %></div>
39
+ </td>
40
+ <td class="last"></td>
41
+ </tr>
42
+ <% end %>
43
+ </tbody>
44
+ </table>
45
+ <div class="tl"></div>
46
+ <div class="tr"></div>
47
+ <div class="bl"></div>
48
+ <div class="br"></div>
49
+ </div>
50
+ </div>
@@ -9,7 +9,15 @@
9
9
  <%= render :partial => 'page_drafts' %>
10
10
  <img src="/images/cms/dashboard/bottom_cap.png" style="position: absolute; bottom: -9px; left: 0" />
11
11
  </div>
12
+
12
13
  <div class="dashboard_wrap tasks_margin">
13
14
  <%= render :partial => 'tasks' %>
14
15
  <img src="/images/cms/dashboard/bottom_cap.png" style="position: absolute; bottom: -9px; left: 0" />
15
- </div>
16
+ </div>
17
+
18
+ <br clear="all"/>
19
+ <div class="wide_top_cap"></div>
20
+ <div class="dashboard_wrap">
21
+ <%= render :partial => 'recently_updated' %>
22
+ <img src="/images/cms/bottom_cap.png" style="position: absolute; bottom: -9px; left: 0" />
23
+ </div>
@@ -11,46 +11,48 @@
11
11
  </div>
12
12
  </div>
13
13
 
14
- <div class="checkbox_group fields" style="float: left; width: 100%">
15
- <label>Public Permissions</label>
16
- <%= hidden_field_tag "section[group_ids][]", "", :id => nil %>
17
- <div class="checkboxes">
18
- <% for group in public_groups %>
19
- <div class="checkbox_fields">
20
- <%= check_box_tag "section[group_ids][]", group.id,
21
- @section.groups.include?(group), :class => "public_group_ids", :id => "public_group_ids_#{group.id}", :tabindex => next_tabindex %>
22
- <label for="public_group_ids_<%= group.id %>"><%= group.name %></label>
23
- </div>
24
- <% end %>
25
- <div class="instructions">Which &ldquo;Public&rdquo; groups can view pages in this section?</div>
26
- <div class="check_uncheck">
27
- <%= link_to_check_all 'input.public_group_ids' %>,
28
- <%= link_to_uncheck_all 'input.public_group_ids' %>
14
+ <% able_to?(:administrate) do %>
15
+ <div class="checkbox_group fields" style="float: left; width: 100%">
16
+ <label>Public Permissions</label>
17
+ <%= hidden_field_tag "section[group_ids][]", "", :id => nil %>
18
+ <div class="checkboxes">
19
+ <% for group in public_groups %>
20
+ <div class="checkbox_fields">
21
+ <%= check_box_tag "section[group_ids][]", group.id,
22
+ @section.groups.include?(group), :class => "public_group_ids", :id => "public_group_ids_#{group.id}", :tabindex => next_tabindex %>
23
+ <label for="public_group_ids_<%= group.id %>"><%= group.name %></label>
24
+ </div>
25
+ <% end %>
26
+ <div class="instructions">Which &ldquo;Public&rdquo; groups can view pages in this section?</div>
27
+ <div class="check_uncheck">
28
+ <%= link_to_check_all 'input.public_group_ids' %>,
29
+ <%= link_to_uncheck_all 'input.public_group_ids' %>
30
+ </div>
29
31
  </div>
30
32
  </div>
31
- </div>
32
33
 
33
- <br clear="all" />
34
+ <br clear="all" />
34
35
 
35
- <div class="checkbox_group fields" style="float: left; width: 100%">
36
- <label>CMS Permissions</label>
37
- <%= hidden_field_tag "section[group_ids][]", "", :id => nil %>
38
- <div class="checkboxes">
39
- <% for group in cms_groups %>
40
- <div class="checkbox_fields">
41
- <%= check_box_tag "section[group_ids][]", group.id,
42
- @section.groups.include?(group), :class => "cms_group_ids", :id => "cms_group_ids_#{group.id}", :tabindex => next_tabindex %>
43
- <label for="cms_group_ids_<%= group.id %>"><%= group.name %></label>
44
- </div>
45
- <% end %>
46
- <div class="instructions">Which &ldquo;CMS&rdquo; groups can edit pages and content in this section?</div>
47
- <div class="check_uncheck">
48
- <%= link_to_check_all 'input.cms_group_ids' %>,
49
- <%= link_to_uncheck_all 'input.cms_group_ids' %>
36
+ <div class="checkbox_group fields" style="float: left; width: 100%">
37
+ <label>CMS Permissions</label>
38
+ <%= hidden_field_tag "section[group_ids][]", "", :id => nil %>
39
+ <div class="checkboxes">
40
+ <% for group in cms_groups %>
41
+ <div class="checkbox_fields">
42
+ <%= check_box_tag "section[group_ids][]", group.id,
43
+ @section.groups.include?(group), :class => "cms_group_ids", :id => "cms_group_ids_#{group.id}", :tabindex => next_tabindex %>
44
+ <label for="cms_group_ids_<%= group.id %>"><%= group.name %></label>
45
+ </div>
46
+ <% end %>
47
+ <div class="instructions">Which &ldquo;CMS&rdquo; groups can edit pages and content in this section?</div>
48
+ <div class="check_uncheck">
49
+ <%= link_to_check_all 'input.cms_group_ids' %>,
50
+ <%= link_to_uncheck_all 'input.cms_group_ids' %>
51
+ </div>
50
52
  </div>
51
53
  </div>
52
- </div>
53
- <br clear="all" />
54
+ <br clear="all" />
55
+ <% end %>
54
56
 
55
57
  <div class="buttons">
56
58
  <%= lt_button_wrapper(f.submit("Save", :class => "submit", :tabindex => next_tabindex)) %>
@@ -67,13 +67,13 @@
67
67
 
68
68
  <%= link_to "<span>Edit Properties</span>",
69
69
  [:edit, :cms, @page],
70
- :id => "edit_properties_button#{ ' disabled' if !current_user.able_to_edit?(@page) }",
71
- :class => "spacer button",
70
+ :id => "edit_properties_button",
71
+ :class => "spacer button#{ ' disabled' unless current_user.able_to_edit?(@page) }",
72
72
  :target => "_top" %>
73
73
 
74
74
  <%= link_to "<span>List Versions</span>",
75
75
  versions_cms_page_path(@page),
76
- :class => "spacer button",
76
+ :class => "spacer button#{ ' disabled' unless current_user.able_to_edit?(@page) }",
77
77
  :target => "_top" %>
78
78
 
79
79
  <% able_to? :publish_content do %>
@@ -83,7 +83,7 @@
83
83
  :id => "delete_button",
84
84
  :title => "Are you sure you want to delete '#{@page.name}'?",
85
85
  :target => "_top",
86
- :class => "spacer button confirm_with_title http_delete" %>
86
+ :class => "spacer button confirm_with_title http_delete#{ ' disabled' unless current_user.able_to_publish?(@page) }" %>
87
87
  <% else %>
88
88
  <%= link_to "<span>Revert to this Version</span>",
89
89
  revert_to_cms_page_path(@page, @page.version),
@@ -98,7 +98,7 @@
98
98
  <div class="visual_editor_label">Visual Editor:</div>
99
99
  <div class="visual_editor_value_container">
100
100
  <% if @mode == "edit" %>
101
- <div><span id="visual_editor_state">ON<% if !current_user.able_to_edit?(@page) %><em title="You don't have permission to edit this page's contents.">*</em><% end %></span></div>
101
+ <div><span id="visual_editor_state"<%= ' title="You don\'t have permission to edit this page"' unless current_user.able_to_edit?(@page) %>>ON<%= '*' unless current_user.able_to_edit?(@page) %></span></div>
102
102
  <% else %>
103
103
  <div><span id="visual_editor_state">OFF</span></div>
104
104
  <% end %>