effective_pages 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +11 -68
- 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 +11 -7
- 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 +4 -2
- data/app/models/effective/menu.rb +8 -32
- data/app/models/effective/menu_item.rb +14 -11
- data/app/models/effective/page.rb +22 -27
- data/app/views/admin/pages/_form.html.haml +12 -15
- data/config/effective_pages.rb +8 -32
- data/config/routes.rb +3 -2
- data/lib/effective_pages.rb +20 -59
- 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 +3 -26
- 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 -11
- 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 / bootstrap4 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_pages/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
|
-
```ruby
|
127
|
-
root :to => 'Effective::Pages#show', :id => 'home'
|
128
|
-
```
|
129
|
-
|
130
|
-
Rails 4 Syntax:
|
131
|
-
|
132
121
|
```ruby
|
133
|
-
root :
|
122
|
+
root to: 'effective/pages#show', id: 'home'
|
134
123
|
```
|
135
124
|
|
136
|
-
and make sure a page with slug
|
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
|
```
|
@@ -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.authorize!(self, :admin, :effective_pages)
|
49
|
-
EffectivePages.authorize!(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.authorize!(self, :admin, :effective_pages)
|
105
|
-
EffectivePages.authorize!(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,39 +1,43 @@
|
|
1
1
|
module Effective
|
2
2
|
class PagesController < ApplicationController
|
3
|
-
before_action(:authenticate_user!) if
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise) && EffectiveResources.authenticate_user
|
4
|
+
|
5
|
+
include Effective::CrudController
|
4
6
|
|
5
7
|
def show
|
6
8
|
@pages = Effective::Page.all
|
7
|
-
@pages = @pages.published unless
|
9
|
+
@pages = @pages.published unless EffectiveResources.authorized?(self, :admin, :effective_pages)
|
8
10
|
|
9
11
|
@page = @pages.find(params[:id])
|
10
12
|
|
11
13
|
raise ActiveRecord::RecordNotFound unless @page.present? # Incase .find() isn't raising it
|
12
14
|
raise Effective::AccessDenied.new('Access Denied', :show, @page) unless @page.roles_permit?(current_user)
|
13
15
|
|
14
|
-
|
16
|
+
EffectiveResources.authorize!(self, :show, @page)
|
15
17
|
|
16
18
|
@page_title = @page.title
|
17
19
|
@meta_description = @page.meta_description
|
18
20
|
@canonical_url = effective_pages.page_url(@page)
|
19
21
|
|
20
|
-
if
|
22
|
+
if EffectiveResources.authorized?(self, :admin, :effective_pages)
|
21
23
|
flash.now[:warning] = [
|
22
24
|
'Hi Admin!',
|
23
25
|
('You are viewing a hidden page.' unless @page.published?),
|
24
26
|
'Click here to',
|
25
|
-
("<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?),
|
26
27
|
("<a href='#{effective_pages.edit_admin_page_path(@page)}' class='alert-link'>edit page settings</a>.")
|
27
28
|
].compact.join(' ')
|
28
29
|
end
|
29
30
|
|
30
|
-
|
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 })
|
31
35
|
end
|
32
36
|
|
33
37
|
private
|
34
38
|
|
35
39
|
def admin_edit?
|
36
|
-
|
40
|
+
EffectiveResources.authorized?(self, :admin, :effective_pages) && (params[:edit].to_s == 'true')
|
37
41
|
end
|
38
42
|
|
39
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
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) }
|
@@ -42,29 +45,21 @@ module Effective
|
|
42
45
|
!draft?
|
43
46
|
end
|
44
47
|
|
45
|
-
def content
|
46
|
-
region(:content).content
|
47
|
-
end
|
48
|
-
|
49
|
-
def content=(input)
|
50
|
-
region(:content).content = input
|
51
|
-
end
|
52
|
-
|
53
48
|
# Returns a duplicated post object, or throws an exception
|
54
|
-
def duplicate
|
49
|
+
def duplicate
|
55
50
|
Page.new(attributes.except('id', 'updated_at', 'created_at')).tap do |page|
|
56
51
|
page.title = page.title + ' (Copy)'
|
57
52
|
page.slug = page.slug + '-copy'
|
58
53
|
page.draft = true
|
59
54
|
|
60
|
-
|
61
|
-
page.regions.build(region.attributes.except('id', 'updated_at', 'created_at'))
|
62
|
-
end
|
63
|
-
|
64
|
-
page.save!
|
55
|
+
post.body = body
|
65
56
|
end
|
66
57
|
end
|
67
58
|
|
59
|
+
def duplicate!
|
60
|
+
duplicate.tap { |page| page.save! }
|
61
|
+
end
|
62
|
+
|
68
63
|
end
|
69
64
|
|
70
65
|
end
|
@@ -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
@@ -10,7 +10,11 @@ EffectivePages.setup do |config|
|
|
10
10
|
# Any files in this directory will be automatically available when
|
11
11
|
# creating/editting an Effective::Page from the Admin screens
|
12
12
|
# Relative to app/views/
|
13
|
-
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/'
|
14
18
|
|
15
19
|
# Excluded Pages
|
16
20
|
# Any page templates from the above directory that should be excluded
|
@@ -42,44 +46,16 @@ EffectivePages.setup do |config|
|
|
42
46
|
config.silence_missing_meta_description_warnings = false
|
43
47
|
config.silence_missing_canonical_url_warnings = false
|
44
48
|
|
45
|
-
|
46
49
|
# Display the effective roles 'choose roles' input when an admin creates a new post
|
47
50
|
config.use_effective_roles = false
|
48
51
|
|
49
|
-
# Authorization Method
|
50
|
-
#
|
51
|
-
# This method is called by all controller actions with the appropriate action and resource
|
52
|
-
# If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
|
53
|
-
#
|
54
|
-
# Use via Proc (and with CanCan):
|
55
|
-
# config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
|
56
|
-
#
|
57
|
-
# Use via custom method:
|
58
|
-
# config.authorization_method = :my_authorization_method
|
59
|
-
#
|
60
|
-
# And then in your application_controller.rb:
|
61
|
-
#
|
62
|
-
# def my_authorization_method(action, resource)
|
63
|
-
# current_user.is?(:admin)
|
64
|
-
# end
|
65
|
-
#
|
66
|
-
# Or disable the check completely:
|
67
|
-
# config.authorization_method = false
|
68
|
-
config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) && resource.roles_permit?(current_user) } # CanCanCan
|
69
|
-
# Use effective_roles: resource.roles_permit?(current_user)
|
70
|
-
|
71
52
|
# Layout Settings
|
72
|
-
#
|
73
|
-
|
74
|
-
# The layout for the EffectivePages admin screen
|
75
|
-
config.layout = {
|
76
|
-
:admin => 'application'
|
77
|
-
}
|
53
|
+
# config.layout = { admin: 'admin' }
|
78
54
|
|
79
55
|
# All effective_page menu options
|
80
56
|
config.menu = {
|
81
|
-
:
|
82
|
-
:
|
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
|
83
59
|
}
|
84
60
|
|
85
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,87 +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
|
-
mattr_accessor :authenticate_user
|
30
|
-
|
31
|
-
mattr_accessor :menu
|
32
|
-
mattr_accessor :authorization_method
|
33
|
-
mattr_accessor :layout
|
34
|
-
|
35
|
-
def self.setup
|
36
|
-
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
|
+
]
|
37
17
|
end
|
38
18
|
|
39
|
-
|
40
|
-
@_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
|
41
|
-
|
42
|
-
return !!authorization_method unless authorization_method.respond_to?(:call)
|
43
|
-
controller = controller.controller if controller.respond_to?(:controller)
|
44
|
-
|
45
|
-
begin
|
46
|
-
!!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
|
47
|
-
rescue *@_exceptions
|
48
|
-
false
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.authorize!(controller, action, resource)
|
53
|
-
raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Remove leading and trailing '/' characters
|
57
|
-
# Will return: "effective/pages"
|
58
|
-
def self.pages_path=(filepath)
|
59
|
-
filepath = filepath.to_s
|
60
|
-
filepath = filepath[1..-1] if filepath.starts_with?('/')
|
61
|
-
@@pages_path = filepath.chomp('/')
|
62
|
-
end
|
19
|
+
include EffectiveGem
|
63
20
|
|
64
21
|
def self.templates
|
65
|
-
ApplicationController.view_paths.map { |path| Dir[
|
22
|
+
ApplicationController.view_paths.map { |path| Dir[File.join(path, pages_path, '**')] }.flatten.map do |file|
|
66
23
|
name = File.basename(file).split('.').first
|
67
24
|
next if name.starts_with?('_')
|
68
25
|
next if Array(EffectivePages.excluded_pages).map { |str| str.to_s }.include?(name)
|
69
26
|
name
|
70
|
-
end.compact
|
27
|
+
end.compact.sort
|
71
28
|
end
|
72
29
|
|
73
30
|
def self.layouts
|
74
|
-
|
31
|
+
return [] if layouts_path.blank?
|
32
|
+
|
33
|
+
ApplicationController.view_paths.map { |path| Dir[File.join(path, layouts_path, '**')] }.flatten.map do |file|
|
75
34
|
name = File.basename(file).split('.').first
|
76
35
|
next if name.starts_with?('_')
|
77
36
|
next if name.include?('mailer')
|
78
37
|
next if Array(EffectivePages.excluded_layouts).map { |str| str.to_s }.include?(name)
|
79
38
|
name
|
80
|
-
end.compact
|
39
|
+
end.compact.sort
|
81
40
|
end
|
82
41
|
|
83
42
|
def self.permitted_params
|
84
|
-
|
43
|
+
@permitted_params ||= [
|
44
|
+
:title, :meta_description, :draft, :layout, :template, :slug, roles: []
|
45
|
+
]
|
85
46
|
end
|
86
47
|
|
87
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,7 +1,7 @@
|
|
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
|
@@ -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
|
@@ -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,11 +0,0 @@
|
|
1
|
-
= dropdown(variation: :dropleft) do
|
2
|
-
- if EffectivePages.authorized?(self, :edit, page)
|
3
|
-
= dropdown_link_to 'Edit', effective_pages.edit_admin_page_path(page)
|
4
|
-
= dropdown_link_to 'Edit Content', effective_regions.edit_path(page), 'data-no-turbolink': true, 'data-turbolinks': false, target: '_blank'
|
5
|
-
|
6
|
-
- if EffectivePages.authorized?(self, :show, page)
|
7
|
-
= dropdown_link_to 'View', effective_pages.page_path(page), 'data-no-turbolink': true, 'data-turbolinks': false, target: '_blank'
|
8
|
-
|
9
|
-
- if EffectivePages.authorized?(self, :destroy, page)
|
10
|
-
= dropdown_link_to "Delete #{page}", effective_pages.admin_page_path(page),
|
11
|
-
data: { method: :delete, confirm: "Really delete #{page}?" }
|