effective_pages 2.0.7 → 3.0.1

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 (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