effective_pages 2.0.7 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +11 -70
  4. data/app/controllers/admin/menus_controller.rb +6 -48
  5. data/app/controllers/admin/pages_controller.rb +11 -102
  6. data/app/controllers/effective/pages_controller.rb +14 -8
  7. data/app/datatables/effective_menus_datatable.rb +1 -1
  8. data/app/datatables/effective_pages_datatable.rb +3 -1
  9. data/app/helpers/effective_menus_helper.rb +1 -1
  10. data/app/helpers/effective_pages_helper.rb +5 -3
  11. data/app/models/effective/menu.rb +8 -32
  12. data/app/models/effective/menu_item.rb +14 -11
  13. data/app/models/effective/page.rb +43 -23
  14. data/app/views/admin/pages/_form.html.haml +12 -16
  15. data/app/views/admin/pages/_rich_texts.html.haml +2 -0
  16. data/config/effective_pages.rb +11 -32
  17. data/config/routes.rb +6 -9
  18. data/db/migrate/01_create_effective_pages.rb.erb +11 -3
  19. data/lib/effective_pages.rb +17 -61
  20. data/lib/effective_pages/version.rb +1 -1
  21. data/lib/generators/effective_pages/install_generator.rb +1 -1
  22. data/lib/generators/templates/example.html.haml +2 -6
  23. data/lib/tasks/effective_pages_tasks.rake +1 -1
  24. metadata +9 -31
  25. data/app/models/effective/access_denied.rb +0 -17
  26. data/app/views/admin/menus/_actions.html.haml +0 -2
  27. data/app/views/admin/menus/edit.html.haml +0 -3
  28. data/app/views/admin/menus/index.html.haml +0 -3
  29. data/app/views/admin/menus/new.html.haml +0 -3
  30. data/app/views/admin/pages/_actions.html.haml +0 -7
  31. data/app/views/admin/pages/edit.html.haml +0 -3
  32. data/app/views/admin/pages/index.html.haml +0 -6
  33. data/app/views/admin/pages/new.html.haml +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc4146ba84bf916d768ba60fd5b81cdad9d9fed5ca0183f587f7366f97f2734c
4
- data.tar.gz: d1ba1a9841c8a9950109b719c08102305c9024ebd94dc0389bf9dfc9475c39bd
3
+ metadata.gz: ccfde3b643933010d2ed2b254f381eda959b5d057cf9e30ab1cb1e2ed57adfaf
4
+ data.tar.gz: 5021c6f8feb8dfddc5f32ae1e076c976f7fc15408d0c69db25ae37e8c40da834
5
5
  SHA512:
6
- metadata.gz: bb0468bf139a9ea55c238bdfb15a1e73bb5c580b7f50d827b0962a7771fa09216e7a9ea4a84be6fea3f1bca579104e57dd74403531d085cfffce8dba24e927b7
7
- data.tar.gz: 0f70822d70b8ea025a9bc96f0899051792659e5e454052c48f44890f6a2cbe9ec2328f61dba60322920accce49463a5627695b6c5d104d844e72d0e235da170d
6
+ metadata.gz: 70284db9597483e1ff7117056a18c282c7c822c372a6f5d1826e1d01ad4fbdba6603385e584c64040b0e2a0702590f3427d258837a38829cdbf340e5650ee613
7
+ data.tar.gz: f0f64d3c8739c2aeefb511cbbd1b6fd505728e7608f06684c020c68781d0baf005b753919da9b0ed2cdaad0dcc637d5016d43ac3c7750e12344a7464a6b26678
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2018 Code and Effect Inc.
1
+ Copyright 2021 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -6,18 +6,14 @@ Create content pages ontop of one or more templates -- just regular Rails views
6
6
 
7
7
  Use this gem to create a fully-functional CMS that provides full or restricted editing for your end users.
8
8
 
9
- Built ontop of effective_regions and effective_ckeditor.
10
9
 
10
+ ## effective_pages 3.0
11
11
 
12
- ## effective_pages 2.0
13
-
14
- This is the 2.0 series of effective_pages.
15
-
16
- This requires Twitter Bootstrap 4 and Rails 5.1+
17
-
18
- Please check out [bootstrap3 branch](https://github.com/code-and-effect/effective_datatables/tree/bootstrap3) for more information using this gem with Bootstrap 3.
12
+ This is the 3.0 series of effective_pages.
19
13
 
14
+ This requires Twitter Bootstrap 4 and Rails 6+
20
15
 
16
+ Please check out [Effective Posts 0.x](https://github.com/code-and-effect/effective_posts/tree/bootstrap3) for more information using this gem with Bootstrap 3.
21
17
  ## Getting Started
22
18
 
23
19
  Please first install the [effective_regions](https://github.com/code-and-effect/effective_regions) and [effective_datatables](https://github.com/code-and-effect/effective_datatables) gems.
@@ -90,6 +86,7 @@ An example of a two-column layout I like to create is as follows:
90
86
 
91
87
  ```haml
92
88
  %h1
89
+
93
90
  = simple_effective_region page, :header do
94
91
  = page.title
95
92
 
@@ -121,19 +118,11 @@ effective_pages.page_url(page)
121
118
 
122
119
  If you would like to use an Effective::Page for your home/root page, add the following to your routes.rb:
123
120
 
124
- Rails 3 Syntax:
125
-
126
121
  ```ruby
127
- root :to => 'Effective::Pages#show', :id => 'home'
122
+ root to: 'effective/pages#show', id: 'home'
128
123
  ```
129
124
 
130
- Rails 4 Syntax:
131
-
132
- ```ruby
133
- root :to => 'effective/pages#show', :id => 'home'
134
- ```
135
-
136
- and make sure a page with slug 'home' exists.
125
+ and make sure a page with slug `home` exists.
137
126
 
138
127
 
139
128
  ### Header Tags
@@ -156,10 +145,10 @@ This helper is entirely optional and in no way required for effective_pages to w
156
145
 
157
146
  ### Body Tag Classes
158
147
 
159
- Another optional helper. Add the following to your `<body>` tag:
148
+ Another optional helper. Add the following to your `<body>` tag:
160
149
 
161
150
  ```haml
162
- %body{:class => effective_pages_body_classes}
151
+ %body{class: effective_pages_body_classes}
163
152
  ```
164
153
 
165
154
  to apply the following html classes: `params[:controller]`, `params[:action]`, `signed-in` / `not-signed-in`, `@page.template` and any thing set in the `@body_classes` instance variable.
@@ -176,54 +165,7 @@ Use this functionality to create member-only type pages.
176
165
 
177
166
  ## Authorization
178
167
 
179
- All authorization checks are handled via the config.authorization_method found in the `config/initializers/effective_pages.rb` file.
180
-
181
- It is intended for flow through to CanCan or Pundit, but neither of those gems are required.
182
-
183
- This method is called by all controller actions with the appropriate action and resource
184
-
185
- Action will be one of [:index, :show, :new, :create, :edit, :update, :destroy]
186
-
187
- Resource will the appropriate Effective::Page object or class
188
-
189
- The authorization method is defined in the initializer file:
190
-
191
- ```ruby
192
- # As a Proc (with CanCan)
193
- config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) }
194
- ```
195
-
196
- ```ruby
197
- # As a Custom Method
198
- config.authorization_method = :my_authorization_method
199
- ```
200
-
201
- and then in your application_controller.rb:
202
-
203
- ```ruby
204
- def my_authorization_method(action, resource)
205
- current_user.is?(:admin) || EffectivePunditPolicy.new(current_user, resource).send('#{action}?')
206
- end
207
- ```
208
-
209
- or disabled entirely:
210
-
211
- ```ruby
212
- config.authorization_method = false
213
- ```
214
-
215
- If the method or proc returns false (user is not authorized) an Effective::AccessDenied exception will be raised
216
-
217
- You can rescue from this exception by adding the following to your application_controller.rb:
218
-
219
- ```ruby
220
- rescue_from Effective::AccessDenied do |exception|
221
- respond_to do |format|
222
- format.html { render 'static_pages/access_denied', :status => 403 }
223
- format.any { render :text => 'Access Denied', :status => 403 }
224
- end
225
- end
226
- ```
168
+ All authorization checks are handled via the effective_resources gem found in the `config/initializers/effective_resources.rb` file.
227
169
 
228
170
  ### Permissions
229
171
 
@@ -234,6 +176,7 @@ can [:show], Effective::Page
234
176
 
235
177
  if user.is?(:admin)
236
178
  can :manage, Effective::Page
179
+ can :manage, Effective::Menu
237
180
  can :admin, :effective_pages # Can access the admin screens
238
181
  end
239
182
  ```
@@ -250,5 +193,3 @@ MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
250
193
  4. Push to the branch (`git push origin my-new-feature`)
251
194
  5. Bonus points for test coverage
252
195
  6. Create new Pull Request
253
-
254
-
@@ -1,56 +1,14 @@
1
1
  module Admin
2
2
  class MenusController < ApplicationController
3
- before_action(:authenticate_user!) # Devise
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_pages) }
4
5
 
5
- helper EffectiveMenusAdminHelper
6
-
7
- layout (EffectivePages.layout.kind_of?(Hash) ? EffectivePages.layout[:admin] : EffectivePages.layout)
8
-
9
- def index
10
- @datatable = EffectiveMenusDatatable.new(self)
11
- @page_title = 'Menus'
12
-
13
- authorize_effective_menus!
14
- end
15
-
16
- def new
17
- @menu = Effective::Menu.new()
18
- @page_title = 'New Menu'
19
-
20
- authorize_effective_menus!
21
- end
22
-
23
- def create
24
- @menu = Effective::Menu.new(menu_params)
25
- @page_title = 'New Menu'
6
+ include Effective::CrudController
26
7
 
27
- authorize_effective_menus!
28
-
29
- if @menu.save
30
- flash[:success] = 'Successfully created menu'
31
- redirect_to effective_pages.admin_menu_path(@menu)
32
- else
33
- flash.now[:danger] = 'Unable to create menu'
34
- render :action => :new
35
- end
36
- end
37
-
38
- def show
39
- @menu = Effective::Menu.find(params[:id])
40
- @page_title = @menu.to_s
41
-
42
- authorize_effective_menus!
43
- end
44
-
45
- private
46
-
47
- def authorize_effective_menus!
48
- EffectivePages.authorized?(self, :admin, :effective_pages)
49
- EffectivePages.authorized?(self, action_name.to_sym, @menu || Effective::Menu)
50
- end
8
+ helper EffectiveMenusAdminHelper
51
9
 
52
- def menu_params
53
- params.require(:effective_menu).permit(:title)
10
+ if (config = EffectivePages.layout)
11
+ layout(config.kind_of?(Hash) ? config[:admin] : config)
54
12
  end
55
13
 
56
14
  end
@@ -1,112 +1,21 @@
1
1
  module Admin
2
2
  class PagesController < ApplicationController
3
- before_action(:authenticate_user!) # Devise
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_pages) }
4
5
 
5
- layout (EffectivePages.layout.kind_of?(Hash) ? EffectivePages.layout[:admin] : EffectivePages.layout)
6
+ include Effective::CrudController
6
7
 
7
- def index
8
- @datatable = EffectivePagesDatatable.new(self)
9
- @page_title = 'Pages'
10
-
11
- authorize_effective_pages!
12
- end
13
-
14
- def new
15
- @page = Effective::Page.new()
16
- @page_title = 'New Page'
17
-
18
- authorize_effective_pages!
19
- end
20
-
21
- def create
22
- @page = Effective::Page.new(page_params)
23
- @page_title = 'New Page'
24
-
25
- authorize_effective_pages!
26
-
27
- if @page.save
28
- if params[:commit] == 'Save and Edit Content'
29
- redirect_to effective_regions.edit_path(effective_pages.page_path(@page), :exit => effective_pages.edit_admin_page_path(@page))
30
- elsif params[:commit] == 'Save and Add New'
31
- flash[:success] = 'Successfully created page'
32
- redirect_to effective_pages.new_admin_page_path
33
- elsif params[:commit] == 'Save and View'
34
- redirect_to effective_pages.page_path(@page)
35
- else
36
- flash[:success] = 'Successfully created page'
37
- redirect_to effective_pages.edit_admin_page_path(@page)
38
- end
39
- else
40
- flash.now[:danger] = 'Unable to create page'
41
- render :action => :new
42
- end
43
- end
44
-
45
- def edit
46
- @page = Effective::Page.find(params[:id])
47
- @page_title = 'Edit Page'
48
-
49
- authorize_effective_pages!
8
+ if (config = EffectivePages.layout)
9
+ layout(config.kind_of?(Hash) ? config[:admin] : config)
50
10
  end
51
11
 
52
- def update
53
- @page = Effective::Page.find(params[:id])
54
- @page_title = 'Edit Page'
55
-
56
- authorize_effective_pages!
57
-
58
- if @page.update_attributes(page_params)
59
- if params[:commit] == 'Save and Edit Content'
60
- redirect_to effective_regions.edit_path(effective_pages.page_path(@page), :exit => effective_pages.edit_admin_page_path(@page))
61
- elsif params[:commit] == 'Save and Add New'
62
- flash[:success] = 'Successfully updated page'
63
- redirect_to effective_pages.new_admin_page_path
64
- elsif params[:commit] == 'Save and View'
65
- redirect_to effective_pages.page_path(@page)
66
- elsif params[:commit] == 'Duplicate'
67
- begin
68
- page = @page.duplicate!
69
- flash[:success] = 'Successfully saved and duplicated page.'
70
- flash[:info] = "You are now editting the duplicated page. This new page has been created as a Draft."
71
- rescue => e
72
- flash.delete(:success)
73
- flash[:danger] = "Unable to duplicate page: #{e.message}"
74
- end
75
-
76
- redirect_to effective_pages.edit_admin_page_path(page || @page)
77
- else
78
- flash[:success] = 'Successfully updated page'
79
- redirect_to effective_pages.edit_admin_page_path(@page)
80
- end
81
- else
82
- flash.now[:danger] = 'Unable to update page'
83
- render :action => :edit
84
- end
85
- end
86
-
87
- def destroy
88
- @page = Effective::Page.find(params[:id])
89
-
90
- authorize_effective_pages!
91
-
92
- if @page.destroy
93
- flash[:success] = 'Successfully deleted page'
94
- else
95
- flash[:danger] = 'Unable to delete page'
96
- end
97
-
98
- redirect_to effective_pages.admin_pages_path
99
- end
100
-
101
- private
102
-
103
- def authorize_effective_pages!
104
- EffectivePages.authorized?(self, :admin, :effective_pages)
105
- EffectivePages.authorized?(self, action_name.to_sym, @page|| Effective::Page)
106
- end
12
+ submit :save, 'Save'
13
+ submit :save, 'Save and Add New', redirect: :new
14
+ submit :save, 'Save and View', redirect: -> { effective_pages.page_path(resource) }
15
+ submit :save, 'Duplicate', only: :edit, redirect: -> { effective_posts.new_admin_page_path(duplicate_id: resource.id) }
107
16
 
108
- def page_params
109
- params.require(:effective_page).permit(EffectivePages.permitted_params)
17
+ def permitted_params
18
+ params.require(:effective_page).permit!
110
19
  end
111
20
 
112
21
  end
@@ -1,37 +1,43 @@
1
1
  module Effective
2
2
  class PagesController < ApplicationController
3
+ include Effective::CrudController
4
+
3
5
  def show
4
6
  @pages = Effective::Page.all
5
- @pages = @pages.published unless EffectivePages.authorized?(self, :admin, :effective_pages)
7
+ @pages = @pages.published unless EffectiveResources.authorized?(self, :admin, :effective_pages)
6
8
 
7
9
  @page = @pages.find(params[:id])
8
10
 
9
- raise ActiveRecord::RecordNotFound unless @page.present? # Incase .find() isn't raising it
10
- raise Effective::AccessDenied.new('Access Denied', :show, @page) unless @page.roles_permit?(current_user)
11
+ if @page.authenticate_user? || @page.roles.present?
12
+ authenticate_user!
13
+ end
11
14
 
12
- EffectivePages.authorized?(self, :show, @page)
15
+ raise Effective::AccessDenied.new('Access Denied', :show, @page) unless @page.roles_permit?(current_user)
16
+ EffectiveResources.authorize!(self, :show, @page)
13
17
 
14
18
  @page_title = @page.title
15
19
  @meta_description = @page.meta_description
16
20
  @canonical_url = effective_pages.page_url(@page)
17
21
 
18
- if EffectivePages.authorized?(self, :admin, :effective_pages)
22
+ if EffectiveResources.authorized?(self, :admin, :effective_pages)
19
23
  flash.now[:warning] = [
20
24
  'Hi Admin!',
21
25
  ('You are viewing a hidden page.' unless @page.published?),
22
26
  'Click here to',
23
- ("<a href='#{effective_regions.edit_path(effective_pages.page_path(@page))}' class='alert-link' data-no-turbolink='true' data-turbolinks='false'>edit page content</a> or" unless admin_edit?),
24
27
  ("<a href='#{effective_pages.edit_admin_page_path(@page)}' class='alert-link'>edit page settings</a>.")
25
28
  ].compact.join(' ')
26
29
  end
27
30
 
28
- render @page.template, layout: @page.layout, locals: { page: @page }
31
+ template = File.join(EffectivePages.pages_path, @page.template)
32
+ layout = File.join(EffectivePages.layouts_path, @page.layout)
33
+
34
+ render(template, layout: layout, locals: { page: @page })
29
35
  end
30
36
 
31
37
  private
32
38
 
33
39
  def admin_edit?
34
- EffectivePages.authorized?(self, :admin, :effective_posts) && (params[:edit].to_s == 'true')
40
+ EffectiveResources.authorized?(self, :admin, :effective_pages) && (params[:edit].to_s == 'true')
35
41
  end
36
42
 
37
43
  end
@@ -6,7 +6,7 @@ class EffectiveMenusDatatable < Effective::Datatable
6
6
 
7
7
  col :title
8
8
 
9
- actions_col partial: 'admin/menus/actions', partial_as: :menu
9
+ actions_col
10
10
  end
11
11
 
12
12
  collection do
@@ -18,7 +18,9 @@ class EffectivePagesDatatable < Effective::Datatable
18
18
  col :layout, visible: false
19
19
  col :tempate, visible: false
20
20
 
21
- actions_col partial: 'admin/pages/actions', partial_as: :page
21
+ actions_col do |page|
22
+ dropdown_link_to('View', effective_pages.page_path(page), target: '_blank')
23
+ end
22
24
  end
23
25
 
24
26
  collection do
@@ -3,7 +3,7 @@ module EffectiveMenusHelper
3
3
  menu = Effective::Menu.find_by_title(menu.to_s) if menu.kind_of?(String) || menu.kind_of?(Symbol)
4
4
  return "<ul class='nav navbar-nav'><li>Menu '#{menu}' does not exist</li></ul>".html_safe if !menu.present?
5
5
 
6
- if (effectively_editting? && EffectivePages.authorized?(controller, :edit, menu) rescue false)
6
+ if (effectively_editting? && EffectiveResources.authorized?(controller, :edit, menu) rescue false)
7
7
  options[:menu_id] = menu.id
8
8
  form_for(menu, :url => '/') { |form| options[:form] = form }
9
9
  end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EffectivePagesHelper
2
4
 
3
5
  def effective_pages_body_classes
4
6
  [
5
- params[:controller].parameterize,
7
+ params[:controller].to_s.parameterize,
6
8
  params[:action],
7
- ((user_signed_in? ? 'signed-in'.freeze : 'not-signed-in'.freeze) rescue nil),
8
- (@page.template rescue nil),
9
+ (user_signed_in? ? 'signed-in' : 'not-signed-in'),
10
+ (@page.template if @page && @page.respond_to?(:template)),
9
11
  @body_classes
10
12
  ].compact.join(' ')
11
13
  end
@@ -1,16 +1,19 @@
1
1
  module Effective
2
2
  class Menu < ActiveRecord::Base
3
- has_many :menu_items, dependent: :delete_all
3
+ attr_accessor :current_user
4
+
5
+ log_changes if respond_to?(:log_changes)
4
6
 
5
7
  self.table_name = EffectivePages.menus_table_name.to_s
6
8
 
7
- # structure do
8
- # title :string
9
- # timestamps
10
- # end
9
+ effective_resource do
10
+ title :string
11
+ timestamps
12
+ end
11
13
 
12
14
  validates :title, presence: true, uniqueness: true, length: { maximum: 255 }
13
15
 
16
+ has_many :menu_items, -> { MenuItem.sorted }, inverse_of: :menu, dependent: :delete_all
14
17
  accepts_nested_attributes_for :menu_items, allow_destroy: true
15
18
 
16
19
  before_save do
@@ -19,33 +22,6 @@ module Effective
19
22
  end
20
23
  end
21
24
 
22
- def self.update_from_effective_regions!(params)
23
- Effective::Menu.transaction do
24
- (params || {}).each do |menu_id, attributes|
25
- menu = Effective::Menu.includes(:menu_items).find(menu_id)
26
- menu.menu_items.delete_all
27
-
28
- right = -1
29
-
30
- attributes[:menu_items_attributes].each do |_, atts|
31
- atts[:menuable_type] = 'Effective::Page' if atts[:menuable_type].blank?
32
- atts.delete(:id)
33
- right = [atts[:rgt].to_i, right].max
34
- end
35
-
36
- menu.attributes = attributes
37
-
38
- # So when we render the menu, we don't include the Root/Home item.
39
- # It has a left of 1 and a right of max(items.right)
40
- root_node = menu.menu_items.find { |menu_item| menu_item.lft == 1 }
41
- root_node ||= menu.menu_items.build(title: 'Home', url: '/', lft: 1, rgt: 2)
42
- root_node.rgt = right + 1
43
-
44
- menu.save!
45
- end
46
- end
47
- end
48
-
49
25
  def to_s
50
26
  self[:title] || 'New Menu'
51
27
  end
@@ -9,19 +9,21 @@ module Effective
9
9
 
10
10
  acts_as_role_restricted
11
11
 
12
- # structure do
13
- # title :string
12
+ effective_resource do
13
+ title :string
14
14
 
15
- # url :string
16
- # special :string # divider / search / *_path
15
+ url :string
16
+ special :string # divider / search / *_path
17
17
 
18
- # classes :string
19
- # new_window :boolean
20
- # roles_mask :integer # 0 is going to mean logged in, -1 is going to mean public, > 0 will be future implementation of roles masking
18
+ classes :string
19
+ new_window :boolean
20
+ roles_mask :integer # 0 is going to mean logged in, -1 is going to mean public, > 0 will be future implementation of roles masking
21
21
 
22
- # lft :integer
23
- # rgt :integer
24
- # end
22
+ lft :integer
23
+ rgt :integer
24
+
25
+ timestamps
26
+ end
25
27
 
26
28
  validates :title, presence: true, length: { maximum: 255 }
27
29
  validates :url, length: { maximum: 255 }
@@ -32,7 +34,8 @@ module Effective
32
34
  validates :lft, presence: true
33
35
  validates :rgt, presence: true
34
36
 
35
- default_scope -> { includes(:menuable).order(:lft) }
37
+ scope :deep, -> { includes(:menuable) }
38
+ scope :sorted, -> { order(:lft) }
36
39
 
37
40
  def leaf?
38
41
  (rgt.to_i - lft.to_i) == 1
@@ -1,39 +1,63 @@
1
1
  module Effective
2
2
  class Page < ActiveRecord::Base
3
+ attr_accessor :current_user
4
+
5
+ # These parent / children are for the menu as well
6
+ belongs_to :menu_parent, class_name: 'Effective::Page', optional: true
7
+
8
+ has_many :menu_children, -> { Effective::Page.menuable }, class_name: 'Effective::Page',
9
+ foreign_key: :menu_parent_id, inverse_of: :menu_parent
10
+
3
11
  acts_as_role_restricted
4
- acts_as_regionable
5
12
  acts_as_slugged
13
+ has_many_rich_texts
6
14
 
7
- has_many :menu_items, as: :menuable, dependent: :destroy
15
+ log_changes if respond_to?(:log_changes)
8
16
 
9
17
  self.table_name = EffectivePages.pages_table_name.to_s
10
18
 
11
- # structure do
12
- # title :string
13
- # meta_description :string
19
+ effective_resource do
20
+ title :string
21
+ meta_description :string
14
22
 
15
- # draft :boolean
23
+ draft :boolean
16
24
 
17
- # layout :string
18
- # template :string
25
+ layout :string
26
+ template :string
19
27
 
20
- # slug :string
21
- # roles_mask :integer
28
+ slug :string
22
29
 
23
- # timestamps
24
- # end
30
+ roles_mask :integer
31
+ authenticate_user :boolean
32
+
33
+ # Menu stuff
34
+ menu :boolean
35
+ menu_name :string
36
+ menu_url :string
37
+ menu_position :integer
38
+
39
+ timestamps
40
+ end
25
41
 
26
42
  validates :title, presence: true, length: { maximum: 255 }
27
43
  validates :meta_description, presence: true, length: { maximum: 150 }
28
44
 
29
- validates :layout, presence: true
30
45
  validates :template, presence: true
31
46
 
47
+ # validates :menu_name, if: -> { menu? },
48
+ # presence: true, inclusion: { in: EffectivePages.menus }
49
+
50
+ # validates :menu_position, if: -> { menu? },
51
+ # presence: true, uniqueness: { scope: [:menu_name, :menu_parent_id] }
52
+
32
53
  scope :drafts, -> { where(draft: true) }
33
54
  scope :published, -> { where(draft: false) }
34
55
  scope :sorted, -> { order(:title) }
35
56
  scope :except_home, -> { where.not(title: 'Home') }
36
57
 
58
+ scope :menuable, -> { where(menu: true).order(:menu_position) }
59
+ scope :for_menu, -> (name) { menuable.where(menu_name: name) }
60
+
37
61
  def to_s
38
62
  title
39
63
  end
@@ -43,24 +67,20 @@ module Effective
43
67
  end
44
68
 
45
69
  # Returns a duplicated post object, or throws an exception
46
- def duplicate!
70
+ def duplicate
47
71
  Page.new(attributes.except('id', 'updated_at', 'created_at')).tap do |page|
48
72
  page.title = page.title + ' (Copy)'
49
73
  page.slug = page.slug + '-copy'
50
74
  page.draft = true
51
75
 
52
- regions.each do |region|
53
- page.regions.build(region.attributes.except('id', 'updated_at', 'created_at'))
54
- end
55
-
56
- page.save!
76
+ post.body = body
57
77
  end
58
78
  end
59
79
 
80
+ def duplicate!
81
+ duplicate.tap { |page| page.save! }
82
+ end
83
+
60
84
  end
61
85
 
62
86
  end
63
-
64
-
65
-
66
-
@@ -1,15 +1,15 @@
1
- = effective_form_with(model: page, url: (page.persisted? ? effective_pages.admin_page_path(page.id) : effective_pages.admin_pages_path)) do |f|
2
- = f.text_field :title, hint: 'The title of your page.', input_html: { maxlength: 255 }
1
+ = effective_form_with(model: page, url: page.persisted? ? effective_pages.admin_page_path(page.id) : effective_pages.admin_pages_path) do |f|
2
+ = f.text_field :title, hint: 'The title of your page.'
3
3
 
4
- - if (templates = EffectivePages.templates).length == 1
5
- = f.hidden_field :template, value: templates.first
6
- - else
4
+ - if (templates = EffectivePages.templates).length > 1
7
5
  = f.select :template, templates
8
-
9
- - if (layouts = EffectivePages.layouts).length == 1
10
- = f.hidden_field :layout, value: layouts.first
11
6
  - else
7
+ = f.hidden_field :template, value: templates.first
8
+
9
+ - if (layouts = EffectivePages.layouts).length > 1
12
10
  = f.select :layout, layouts
11
+ - else
12
+ = f.hidden_field :layout, value: layouts.first
13
13
 
14
14
  - if f.object.persisted? || f.object.errors.include?(:slug)
15
15
  - current_url = (effective_pages.page_url(f.object) rescue nil)
@@ -18,15 +18,11 @@
18
18
  = f.text_field :meta_description, hint: "A one or two sentence summary of this page. Appears on Google search results underneath the page title.", input_html: { maxlength: 150 }
19
19
 
20
20
  = render partial: '/admin/pages/additional_fields', locals: { page: page, form: f, f: f }
21
+ = render partial: '/admin/pages/rich_texts', locals: { page: page, form: f, f: f }
21
22
 
22
- = f.check_box :draft, label: 'Save this page as a draft. It will not be accessible on the website.'
23
+ = f.check_box :draft, label: 'Save this page as a draft. It will not be accessible on the website.'
23
24
 
24
- - if defined?(EffectiveRoles) and f.object.respond_to?(:roles) && EffectivePages.use_effective_roles
25
+ - if EffectivePages.use_effective_roles
25
26
  = render partial: '/admin/pages/roles', locals: { page: page, form: f, f: f }
26
27
 
27
- = f.submit do
28
- = f.save 'Save'
29
- = f.save 'Save and Edit Content', class: 'btn btn-secondary'
30
- = f.save 'Save and View', class: 'btn btn-secondary'
31
- - if f.object.persisted?
32
- = f.save 'Duplicate', class: 'btn btn-info'
28
+ = effective_submit(f)
@@ -0,0 +1,2 @@
1
+ = f.rich_text_area :rich_text_body, hint: 'The main body of your page'
2
+ = f.rich_text_area :rich_text_sidebar, hint: 'The sidebar content of your page'
@@ -3,11 +3,18 @@ EffectivePages.setup do |config|
3
3
  config.menus_table_name = :menus
4
4
  config.menu_items_table_name = :menu_items
5
5
 
6
+ # The menu names a page can belong to
7
+ config.menus = [:main, :footer]
8
+
6
9
  # The directory where your page templates live
7
10
  # Any files in this directory will be automatically available when
8
11
  # creating/editting an Effective::Page from the Admin screens
9
12
  # Relative to app/views/
10
- config.pages_path = '/effective/pages/'
13
+ config.pages_path = 'effective/pages/'
14
+
15
+ # The directory where your layouts live
16
+ # Relative to app/views/
17
+ config.layouts_path = 'layouts/'
11
18
 
12
19
  # Excluded Pages
13
20
  # Any page templates from the above directory that should be excluded
@@ -39,44 +46,16 @@ EffectivePages.setup do |config|
39
46
  config.silence_missing_meta_description_warnings = false
40
47
  config.silence_missing_canonical_url_warnings = false
41
48
 
42
-
43
49
  # Display the effective roles 'choose roles' input when an admin creates a new post
44
50
  config.use_effective_roles = false
45
51
 
46
- # Authorization Method
47
- #
48
- # This method is called by all controller actions with the appropriate action and resource
49
- # If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
50
- #
51
- # Use via Proc (and with CanCan):
52
- # config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
53
- #
54
- # Use via custom method:
55
- # config.authorization_method = :my_authorization_method
56
- #
57
- # And then in your application_controller.rb:
58
- #
59
- # def my_authorization_method(action, resource)
60
- # current_user.is?(:admin)
61
- # end
62
- #
63
- # Or disable the check completely:
64
- # config.authorization_method = false
65
- config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) && resource.roles_permit?(current_user) } # CanCanCan
66
- # Use effective_roles: resource.roles_permit?(current_user)
67
-
68
52
  # Layout Settings
69
- # Configure the Layout per controller, or all at once
70
-
71
- # The layout for the EffectivePages admin screen
72
- config.layout = {
73
- :admin => 'application'
74
- }
53
+ # config.layout = { admin: 'admin' }
75
54
 
76
55
  # All effective_page menu options
77
56
  config.menu = {
78
- :apply_active_class => true, # Add an .active class to the appropriate li item based on current page url
79
- :maxdepth => 2 # 2 by default, strict bootstrap3 doesnt support dropdowns in your dropdowns
57
+ apply_active_class: true, # Add an .active class to the appropriate li item based on current page url
58
+ maxdepth: 2 # 2 by default, strict bootstrap3 doesnt support dropdowns in your dropdowns
80
59
  }
81
60
 
82
61
  end
data/config/routes.rb CHANGED
@@ -1,23 +1,20 @@
1
- class EffectivePagesConstraint
2
- def self.matches?(request)
3
- Effective::Page.find(request.path_parameters[:id] || '/').present? rescue false
4
- end
5
- end
6
-
7
1
  EffectivePages::Engine.routes.draw do
8
2
  namespace :admin do
9
3
  resources :pages, except: [:show]
4
+ resources :menus
10
5
  end
11
6
 
12
- scope :module => 'effective' do
13
- get '*id', to: 'pages#show', constraints: EffectivePagesConstraint, as: :page
7
+ scope module: 'effective' do
8
+ match '*id', to: 'pages#show', via: :get, as: :page, constraints: lambda { |req|
9
+ Effective::Page.find_by_slug_or_id(req.path_parameters[:id] || '/').present?
10
+ }
14
11
  end
15
12
  end
16
13
 
17
14
  # Automatically mount the engine as an append
18
15
  Rails.application.routes.append do
19
16
  unless Rails.application.routes.routes.find { |r| r.name == 'effective_pages' }
20
- mount EffectivePages::Engine => '/', :as => 'effective_pages'
17
+ mount EffectivePages::Engine => '/', as: 'effective_pages'
21
18
  end
22
19
  end
23
20
 
@@ -4,13 +4,21 @@ class CreateEffectivePages < ActiveRecord::Migration[4.2]
4
4
  t.string :title
5
5
  t.string :meta_description
6
6
 
7
- t.boolean :draft, :default => false
7
+ t.boolean :draft, default: false
8
8
 
9
- t.string :layout, :default => 'application'
9
+ t.string :layout, default: 'application'
10
10
  t.string :template
11
11
 
12
12
  t.string :slug
13
- t.integer :roles_mask, :default => 0
13
+
14
+ t.boolean :authenticate_user, default: false
15
+ t.integer :roles_mask, default: 0
16
+
17
+ t.integer :menu_parent_id
18
+ t.boolean :menu, default: true
19
+ t.string :menu_name
20
+ t.string :menu_url
21
+ t.integer :menu_position
14
22
 
15
23
  t.datetime :updated_at
16
24
  t.datetime :created_at
@@ -1,86 +1,42 @@
1
1
  require 'effective_datatables'
2
- require 'effective_regions'
2
+ require 'effective_resources'
3
3
  require 'effective_roles'
4
4
  require 'effective_pages/engine'
5
5
  require 'effective_pages/version'
6
6
 
7
7
  module EffectivePages
8
- mattr_accessor :pages_table_name
9
- mattr_accessor :menus_table_name
10
- mattr_accessor :menu_items_table_name
11
-
12
- mattr_accessor :pages_path
13
- mattr_accessor :excluded_pages
14
- mattr_accessor :excluded_layouts
15
-
16
- mattr_accessor :site_og_image
17
- mattr_accessor :site_og_image_width
18
- mattr_accessor :site_og_image_height
19
-
20
- mattr_accessor :site_title
21
- mattr_accessor :site_title_suffix
22
- mattr_accessor :fallback_meta_description
23
-
24
- mattr_accessor :silence_missing_page_title_warnings
25
- mattr_accessor :silence_missing_meta_description_warnings
26
- mattr_accessor :silence_missing_canonical_url_warnings
27
-
28
- mattr_accessor :use_effective_roles
29
-
30
- mattr_accessor :menu
31
- mattr_accessor :authorization_method
32
- mattr_accessor :layout
33
-
34
- def self.setup
35
- yield self
8
+ def self.config_keys
9
+ [
10
+ :pages_table_name, :menus_table_name, :menu_items_table_name,
11
+ :pages_path, :excluded_pages, :layouts_path, :excluded_layouts,
12
+ :site_og_image, :site_og_image_width, :site_og_image_height,
13
+ :site_title, :site_title_suffix, :fallback_meta_description,
14
+ :silence_missing_page_title_warnings, :silence_missing_meta_description_warnings, :silence_missing_canonical_url_warnings,
15
+ :use_effective_roles, :menus, :menu, :layout
16
+ ]
36
17
  end
37
18
 
38
- def self.authorized?(controller, action, resource)
39
- @_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
40
-
41
- return !!authorization_method unless authorization_method.respond_to?(:call)
42
- controller = controller.controller if controller.respond_to?(:controller)
43
-
44
- begin
45
- !!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
46
- rescue *@_exceptions
47
- false
48
- end
49
- end
50
-
51
- def self.authorize!(controller, action, resource)
52
- raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
53
- end
54
-
55
- # Remove leading and trailing '/' characters
56
- # Will return: "effective/pages"
57
- def self.pages_path=(filepath)
58
- filepath = filepath.to_s
59
- filepath = filepath[1..-1] if filepath.starts_with?('/')
60
- @@pages_path = filepath.chomp('/')
61
- end
19
+ include EffectiveGem
62
20
 
63
21
  def self.templates
64
- ApplicationController.view_paths.map { |path| Dir["#{path}/#{pages_path}/**"] }.flatten.reverse.map do |file|
22
+ ApplicationController.view_paths.map { |path| Dir[File.join(path, pages_path, '**')] }.flatten.map do |file|
65
23
  name = File.basename(file).split('.').first
66
24
  next if name.starts_with?('_')
67
25
  next if Array(EffectivePages.excluded_pages).map { |str| str.to_s }.include?(name)
68
26
  name
69
- end.compact
27
+ end.compact.sort
70
28
  end
71
29
 
72
30
  def self.layouts
73
- ApplicationController.view_paths.map { |path| Dir["#{path}/layouts/**"] }.flatten.reverse.map do |file|
31
+ return [] if layouts_path.blank?
32
+
33
+ ApplicationController.view_paths.map { |path| Dir[File.join(path, layouts_path, '**')] }.flatten.map do |file|
74
34
  name = File.basename(file).split('.').first
75
35
  next if name.starts_with?('_')
76
36
  next if name.include?('mailer')
77
37
  next if Array(EffectivePages.excluded_layouts).map { |str| str.to_s }.include?(name)
78
38
  name
79
- end.compact
80
- end
81
-
82
- def self.permitted_params
83
- @@permitted_params ||= [:title, :meta_description, :draft, :layout, :template, :slug, roles: []]
39
+ end.compact.sort
84
40
  end
85
41
 
86
42
  end
@@ -1,3 +1,3 @@
1
1
  module EffectivePages
2
- VERSION = '2.0.7'.freeze
2
+ VERSION = '3.0.1'.freeze
3
3
  end
@@ -32,7 +32,7 @@ module EffectivePages
32
32
  end
33
33
 
34
34
  def setup_routes
35
- inject_into_file 'config/routes.rb', "\n # if you want EffectivePages to render the home / root page\n # uncomment the following line and create an Effective::Page with slug == 'home' \n # root :to => 'Effective::Pages#show', :id => 'home'\n", :before => /root (:?)to.*/
35
+ inject_into_file 'config/routes.rb', "\n # if you want EffectivePages to render the home / root page\n # uncomment the following line and create an Effective::Page with slug == 'home' \n # root to: 'Effective::Pages#show', id: 'home'\n", :before => /root (:?)to.*/
36
36
  end
37
37
 
38
38
  end
@@ -1,6 +1,2 @@
1
- %h1
2
- = simple_effective_region page, :title do
3
- = page.title
4
-
5
- = effective_region page, :content do
6
- %p this is default content for the page titled #{page.title}
1
+ %h1= page.title
2
+ = page.body
@@ -1,6 +1,6 @@
1
1
  # bundle exec rake effective_pages:seed
2
2
  namespace :effective_pages do
3
- task :seed => :environment do
3
+ task seed: :environment do
4
4
  include EffectiveMenusHelper
5
5
 
6
6
  return true if Effective::Menu.find_by_title('main menu').present?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_pages
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-31 00:00:00.000000000 Z
11
+ date: 2021-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.2.0
19
+ version: '6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.2.0
26
+ version: '6'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: effective_datatables
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 4.0.0
41
- - !ruby/object:Gem::Dependency
42
- name: effective_regions
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: effective_resources
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -98,7 +84,6 @@ files:
98
84
  - app/helpers/effective_menus_admin_helper.rb
99
85
  - app/helpers/effective_menus_helper.rb
100
86
  - app/helpers/effective_pages_helper.rb
101
- - app/models/effective/access_denied.rb
102
87
  - app/models/effective/menu.rb
103
88
  - app/models/effective/menu_item.rb
104
89
  - app/models/effective/page.rb
@@ -106,19 +91,12 @@ files:
106
91
  - app/views/admin/menu_items/_expand.html.haml
107
92
  - app/views/admin/menu_items/_item.html.haml
108
93
  - app/views/admin/menu_items/_new.html.haml
109
- - app/views/admin/menus/_actions.html.haml
110
94
  - app/views/admin/menus/_form.html.haml
111
- - app/views/admin/menus/edit.html.haml
112
- - app/views/admin/menus/index.html.haml
113
- - app/views/admin/menus/new.html.haml
114
95
  - app/views/admin/menus/show.html.haml
115
- - app/views/admin/pages/_actions.html.haml
116
96
  - app/views/admin/pages/_additional_fields.html.haml
117
97
  - app/views/admin/pages/_form.html.haml
98
+ - app/views/admin/pages/_rich_texts.html.haml
118
99
  - app/views/admin/pages/_roles.html.haml
119
- - app/views/admin/pages/edit.html.haml
120
- - app/views/admin/pages/index.html.haml
121
- - app/views/admin/pages/new.html.haml
122
100
  - config/effective_pages.rb
123
101
  - config/routes.rb
124
102
  - db/migrate/01_create_effective_pages.rb.erb
@@ -132,7 +110,7 @@ homepage: https://github.com/code-and-effect/effective_pages
132
110
  licenses:
133
111
  - MIT
134
112
  metadata: {}
135
- post_install_message:
113
+ post_install_message:
136
114
  rdoc_options: []
137
115
  require_paths:
138
116
  - lib
@@ -147,8 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
125
  - !ruby/object:Gem::Version
148
126
  version: '0'
149
127
  requirements: []
150
- rubygems_version: 3.0.3
151
- signing_key:
128
+ rubygems_version: 3.1.2
129
+ signing_key:
152
130
  specification_version: 4
153
131
  summary: Content pages for your rails app
154
132
  test_files: []
@@ -1,17 +0,0 @@
1
- unless defined?(Effective::AccessDenied)
2
- module Effective
3
- class AccessDenied < StandardError
4
- attr_reader :action, :subject
5
-
6
- def initialize(message = nil, action = nil, subject = nil)
7
- @message = message
8
- @action = action
9
- @subject = subject
10
- end
11
-
12
- def to_s
13
- @message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
14
- end
15
- end
16
- end
17
- end
@@ -1,2 +0,0 @@
1
- = dropdown(variation: :dropleft) do
2
- = dropdown_link_to 'Settings', effective_pages.admin_menu_path(menu)
@@ -1,3 +0,0 @@
1
- %h1.effective-admin-heading= @page_title
2
-
3
- = render partial: 'form', as: :menu, object: @menu
@@ -1,3 +0,0 @@
1
- %h1.effective-admin-heading= @page_title
2
-
3
- = render_datatable(@datatable)
@@ -1,3 +0,0 @@
1
- %h1.effective-admin-heading= @page_title
2
-
3
- = render partial: 'form', as: :menu, object: @menu
@@ -1,7 +0,0 @@
1
- = dropdown(variation: :dropleft) do
2
- = dropdown_link_to 'Edit', effective_pages.edit_admin_page_path(page)
3
- = dropdown_link_to 'Edit Content', effective_regions.edit_path(page), 'data-no-turbolink': true, 'data-turbolinks': false, target: '_blank'
4
- = dropdown_link_to 'View', effective_pages.page_path(page), 'data-no-turbolink': true, 'data-turbolinks': false, target: '_blank'
5
-
6
- = dropdown_link_to "Delete #{page}", effective_pages.admin_page_path(page),
7
- data: { method: :delete, confirm: "Really delete #{page}?" }
@@ -1,3 +0,0 @@
1
- %h1.effective-admin-heading= @page_title
2
-
3
- = render partial: 'form', as: :page, object: @page
@@ -1,6 +0,0 @@
1
- %h1.effective-admin-heading= @page_title
2
-
3
- %p.text-right.effective-admin-actions
4
- = link_to 'New Page', effective_pages.new_admin_page_path, class: 'btn btn-primary'
5
-
6
- = render_datatable(@datatable)
@@ -1,3 +0,0 @@
1
- %h1.effective-admin-heading= @page_title
2
-
3
- = render partial: 'form', as: :page, object: @page