effective_pages 2.0.6 → 3.0.0
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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +11 -70
- data/app/controllers/admin/menus_controller.rb +6 -48
- data/app/controllers/admin/pages_controller.rb +9 -104
- data/app/controllers/effective/pages_controller.rb +12 -6
- data/app/datatables/effective_menus_datatable.rb +1 -1
- data/app/datatables/effective_pages_datatable.rb +3 -1
- data/app/helpers/effective_menus_helper.rb +1 -1
- data/app/helpers/effective_pages_helper.rb +5 -3
- data/app/models/effective/menu.rb +8 -32
- data/app/models/effective/menu_item.rb +14 -11
- data/app/models/effective/page.rb +22 -23
- data/app/views/admin/menus/show.html.haml +1 -1
- data/app/views/admin/pages/_form.html.haml +12 -15
- data/config/effective_pages.rb +11 -32
- data/config/routes.rb +3 -2
- data/lib/effective_pages.rb +20 -58
- data/lib/effective_pages/version.rb +1 -1
- data/lib/generators/effective_pages/install_generator.rb +1 -1
- data/lib/generators/templates/example.html.haml +2 -6
- data/lib/tasks/effective_pages_tasks.rake +1 -1
- metadata +8 -31
- data/app/models/effective/access_denied.rb +0 -17
- data/app/views/admin/menus/_actions.html.haml +0 -2
- data/app/views/admin/menus/edit.html.haml +0 -3
- data/app/views/admin/menus/index.html.haml +0 -3
- data/app/views/admin/menus/new.html.haml +0 -3
- data/app/views/admin/pages/_actions.html.haml +0 -7
- data/app/views/admin/pages/edit.html.haml +0 -3
- data/app/views/admin/pages/index.html.haml +0 -6
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56bbdfa9406cb66a2fc4171e85e118038d339b056555a33fbc105880397772c7
|
4
|
+
data.tar.gz: a5bf336957ac12e9cb39a4e20be9f649cf89fa5a2be0dabb17638db7fd4efde2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ceef3c2528eefddfbfdc15c03c36b4f9f1b77b4cd8c4ff8ed683f6bdd1c8fdbd034d3138b24de88840d2cc93d1a6302629884187ceb4ddacc1c8ce1e2e4834dc
|
7
|
+
data.tar.gz: dc8d257ad150d15d2fd9d4784ed3a22dfc7b353544dd0f723f5d356bb463d92aa6cf29229be251bc576222c0eeed2e3dca5ac17c6a28cba3690735f78bf647d6
|
data/MIT-LICENSE
CHANGED
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
|
-
|
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 :
|
122
|
+
root to: 'effective/pages#show', id: 'home'
|
128
123
|
```
|
129
124
|
|
130
|
-
|
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.
|
148
|
+
Another optional helper. Add the following to your `<body>` tag:
|
160
149
|
|
161
150
|
```haml
|
162
|
-
%body{:
|
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
|
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!)
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_pages) }
|
4
5
|
|
5
|
-
|
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
|
-
|
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
|
-
|
53
|
-
|
10
|
+
if (config = EffectivePages.layout)
|
11
|
+
layout(config.kind_of?(Hash) ? config[:admin] : config)
|
54
12
|
end
|
55
13
|
|
56
14
|
end
|
@@ -1,113 +1,18 @@
|
|
1
1
|
module Admin
|
2
2
|
class PagesController < ApplicationController
|
3
|
-
before_action(:authenticate_user!)
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_pages) }
|
4
5
|
|
5
|
-
|
6
|
+
include Effective::CrudController
|
6
7
|
|
7
|
-
|
8
|
-
|
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!
|
8
|
+
if (config = EffectivePages.layout)
|
9
|
+
layout(config.kind_of?(Hash) ? config[:admin] : config)
|
19
10
|
end
|
20
11
|
|
21
|
-
|
22
|
-
|
23
|
-
|
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!
|
50
|
-
end
|
51
|
-
|
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
|
107
|
-
|
108
|
-
def page_params
|
109
|
-
params.require(:effective_page).permit(EffectivePages.permitted_params)
|
110
|
-
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) }
|
111
16
|
|
112
17
|
end
|
113
18
|
end
|
@@ -1,37 +1,43 @@
|
|
1
1
|
module Effective
|
2
2
|
class PagesController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise) && EffectiveResources.authenticate_user
|
4
|
+
|
5
|
+
include Effective::CrudController
|
6
|
+
|
3
7
|
def show
|
4
8
|
@pages = Effective::Page.all
|
5
|
-
@pages = @pages.published unless
|
9
|
+
@pages = @pages.published unless EffectiveResources.authorized?(self, :admin, :effective_pages)
|
6
10
|
|
7
11
|
@page = @pages.find(params[:id])
|
8
12
|
|
9
13
|
raise ActiveRecord::RecordNotFound unless @page.present? # Incase .find() isn't raising it
|
10
14
|
raise Effective::AccessDenied.new('Access Denied', :show, @page) unless @page.roles_permit?(current_user)
|
11
15
|
|
12
|
-
|
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
|
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'>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
|
-
|
31
|
+
template = File.join(EffectivePages.pages_path, @page.template)
|
32
|
+
layout = (@page.layout.presence || resource_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
|
-
|
40
|
+
EffectiveResources.authorized?(self, :admin, :effective_pages) && (params[:edit].to_s == 'true')
|
35
41
|
end
|
36
42
|
|
37
43
|
end
|
@@ -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
|
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? &&
|
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
|
-
(
|
8
|
-
(@page.template
|
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
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
12
|
+
effective_resource do
|
13
|
+
title :string
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
url :string
|
16
|
+
special :string # divider / search / *_path
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
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,32 +1,35 @@
|
|
1
1
|
module Effective
|
2
2
|
class Page < ActiveRecord::Base
|
3
|
-
|
4
|
-
|
3
|
+
attr_accessor :current_user
|
4
|
+
|
5
5
|
acts_as_slugged
|
6
6
|
|
7
|
+
log_changes if respond_to?(:log_changes)
|
8
|
+
acts_as_role_restricted
|
9
|
+
|
10
|
+
has_rich_text :body
|
7
11
|
has_many :menu_items, as: :menuable, dependent: :destroy
|
8
12
|
|
9
13
|
self.table_name = EffectivePages.pages_table_name.to_s
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
effective_resource do
|
16
|
+
title :string
|
17
|
+
meta_description :string
|
14
18
|
|
15
|
-
|
19
|
+
draft :boolean
|
16
20
|
|
17
|
-
|
18
|
-
|
21
|
+
layout :string
|
22
|
+
template :string
|
19
23
|
|
20
|
-
|
21
|
-
|
24
|
+
slug :string
|
25
|
+
roles_mask :integer
|
22
26
|
|
23
|
-
|
24
|
-
|
27
|
+
timestamps
|
28
|
+
end
|
25
29
|
|
26
30
|
validates :title, presence: true, length: { maximum: 255 }
|
27
31
|
validates :meta_description, presence: true, length: { maximum: 150 }
|
28
32
|
|
29
|
-
validates :layout, presence: true
|
30
33
|
validates :template, presence: true
|
31
34
|
|
32
35
|
scope :drafts, -> { where(draft: true) }
|
@@ -43,24 +46,20 @@ module Effective
|
|
43
46
|
end
|
44
47
|
|
45
48
|
# Returns a duplicated post object, or throws an exception
|
46
|
-
def duplicate
|
49
|
+
def duplicate
|
47
50
|
Page.new(attributes.except('id', 'updated_at', 'created_at')).tap do |page|
|
48
51
|
page.title = page.title + ' (Copy)'
|
49
52
|
page.slug = page.slug + '-copy'
|
50
53
|
page.draft = true
|
51
54
|
|
52
|
-
|
53
|
-
page.regions.build(region.attributes.except('id', 'updated_at', 'created_at'))
|
54
|
-
end
|
55
|
-
|
56
|
-
page.save!
|
55
|
+
post.body = body
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
59
|
+
def duplicate!
|
60
|
+
duplicate.tap { |page| page.save! }
|
61
|
+
end
|
62
|
+
|
60
63
|
end
|
61
64
|
|
62
65
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
@@ -7,7 +7,7 @@
|
|
7
7
|
All menu editing may be done from the fullscreen editor. Just drag and drop menu items.
|
8
8
|
.col-sm-6
|
9
9
|
%p.text-right
|
10
|
-
= link_to "Edit #{@menu}", effective_regions.edit_path('/'), class: 'btn btn-primary', 'data-no-turbolink': true, target: '_blank'
|
10
|
+
= link_to "Edit #{@menu}", effective_regions.edit_path('/'), class: 'btn btn-primary', 'data-no-turbolink': true, 'data-turbolinks': false, target: '_blank'
|
11
11
|
|
12
12
|
- if defined?(EffectiveRoles)
|
13
13
|
%h2 Menu Items
|
@@ -1,15 +1,15 @@
|
|
1
|
-
= effective_form_with(model: page, url:
|
2
|
-
= f.text_field :title, hint: 'The title of your page.'
|
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
|
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)
|
@@ -19,14 +19,11 @@
|
|
19
19
|
|
20
20
|
= render partial: '/admin/pages/additional_fields', locals: { page: page, form: f, f: f }
|
21
21
|
|
22
|
-
= f.
|
22
|
+
= f.rich_text_area :body, hint: 'The main body of your page'
|
23
|
+
|
24
|
+
= f.check_box :draft, label: 'Save this page as a draft. It will not be accessible on the website.'
|
23
25
|
|
24
26
|
- if defined?(EffectiveRoles) and f.object.respond_to?(:roles) && EffectivePages.use_effective_roles
|
25
27
|
= render partial: '/admin/pages/roles', locals: { page: page, form: f, f: f }
|
26
28
|
|
27
|
-
= f
|
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'
|
29
|
+
= effective_submit(f)
|
data/config/effective_pages.rb
CHANGED
@@ -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
|
+
# Call devise authenticate_user! as a before_action on Effective::Pages#show
|
7
|
+
config.authenticate_user = false
|
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 = '
|
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
|
-
#
|
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
|
-
:
|
79
|
-
:
|
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
@@ -7,9 +7,10 @@ end
|
|
7
7
|
EffectivePages::Engine.routes.draw do
|
8
8
|
namespace :admin do
|
9
9
|
resources :pages, except: [:show]
|
10
|
+
resources :menus
|
10
11
|
end
|
11
12
|
|
12
|
-
scope :
|
13
|
+
scope module: 'effective' do
|
13
14
|
get '*id', to: 'pages#show', constraints: EffectivePagesConstraint, as: :page
|
14
15
|
end
|
15
16
|
end
|
@@ -17,7 +18,7 @@ end
|
|
17
18
|
# Automatically mount the engine as an append
|
18
19
|
Rails.application.routes.append do
|
19
20
|
unless Rails.application.routes.routes.find { |r| r.name == 'effective_pages' }
|
20
|
-
mount EffectivePages::Engine => '/', :
|
21
|
+
mount EffectivePages::Engine => '/', as: 'effective_pages'
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
data/lib/effective_pages.rb
CHANGED
@@ -1,86 +1,48 @@
|
|
1
1
|
require 'effective_datatables'
|
2
|
-
require '
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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, :authenticate_user, :menu, :layout
|
16
|
+
]
|
36
17
|
end
|
37
18
|
|
38
|
-
|
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[
|
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
|
-
|
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
|
39
|
+
end.compact.sort
|
80
40
|
end
|
81
41
|
|
82
42
|
def self.permitted_params
|
83
|
-
|
43
|
+
@permitted_params ||= [
|
44
|
+
:title, :meta_description, :draft, :layout, :template, :slug, roles: []
|
45
|
+
]
|
84
46
|
end
|
85
47
|
|
86
48
|
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 :
|
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
|
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:
|
4
|
+
version: 3.0.0
|
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:
|
11
|
+
date: 2021-02-23 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:
|
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:
|
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,11 @@ 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
|
118
98
|
- 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
99
|
- config/effective_pages.rb
|
123
100
|
- config/routes.rb
|
124
101
|
- db/migrate/01_create_effective_pages.rb.erb
|
@@ -132,7 +109,7 @@ homepage: https://github.com/code-and-effect/effective_pages
|
|
132
109
|
licenses:
|
133
110
|
- MIT
|
134
111
|
metadata: {}
|
135
|
-
post_install_message:
|
112
|
+
post_install_message:
|
136
113
|
rdoc_options: []
|
137
114
|
require_paths:
|
138
115
|
- lib
|
@@ -147,8 +124,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
124
|
- !ruby/object:Gem::Version
|
148
125
|
version: '0'
|
149
126
|
requirements: []
|
150
|
-
rubygems_version: 3.
|
151
|
-
signing_key:
|
127
|
+
rubygems_version: 3.1.2
|
128
|
+
signing_key:
|
152
129
|
specification_version: 4
|
153
130
|
summary: Content pages for your rails app
|
154
131
|
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,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, target: '_blank'
|
4
|
-
= dropdown_link_to 'View', effective_pages.page_path(page), 'data-no-turbolink': true, target: '_blank'
|
5
|
-
|
6
|
-
= dropdown_link_to "Delete #{page}", effective_pages.admin_page_path(page),
|
7
|
-
data: { method: :delete, confirm: "Really delete #{page}?" }
|