effective_pages 3.0.0 → 3.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/admin/menus_controller.rb +1 -1
- data/app/controllers/admin/pages_controller.rb +5 -1
- data/app/controllers/effective/pages_controller.rb +5 -5
- data/app/datatables/effective_pages_datatable.rb +17 -1
- data/app/datatables/effective_pages_menu_datatable.rb +38 -0
- data/app/helpers/effective_menus_helper.rb +31 -136
- data/app/models/effective/page.rb +57 -7
- data/app/views/admin/menus/index.html.haml +11 -0
- data/app/views/admin/pages/_form.html.haml +21 -22
- data/app/views/admin/pages/_form_access.html.haml +10 -0
- data/app/views/admin/pages/_form_content.html.haml +3 -0
- data/app/views/admin/pages/_form_menu.html.haml +24 -0
- data/app/views/admin/pages/_form_page.html.haml +31 -0
- data/app/views/admin/pages/_rich_text_areas.html.haml +2 -0
- data/app/views/effective/pages/_menu.html.haml +20 -0
- data/config/effective_pages.rb +2 -10
- data/config/routes.rb +4 -8
- data/db/migrate/01_create_effective_pages.rb.erb +13 -30
- data/lib/effective_pages.rb +4 -10
- data/lib/effective_pages/version.rb +1 -1
- data/lib/generators/effective_pages/install_generator.rb +0 -3
- data/lib/generators/templates/example.html.haml +4 -1
- metadata +10 -14
- data/app/datatables/effective_menus_datatable.rb +0 -16
- data/app/helpers/effective_breadcrumbs_helper.rb +0 -41
- data/app/helpers/effective_menus_admin_helper.rb +0 -8
- data/app/models/effective/menu.rb +0 -148
- data/app/models/effective/menu_item.rb +0 -81
- data/app/views/admin/menu_items/_actions.html.haml +0 -4
- data/app/views/admin/menu_items/_expand.html.haml +0 -2
- data/app/views/admin/menu_items/_item.html.haml +0 -13
- data/app/views/admin/menu_items/_new.html.haml +0 -3
- data/app/views/admin/menus/_form.html.haml +0 -4
- data/app/views/admin/menus/show.html.haml +0 -39
- data/app/views/admin/pages/_roles.html.haml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2607792f3255903a84c8ef0b74d49d9278265a5ad0bdd518aae75efe55aeee7
|
4
|
+
data.tar.gz: b5e0ce5b60989700346dffa5709693c9fe80ed12a49f93f2feaa488623d38f24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f0b5af9258a98e3cd3af75523b5670716ea37a6c78d37b8951071602489ccbeee773605ee025ccf08aca905c21e139581349fe4c822f900d788493e69eb6e4e
|
7
|
+
data.tar.gz: 2f5ece4423c3742e50e104779d9a58ef8ca4a69870e8bec5a9851538c680615acba337a85be9d286c4f967341d223f2e71d7fcaa6cb7954058b03aadb04ccfb6
|
@@ -12,7 +12,11 @@ module Admin
|
|
12
12
|
submit :save, 'Save'
|
13
13
|
submit :save, 'Save and Add New', redirect: :new
|
14
14
|
submit :save, 'Save and View', redirect: -> { effective_pages.page_path(resource) }
|
15
|
-
submit :save, 'Duplicate', only: :edit, redirect: -> {
|
15
|
+
submit :save, 'Duplicate', only: :edit, redirect: -> { effective_pages.new_admin_page_path(duplicate_id: resource.id) }
|
16
|
+
|
17
|
+
def permitted_params
|
18
|
+
params.require(:effective_page).permit!
|
19
|
+
end
|
16
20
|
|
17
21
|
end
|
18
22
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module Effective
|
2
2
|
class PagesController < ApplicationController
|
3
|
-
before_action(:authenticate_user!) if defined?(Devise) && EffectiveResources.authenticate_user
|
4
|
-
|
5
3
|
include Effective::CrudController
|
6
4
|
|
7
5
|
def show
|
@@ -10,9 +8,11 @@ module Effective
|
|
10
8
|
|
11
9
|
@page = @pages.find(params[:id])
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
if @page.authenticate_user? || @page.roles.present?
|
12
|
+
authenticate_user!
|
13
|
+
end
|
15
14
|
|
15
|
+
raise Effective::AccessDenied.new('Access Denied', :show, @page) unless @page.roles_permit?(current_user)
|
16
16
|
EffectiveResources.authorize!(self, :show, @page)
|
17
17
|
|
18
18
|
@page_title = @page.title
|
@@ -29,7 +29,7 @@ module Effective
|
|
29
29
|
end
|
30
30
|
|
31
31
|
template = File.join(EffectivePages.pages_path, @page.template)
|
32
|
-
layout = (@page.layout
|
32
|
+
layout = File.join(EffectivePages.layouts_path, @page.layout)
|
33
33
|
|
34
34
|
render(template, layout: layout, locals: { page: @page })
|
35
35
|
end
|
@@ -1,5 +1,12 @@
|
|
1
1
|
class EffectivePagesDatatable < Effective::Datatable
|
2
2
|
|
3
|
+
filters do
|
4
|
+
scope :published
|
5
|
+
scope :draft
|
6
|
+
scope :on_menu
|
7
|
+
scope :all
|
8
|
+
end
|
9
|
+
|
3
10
|
datatable do
|
4
11
|
order :title, :asc
|
5
12
|
length :all
|
@@ -18,13 +25,22 @@ class EffectivePagesDatatable < Effective::Datatable
|
|
18
25
|
col :layout, visible: false
|
19
26
|
col :tempate, visible: false
|
20
27
|
|
28
|
+
col :menu
|
29
|
+
col :menu_name, visible: false
|
30
|
+
col :menu_url, visible: false
|
31
|
+
col :menu_parent, visible: false
|
32
|
+
col :menu_position, visible: false
|
33
|
+
|
34
|
+
col :authenticate_user, visible: false
|
35
|
+
col :roles, visible: false
|
36
|
+
|
21
37
|
actions_col do |page|
|
22
38
|
dropdown_link_to('View', effective_pages.page_path(page), target: '_blank')
|
23
39
|
end
|
24
40
|
end
|
25
41
|
|
26
42
|
collection do
|
27
|
-
Effective::Page.all
|
43
|
+
Effective::Page.deep.all
|
28
44
|
end
|
29
45
|
|
30
46
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class EffectivePagesMenuDatatable < Effective::Datatable
|
2
|
+
|
3
|
+
datatable do
|
4
|
+
reorder :menu_position
|
5
|
+
|
6
|
+
if attributes[:menu_parent_id].present?
|
7
|
+
col :menu_parent
|
8
|
+
end
|
9
|
+
|
10
|
+
col :title do |page|
|
11
|
+
link_to(page, effective_pages.edit_admin_page_path(page))
|
12
|
+
end
|
13
|
+
|
14
|
+
col :menu_url, label: 'Redirect Url'
|
15
|
+
col :menu_position, label: 'Position', visible: false
|
16
|
+
col :menu_children, label: 'Children'
|
17
|
+
|
18
|
+
actions_col(new: false, destroy: false)
|
19
|
+
end
|
20
|
+
|
21
|
+
collection(apply_belongs_to: false) do
|
22
|
+
scope = Effective::Page.deep.for_menu(menu)
|
23
|
+
|
24
|
+
scope = if attributes[:menu_parent_id].present?
|
25
|
+
scope.where(menu_parent_id: attributes[:menu_parent_id])
|
26
|
+
else
|
27
|
+
scope.where(menu_parent_id: nil)
|
28
|
+
end
|
29
|
+
|
30
|
+
scope
|
31
|
+
end
|
32
|
+
|
33
|
+
def menu
|
34
|
+
menu = EffectivePages.menus.find { |menu| menu.to_s == attributes[:menu].to_s }
|
35
|
+
menu || raise("unexpected menu: #{attributes[:menu] || 'none'}")
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -1,156 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module EffectiveMenusHelper
|
2
|
-
def render_menu(menu, options = {}, &block)
|
3
|
-
menu = Effective::Menu.find_by_title(menu.to_s) if menu.kind_of?(String) || menu.kind_of?(Symbol)
|
4
|
-
return "<ul class='nav navbar-nav'><li>Menu '#{menu}' does not exist</li></ul>".html_safe if !menu.present?
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
menu_items = menu.menu_items
|
12
|
-
|
13
|
-
if menu.new_record?
|
14
|
-
menu_items = menu_items.to_a.sort! { |a, b| a.lft <=> b.lft }
|
15
|
-
end
|
4
|
+
def render_menu(name, options = {}, &block)
|
5
|
+
name = name.to_s
|
6
|
+
menu = Array(EffectivePages.menus).find { |menu| menu.to_s == name }
|
16
7
|
|
17
|
-
if
|
18
|
-
|
19
|
-
else
|
20
|
-
render_menu_items(menu_items, options)
|
8
|
+
if menu.blank?
|
9
|
+
raise("unable to find menu #{name}. Please add it to config/initializers/effective_pages.rb")
|
21
10
|
end
|
22
11
|
|
23
|
-
|
24
|
-
#else
|
25
|
-
# Rails.cache.fetch(menu) { render_menu_items(menu.menu_items, options) }
|
26
|
-
#end
|
12
|
+
content_tag(:ul, options) { render('effective/pages/menu', menu: menu) }
|
27
13
|
end
|
28
14
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
html = ''
|
35
|
-
|
36
|
-
if options[:form]
|
37
|
-
html << "<ul class='nav navbar-nav effective-menu #{options[:class]}'"
|
38
|
-
html << " data-effective-menu-id='#{options[:menu_id] || 0}'"
|
39
|
-
html << " data-effective-menu-expand-html=\"#{render(:partial => 'admin/menu_items/expand').gsub('"', "'").gsub("\n", '').gsub(' ', '')}\""
|
40
|
-
html << " data-effective-menu-new-html=\"#{render(:partial => 'admin/menu_items/new', :locals => { :item => Effective::MenuItem.new(), :form => options[:form] }).gsub('"', "'").gsub("\n", '').gsub(' ', '').gsub('[0]', '[:new]').gsub('_0_', '_:new_')}\""
|
15
|
+
def render_breadcrumbs(menu, page = @page, root: 'Home')
|
16
|
+
return breadcrumbs_root_url(page, root: root) if request.path == '/'
|
17
|
+
return breadcrumbs_fallback(page, root: root) unless page.kind_of?(Effective::Page)
|
41
18
|
|
42
|
-
|
43
|
-
html << " data-effective-menu-maxdepth='#{maxdepth}'" if maxdepth > 0
|
19
|
+
parents = [page.menu_parent].compact
|
44
20
|
|
45
|
-
|
46
|
-
|
47
|
-
|
21
|
+
content_tag(:ol, class: 'breadcrumb') do
|
22
|
+
(
|
23
|
+
[content_tag(:li, link_to(root, root_path, title: root), class: 'breadcrumb-item')] +
|
24
|
+
parents.map do |page|
|
25
|
+
url = (page.menu_url.presence || effective_pages.page_path(page))
|
26
|
+
content_tag(:li, link_to(page, url, title: page.title), class: 'breadcrumb-item')
|
27
|
+
end +
|
28
|
+
[content_tag(:li, page, class: 'breadcrumb-item active', 'aria-current': 'page')]
|
29
|
+
).join.html_safe
|
48
30
|
end
|
49
|
-
|
50
|
-
stack = [items.to_a.first] # A stack to keep track of rgt values.
|
51
|
-
skip_to_lft = 0 # This lets us skip over nodes we don't have visible_for? permission to see
|
52
|
-
|
53
|
-
items.each_with_index do |item, index|
|
54
|
-
next if index == 0 # We always skip the first Root node
|
55
|
-
|
56
|
-
# This allows us to skip over nodes we don't have permission to view
|
57
|
-
next if item.lft < skip_to_lft
|
58
|
-
if options[:form].blank? && !item.visible_for?(defined?(current_user) ? current_user : nil)
|
59
|
-
skip_to_lft = item.rgt + 1
|
60
|
-
next
|
61
|
-
end
|
62
|
-
|
63
|
-
if stack.size > 1
|
64
|
-
html << "<ul class='dropdown-menu'>" if (item.rgt < stack.last.rgt) # Level down?
|
65
|
-
|
66
|
-
while item.rgt > stack.last.rgt # Level up?
|
67
|
-
stack.pop
|
68
|
-
html << "</ul></li>" if (item.rgt > stack.last.rgt)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Render the <li>...</li> with carets only on top level dropdowns, not sub dropdowns
|
73
|
-
html << render_menu_item(item, stack.size == 1, options)
|
74
|
-
|
75
|
-
stack.push(item)
|
76
|
-
end
|
77
|
-
|
78
|
-
while stack.size > 0
|
79
|
-
item = stack.pop
|
80
|
-
|
81
|
-
if stack.size == 0 # Very last one
|
82
|
-
html << render(:partial => 'admin/menu_items/actions') if options[:form]
|
83
|
-
html << (capture(&block) || '') if block_given? && !options[:form]
|
84
|
-
html << '</ul>'
|
85
|
-
elsif item.leaf? == false
|
86
|
-
html << '</ul></li>'
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
html.html_safe
|
91
31
|
end
|
92
32
|
|
93
|
-
|
94
|
-
|
95
|
-
# This is where we actually build out an li item
|
96
|
-
def render_menu_item(item, caret, options)
|
97
|
-
html = ""
|
98
|
-
|
99
|
-
url = (
|
100
|
-
if item.menuable.kind_of?(Effective::Page)
|
101
|
-
effective_pages.page_path(item.menuable)
|
102
|
-
elsif item.divider?
|
103
|
-
nil
|
104
|
-
elsif (item.special || '').end_with?('_path')
|
105
|
-
self.send(item.special) rescue nil
|
106
|
-
elsif item.url.present?
|
107
|
-
item.url
|
108
|
-
end
|
109
|
-
).presence || '#'
|
33
|
+
alias_method :render_breadcrumb, :render_breadcrumbs
|
110
34
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
classes << 'dropdown' if item.dropdown?
|
115
|
-
classes = classes.join(' ')
|
116
|
-
|
117
|
-
if item.leaf?
|
118
|
-
html << (classes.present? ? "<li class='#{classes}'>" : "<li>")
|
119
|
-
|
120
|
-
if !item.divider? || options[:form] # Show the URL in edit mode, but not normally
|
121
|
-
html << render_menu_item_anchor_tag(item, caret, url)
|
122
|
-
end
|
123
|
-
|
124
|
-
if options[:form]
|
125
|
-
html << render(:partial => 'admin/menu_items/item', :locals => { :item => item, :form => options[:form] })
|
126
|
-
end
|
127
|
-
|
128
|
-
html << "</li>"
|
129
|
-
else
|
130
|
-
html << (classes.present? ? "<li class='#{classes}'>" : "<li>")
|
131
|
-
html << render_menu_item_anchor_tag(item, caret, url)
|
132
|
-
|
133
|
-
if options[:form]
|
134
|
-
html << render(:partial => 'admin/menu_items/item', :locals => { :item => item, :form => options[:form] })
|
135
|
-
end
|
35
|
+
def breadcrumbs_root_url(page = @page, root: 'Home')
|
36
|
+
content_tag(:ol, class: 'breadcrumb') do
|
37
|
+
content_tag(:li, root, class: 'breadcrumb-item active', 'aria-current': 'page')
|
136
38
|
end
|
137
|
-
|
138
|
-
html
|
139
39
|
end
|
140
40
|
|
141
|
-
def
|
142
|
-
|
41
|
+
def breadcrumbs_fallback(page = @page, root: 'Home')
|
42
|
+
label = (page if page.kind_of?(Effective::Page)) || @page_title || 'Here'
|
143
43
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
html << "<span class='caret'></span>" if caret
|
150
|
-
html << "</a>"
|
151
|
-
end
|
152
|
-
else
|
153
|
-
"<a href='#{url}'#{new_window_html}>#{item.title}</a>"
|
44
|
+
content_tag(:ol, class: 'breadcrumb') do
|
45
|
+
[
|
46
|
+
content_tag(:li, link_to(root, root_path, title: root), class: 'breadcrumb-item'),
|
47
|
+
content_tag(:li, label, class: 'breadcrumb-item active', 'aria-current': 'page')
|
48
|
+
].join.html_safe
|
154
49
|
end
|
155
50
|
end
|
156
51
|
|
@@ -1,14 +1,19 @@
|
|
1
1
|
module Effective
|
2
2
|
class Page < ActiveRecord::Base
|
3
3
|
attr_accessor :current_user
|
4
|
+
attr_accessor :menu_root_level
|
4
5
|
|
5
|
-
|
6
|
+
# These parent / children are for the menu as well
|
7
|
+
belongs_to :menu_parent, class_name: 'Effective::Page', optional: true
|
8
|
+
|
9
|
+
has_many :menu_children, -> { Effective::Page.menuable }, class_name: 'Effective::Page',
|
10
|
+
foreign_key: :menu_parent_id, inverse_of: :menu_parent
|
6
11
|
|
7
|
-
log_changes if respond_to?(:log_changes)
|
8
12
|
acts_as_role_restricted
|
13
|
+
acts_as_slugged
|
14
|
+
has_many_rich_texts
|
9
15
|
|
10
|
-
|
11
|
-
has_many :menu_items, as: :menuable, dependent: :destroy
|
16
|
+
log_changes if respond_to?(:log_changes)
|
12
17
|
|
13
18
|
self.table_name = EffectivePages.pages_table_name.to_s
|
14
19
|
|
@@ -22,21 +27,59 @@ module Effective
|
|
22
27
|
template :string
|
23
28
|
|
24
29
|
slug :string
|
30
|
+
|
31
|
+
# Menu stuff
|
32
|
+
menu :boolean
|
33
|
+
menu_name :string
|
34
|
+
|
35
|
+
menu_title :string
|
36
|
+
menu_url :string
|
37
|
+
menu_position :integer
|
38
|
+
|
39
|
+
# Access
|
25
40
|
roles_mask :integer
|
41
|
+
authenticate_user :boolean
|
26
42
|
|
27
43
|
timestamps
|
28
44
|
end
|
29
45
|
|
46
|
+
before_validation(if: -> { menu? && menu_position.blank? }) do
|
47
|
+
self.menu_position = (self.class.where(menu_parent: menu_parent).maximum(:menu_position) || -1) + 1
|
48
|
+
end
|
49
|
+
|
50
|
+
validate(if: -> { menu_url.present? }) do
|
51
|
+
unless menu_url.start_with?('http://') || menu_url.start_with?('https://') || menu_url.start_with?('/')
|
52
|
+
self.errors.add(:menu_url, "must start with http(s):// or /")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
30
56
|
validates :title, presence: true, length: { maximum: 255 }
|
31
57
|
validates :meta_description, presence: true, length: { maximum: 150 }
|
32
58
|
|
59
|
+
validates :layout, presence: true
|
33
60
|
validates :template, presence: true
|
34
61
|
|
35
|
-
|
62
|
+
validates :menu_name, if: -> { menu? && EffectivePages.menus.present? },
|
63
|
+
presence: true, inclusion: { in: EffectivePages.menus.map(&:to_s) }
|
64
|
+
|
65
|
+
# validates :menu_position, if: -> { menu? },
|
66
|
+
# presence: true, uniqueness: { scope: [:menu_name, :menu_parent_id] }
|
67
|
+
|
68
|
+
scope :deep, -> { includes(:menu_parent, menu_children: :menu_parent) }
|
69
|
+
|
70
|
+
scope :draft, -> { where(draft: true) }
|
36
71
|
scope :published, -> { where(draft: false) }
|
37
72
|
scope :sorted, -> { order(:title) }
|
73
|
+
scope :on_menu, -> { where(menu: true) }
|
38
74
|
scope :except_home, -> { where.not(title: 'Home') }
|
39
75
|
|
76
|
+
scope :menuable, -> { where(menu: true).order(:menu_position) }
|
77
|
+
scope :menu_deep, -> { includes(:menu_parent, :menu_children) }
|
78
|
+
|
79
|
+
scope :for_menu, -> (name) { menuable.where(menu_name: name) }
|
80
|
+
scope :for_menu_root, -> (name) { for_menu(name).menu_deep.root_level }
|
81
|
+
scope :root_level, -> { where(menu_parent_id: nil) }
|
82
|
+
|
40
83
|
def to_s
|
41
84
|
title
|
42
85
|
end
|
@@ -50,9 +93,12 @@ module Effective
|
|
50
93
|
Page.new(attributes.except('id', 'updated_at', 'created_at')).tap do |page|
|
51
94
|
page.title = page.title + ' (Copy)'
|
52
95
|
page.slug = page.slug + '-copy'
|
53
|
-
page.draft = true
|
54
96
|
|
55
|
-
|
97
|
+
rich_texts.each do |rt|
|
98
|
+
page.send("rich_text_#{rt.name}=", rt.body)
|
99
|
+
end
|
100
|
+
|
101
|
+
page.draft = true
|
56
102
|
end
|
57
103
|
end
|
58
104
|
|
@@ -60,6 +106,10 @@ module Effective
|
|
60
106
|
duplicate.tap { |page| page.save! }
|
61
107
|
end
|
62
108
|
|
109
|
+
def menu_root_level
|
110
|
+
menu_parent.blank?
|
111
|
+
end
|
112
|
+
|
63
113
|
end
|
64
114
|
|
65
115
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
%h1= @page_title
|
2
|
+
|
3
|
+
%p
|
4
|
+
Click Reorder to drag & drop reorder the menu.
|
5
|
+
Edit an item to reorder its children items.
|
6
|
+
|
7
|
+
- EffectivePages.menus.each do |menu|
|
8
|
+
%h2 #{menu.to_s.titleize} Menu
|
9
|
+
- datatable = EffectivePagesMenuDatatable.new(menu: menu)
|
10
|
+
= render_datatable(datatable, simple: true, inline: true)
|
11
|
+
%hr
|
@@ -1,29 +1,28 @@
|
|
1
|
-
|
2
|
-
=
|
1
|
+
- if inline_datatable? && inline_datatable.attributes[:menu]
|
2
|
+
- menu = inline_datatable.attributes[:menu]
|
3
|
+
- datatable = EffectivePagesMenuDatatable.new(menu: menu, menu_parent_id: page.id)
|
3
4
|
|
4
|
-
|
5
|
-
= f.select :template, templates
|
6
|
-
- else
|
7
|
-
= f.hidden_field :template, value: templates.first
|
5
|
+
= render '/admin/pages/form_menu', page: page
|
8
6
|
|
9
|
-
- if (
|
10
|
-
|
11
|
-
|
12
|
-
= f.hidden_field :layout, value: layouts.first
|
7
|
+
- if datatable.present?(self)
|
8
|
+
%h3 Children
|
9
|
+
= render_datatable(datatable, simple: true, inline: true)
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
=
|
11
|
+
- else
|
12
|
+
= tabs do
|
13
|
+
= tab 'Page' do
|
14
|
+
= render '/admin/pages/form_page', page: page
|
17
15
|
|
18
|
-
|
16
|
+
- if page.persisted?
|
17
|
+
= tab 'Menu' do
|
18
|
+
= render '/admin/pages/form_menu', page: page
|
19
19
|
|
20
|
-
|
20
|
+
- unless page.menu_root_level
|
21
|
+
= tab 'Content' do
|
22
|
+
= render '/admin/pages/form_content', page: page
|
21
23
|
|
22
|
-
|
24
|
+
= tab 'Access' do
|
25
|
+
= render '/admin/pages/form_access', page: page
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
- if defined?(EffectiveRoles) and f.object.respond_to?(:roles) && EffectivePages.use_effective_roles
|
27
|
-
= render partial: '/admin/pages/roles', locals: { page: page, form: f, f: f }
|
28
|
-
|
29
|
-
= effective_submit(f)
|
27
|
+
= tab 'Logs' do
|
28
|
+
= render_datatable(page.log_changes_datatable, inline: true, namespace: :admin)
|
@@ -0,0 +1,10 @@
|
|
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.check_box :authenticate_user, label: 'Yes, the user must be be signed in to view this page'
|
3
|
+
|
4
|
+
- if EffectivePages.use_effective_roles
|
5
|
+
= f.checks :roles, EffectiveRoles.roles_collection(f.object)
|
6
|
+
|
7
|
+
%p.text-hint
|
8
|
+
* leave blank for a regular public page that anyone can view
|
9
|
+
|
10
|
+
= f.submit
|
@@ -0,0 +1,24 @@
|
|
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.check_box :menu, label: 'Yes, display this page on the menu'
|
3
|
+
|
4
|
+
= f.show_if :menu, true do
|
5
|
+
|
6
|
+
- if (menus = EffectivePages.menus).length > 1
|
7
|
+
= f.select :menu_name, menus
|
8
|
+
- else
|
9
|
+
= f.hidden_field :menu_name, value: menus.first
|
10
|
+
|
11
|
+
= f.check_box :menu_root_level, label: "This is a top level menu item. Do not show page content."
|
12
|
+
|
13
|
+
= f.show_if :menu_root_level, true do
|
14
|
+
= f.hidden_field :menu_parent_id, value: nil
|
15
|
+
|
16
|
+
= f.show_if :menu_root_level, false do
|
17
|
+
= f.select :menu_parent_id, Effective::Page.menuable.root_level.where.not(id: f.object), required: true
|
18
|
+
|
19
|
+
= f.text_field :menu_title, hint: "Display this title on menus instead of full page title"
|
20
|
+
|
21
|
+
= f.text_field :menu_url, label: "Redirect to path or url instead of displaying page",
|
22
|
+
hint: "Must start with http(s):// or /"
|
23
|
+
|
24
|
+
= f.submit
|
@@ -0,0 +1,31 @@
|
|
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
|
+
|
4
|
+
= f.check_box :draft,
|
5
|
+
label: 'Save this page as a draft. It will not be accessible on the website.'
|
6
|
+
|
7
|
+
= f.text_field :meta_description,
|
8
|
+
hint: "A one or two sentence summary of this page. Appears on Google search results underneath the page title.",
|
9
|
+
input_html: { maxlength: 150 }
|
10
|
+
|
11
|
+
- if (layouts = EffectivePages.layouts).length > 1
|
12
|
+
= f.select :layout, layouts
|
13
|
+
- else
|
14
|
+
= f.hidden_field :layout, value: layouts.first
|
15
|
+
|
16
|
+
- if (templates = EffectivePages.templates).length > 1
|
17
|
+
= f.select :template, templates
|
18
|
+
- else
|
19
|
+
= f.hidden_field :template, value: templates.first
|
20
|
+
|
21
|
+
- if f.object.persisted? || f.object.errors.include?(:slug)
|
22
|
+
- current_url = (effective_pages.page_url(f.object) rescue nil)
|
23
|
+
= f.text_field :slug, hint: "The slug controls this page's internet address. Be careful, changing the slug will break links that other websites may have to the old address.<br>#{('This page is currently reachable via ' + link_to(current_url.gsub(f.object.slug, '<strong>' + f.object.slug + '</strong>').html_safe, current_url)) if current_url }".html_safe
|
24
|
+
|
25
|
+
= render partial: '/admin/pages/additional_fields', locals: { page: page, form: f, f: f }
|
26
|
+
|
27
|
+
-# This is for duplicate
|
28
|
+
- if f.object.new_record? && f.object.rich_texts.present?
|
29
|
+
= render partial: '/admin/pages/rich_text_areas', locals: { page: page, form: f, f: f }
|
30
|
+
|
31
|
+
= effective_submit(f)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
- raise('expected a menu') unless menu.present?
|
2
|
+
- menu = menu.to_s
|
3
|
+
|
4
|
+
- Effective::Page.for_menu_root(menu).each do |page|
|
5
|
+
- next unless EffectiveResources.authorized?(self, :show, page)
|
6
|
+
- next if (page.authenticate_user || page.roles.present?) && current_user.blank?
|
7
|
+
- next if page.roles.present? && !current_user.roles.include?(page.roles)
|
8
|
+
|
9
|
+
- menu_children = page.menu_children.select { |page| page.menu_name == menu }
|
10
|
+
|
11
|
+
- if menu_children.blank?
|
12
|
+
= nav_link_to((page.menu_title.presence || page.title), (page.menu_url.presence || effective_pages.page_path(page)))
|
13
|
+
- else
|
14
|
+
= nav_dropdown(page.to_s) do
|
15
|
+
- menu_children.each do |page|
|
16
|
+
- next unless EffectiveResources.authorized?(self, :show, page)
|
17
|
+
- next if (page.authenticate_user || page.roles.present?) && current_user.blank?
|
18
|
+
- next if page.roles.present? && !current_user.roles.include?(page.roles)
|
19
|
+
|
20
|
+
= nav_link_to((page.menu_title.presence || page.title), (page.menu_url.presence || effective_pages.page_path(page)))
|
data/config/effective_pages.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
EffectivePages.setup do |config|
|
2
2
|
config.pages_table_name = :pages
|
3
|
-
config.menus_table_name = :menus
|
4
|
-
config.menu_items_table_name = :menu_items
|
5
3
|
|
6
|
-
#
|
7
|
-
config.
|
4
|
+
# The menu names a page can belong to
|
5
|
+
config.menus = [:main, :footer]
|
8
6
|
|
9
7
|
# The directory where your page templates live
|
10
8
|
# Any files in this directory will be automatically available when
|
@@ -52,10 +50,4 @@ EffectivePages.setup do |config|
|
|
52
50
|
# Layout Settings
|
53
51
|
# config.layout = { admin: 'admin' }
|
54
52
|
|
55
|
-
# All effective_page menu options
|
56
|
-
config.menu = {
|
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
|
59
|
-
}
|
60
|
-
|
61
53
|
end
|
data/config/routes.rb
CHANGED
@@ -1,17 +1,13 @@
|
|
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]
|
10
|
-
resources :menus
|
4
|
+
resources :menus, only: [:index]
|
11
5
|
end
|
12
6
|
|
13
7
|
scope module: 'effective' do
|
14
|
-
|
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
|
+
}
|
15
11
|
end
|
16
12
|
end
|
17
13
|
|
@@ -4,49 +4,32 @@ class CreateEffectivePages < ActiveRecord::Migration[4.2]
|
|
4
4
|
t.string :title
|
5
5
|
t.string :meta_description
|
6
6
|
|
7
|
-
t.boolean :draft, :
|
7
|
+
t.boolean :draft, default: false
|
8
8
|
|
9
|
-
t.string :layout, :
|
9
|
+
t.string :layout, default: 'application'
|
10
10
|
t.string :template
|
11
11
|
|
12
12
|
t.string :slug
|
13
|
-
|
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: false
|
19
|
+
t.string :menu_name
|
20
|
+
t.string :menu_title
|
21
|
+
t.string :menu_url
|
22
|
+
t.integer :menu_position
|
14
23
|
|
15
24
|
t.datetime :updated_at
|
16
25
|
t.datetime :created_at
|
17
26
|
end
|
18
|
-
add_index <%= @pages_table_name %>, :slug, :unique => true
|
19
|
-
|
20
|
-
create_table <%= @menus_table_name %> do |t|
|
21
|
-
t.string :title
|
22
|
-
t.timestamps
|
23
|
-
end
|
24
|
-
|
25
|
-
create_table <%= @menu_items_table_name %> do |t|
|
26
|
-
t.integer :menu_id
|
27
27
|
|
28
|
-
|
29
|
-
t.string :menuable_type
|
30
|
-
|
31
|
-
t.string :title
|
32
|
-
|
33
|
-
t.string :url
|
34
|
-
t.string :special
|
35
|
-
|
36
|
-
t.string :classes
|
37
|
-
t.boolean :new_window, :default => false
|
38
|
-
t.integer :roles_mask, :default => nil
|
39
|
-
|
40
|
-
t.integer :lft
|
41
|
-
t.integer :rgt
|
42
|
-
end
|
43
|
-
add_index <%= @menu_items_table_name %>, :lft
|
28
|
+
add_index <%= @pages_table_name %>, :slug, :unique => true
|
44
29
|
end
|
45
30
|
|
46
31
|
def self.down
|
47
32
|
drop_table <%= @pages_table_name %>
|
48
|
-
drop_table <%= @menus_table_name %>
|
49
|
-
drop_table <%= @menu_items_table_name %>
|
50
33
|
end
|
51
34
|
|
52
35
|
end
|
data/lib/effective_pages.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
require 'effective_datatables'
|
2
|
-
require 'effective_resources'
|
3
1
|
require 'effective_roles'
|
2
|
+
require 'effective_resources'
|
3
|
+
require 'effective_datatables'
|
4
4
|
require 'effective_pages/engine'
|
5
5
|
require 'effective_pages/version'
|
6
6
|
|
7
7
|
module EffectivePages
|
8
8
|
def self.config_keys
|
9
9
|
[
|
10
|
-
:pages_table_name,
|
10
|
+
:pages_table_name,
|
11
11
|
:pages_path, :excluded_pages, :layouts_path, :excluded_layouts,
|
12
12
|
:site_og_image, :site_og_image_width, :site_og_image_height,
|
13
13
|
:site_title, :site_title_suffix, :fallback_meta_description,
|
14
14
|
:silence_missing_page_title_warnings, :silence_missing_meta_description_warnings, :silence_missing_canonical_url_warnings,
|
15
|
-
:use_effective_roles, :
|
15
|
+
:use_effective_roles, :menus, :layout
|
16
16
|
]
|
17
17
|
end
|
18
18
|
|
@@ -39,10 +39,4 @@ module EffectivePages
|
|
39
39
|
end.compact.sort
|
40
40
|
end
|
41
41
|
|
42
|
-
def self.permitted_params
|
43
|
-
@permitted_params ||= [
|
44
|
-
:title, :meta_description, :draft, :layout, :template, :slug, roles: []
|
45
|
-
]
|
46
|
-
end
|
47
|
-
|
48
42
|
end
|
@@ -21,9 +21,6 @@ module EffectivePages
|
|
21
21
|
|
22
22
|
def create_migration_file
|
23
23
|
@pages_table_name = ':' + EffectivePages.pages_table_name.to_s
|
24
|
-
@menus_table_name = ':' + EffectivePages.menus_table_name.to_s
|
25
|
-
@menu_items_table_name = ':' + EffectivePages.menu_items_table_name.to_s
|
26
|
-
|
27
24
|
migration_template ('../' * 3) + 'db/migrate/01_create_effective_pages.rb.erb', 'db/migrate/create_effective_pages.rb'
|
28
25
|
end
|
29
26
|
|
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: 3.0.
|
4
|
+
version: 3.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -78,24 +78,20 @@ files:
|
|
78
78
|
- app/controllers/admin/menus_controller.rb
|
79
79
|
- app/controllers/admin/pages_controller.rb
|
80
80
|
- app/controllers/effective/pages_controller.rb
|
81
|
-
- app/datatables/effective_menus_datatable.rb
|
82
81
|
- app/datatables/effective_pages_datatable.rb
|
83
|
-
- app/
|
84
|
-
- app/helpers/effective_menus_admin_helper.rb
|
82
|
+
- app/datatables/effective_pages_menu_datatable.rb
|
85
83
|
- app/helpers/effective_menus_helper.rb
|
86
84
|
- app/helpers/effective_pages_helper.rb
|
87
|
-
- app/models/effective/menu.rb
|
88
|
-
- app/models/effective/menu_item.rb
|
89
85
|
- app/models/effective/page.rb
|
90
|
-
- app/views/admin/
|
91
|
-
- app/views/admin/menu_items/_expand.html.haml
|
92
|
-
- app/views/admin/menu_items/_item.html.haml
|
93
|
-
- app/views/admin/menu_items/_new.html.haml
|
94
|
-
- app/views/admin/menus/_form.html.haml
|
95
|
-
- app/views/admin/menus/show.html.haml
|
86
|
+
- app/views/admin/menus/index.html.haml
|
96
87
|
- app/views/admin/pages/_additional_fields.html.haml
|
97
88
|
- app/views/admin/pages/_form.html.haml
|
98
|
-
- app/views/admin/pages/
|
89
|
+
- app/views/admin/pages/_form_access.html.haml
|
90
|
+
- app/views/admin/pages/_form_content.html.haml
|
91
|
+
- app/views/admin/pages/_form_menu.html.haml
|
92
|
+
- app/views/admin/pages/_form_page.html.haml
|
93
|
+
- app/views/admin/pages/_rich_text_areas.html.haml
|
94
|
+
- app/views/effective/pages/_menu.html.haml
|
99
95
|
- config/effective_pages.rb
|
100
96
|
- config/routes.rb
|
101
97
|
- db/migrate/01_create_effective_pages.rb.erb
|
@@ -1,41 +0,0 @@
|
|
1
|
-
module EffectiveBreadcrumbsHelper
|
2
|
-
def render_breadcrumbs(menu, page)
|
3
|
-
menu = Effective::Menu.find_by_title(menu.to_s) if menu.kind_of?(String) || menu.kind_of?(Symbol)
|
4
|
-
return "Menu '#{menu}' does not exist".html_safe unless menu.present?
|
5
|
-
|
6
|
-
return breadcrumbs_fallback(page) if !page.present?
|
7
|
-
|
8
|
-
menu_item = if page.kind_of?(Effective::Page)
|
9
|
-
url = effective_pages.page_path(page)
|
10
|
-
menu.menu_items.find { |item| item.menuable == page || item.title == page.title || item.url == url }
|
11
|
-
elsif page.kind_of?(String)
|
12
|
-
downcased = page.downcase
|
13
|
-
menu.menu_items.find { |item| item.title.downcase == downcased || item.url == downcased }
|
14
|
-
else
|
15
|
-
menu.menu_items.find { |item| item.menuable == page || item.title == page || item.url == page }
|
16
|
-
end
|
17
|
-
|
18
|
-
return breadcrumbs_fallback(page) unless menu_item.present?
|
19
|
-
|
20
|
-
parents = menu.menu_items.select { |item| item.lft < menu_item.lft && item.rgt > menu_item.rgt }
|
21
|
-
|
22
|
-
content_tag(:ol, class: 'breadcrumb') do
|
23
|
-
(
|
24
|
-
parents.map { |parent| content_tag(:li, link_to(parent.title, parent.url.presence || '#', title: parent.title)) } +
|
25
|
-
[content_tag(:li, page.try(:title) || page, class: 'active')]
|
26
|
-
).join().html_safe
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
alias_method :render_breadcrumb, :render_breadcrumbs
|
31
|
-
|
32
|
-
def breadcrumbs_fallback(page = nil, root: 'Home')
|
33
|
-
content_tag(:ol, class: 'breadcrumb') do
|
34
|
-
[
|
35
|
-
content_tag(:li, link_to(root, root_path, title: root)),
|
36
|
-
content_tag(:li, ((page.title if page.respond_to?(:title)) || page || @page_title || 'Here'), class: 'active')
|
37
|
-
].join().html_safe
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
@@ -1,8 +0,0 @@
|
|
1
|
-
module EffectiveMenusAdminHelper
|
2
|
-
|
3
|
-
def visible_badge(menu_item, stack, comparator)
|
4
|
-
visible = comparator.call(menu_item) && stack.all? { |parent_menu_item| parent_menu_item.lft == 1 || comparator.call(parent_menu_item) }
|
5
|
-
content_tag(:span, (visible ? 'YES'.freeze : 'NO'.freeze), :class => "label label-#{(visible ? 'primary' : 'warning')}")
|
6
|
-
end
|
7
|
-
|
8
|
-
end
|
@@ -1,148 +0,0 @@
|
|
1
|
-
module Effective
|
2
|
-
class Menu < ActiveRecord::Base
|
3
|
-
attr_accessor :current_user
|
4
|
-
|
5
|
-
log_changes if respond_to?(:log_changes)
|
6
|
-
|
7
|
-
self.table_name = EffectivePages.menus_table_name.to_s
|
8
|
-
|
9
|
-
effective_resource do
|
10
|
-
title :string
|
11
|
-
timestamps
|
12
|
-
end
|
13
|
-
|
14
|
-
validates :title, presence: true, uniqueness: true, length: { maximum: 255 }
|
15
|
-
|
16
|
-
has_many :menu_items, -> { MenuItem.sorted }, inverse_of: :menu, dependent: :delete_all
|
17
|
-
accepts_nested_attributes_for :menu_items, allow_destroy: true
|
18
|
-
|
19
|
-
before_save do
|
20
|
-
if self.menu_items.find { |menu_item| menu_item.lft == 1 }.blank?
|
21
|
-
menu_items.build(title: 'Home', url: '/', lft: 1, rgt: 2)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_s
|
26
|
-
self[:title] || 'New Menu'
|
27
|
-
end
|
28
|
-
|
29
|
-
def contains?(obj)
|
30
|
-
menu_items.find { |menu_item| menu_item.url == obj || menu_item.menuable == obj }.present?
|
31
|
-
end
|
32
|
-
|
33
|
-
# This is the entry point to the DSL method for creating menu items
|
34
|
-
def build(&block)
|
35
|
-
raise 'build must be called with a block' if !block_given?
|
36
|
-
|
37
|
-
root = menu_items.build(title: 'Home', url: '/', lft: 1, rgt: 2)
|
38
|
-
root.parent = true
|
39
|
-
instance_exec(&block) # A call to dropdown or item
|
40
|
-
root.rgt = menu_items.map(&:rgt).max
|
41
|
-
self
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def dropdown(title, options = {}, &block)
|
47
|
-
raise 'dropdown must be called with a block' if !block_given?
|
48
|
-
raise 'dropdown menu_items may not have a URL' if options.kind_of?(String) || options.kind_of?(Symbol)
|
49
|
-
raise 'dropdown second parameter expects a Hash' unless options.kind_of?(Hash)
|
50
|
-
|
51
|
-
prev_item = menu_items.last
|
52
|
-
|
53
|
-
if prev_item.parent == true # This came from root or dropdown
|
54
|
-
lft = prev_item.lft + 1 # Go down. from lft
|
55
|
-
rgt = prev_item.rgt + 1
|
56
|
-
else
|
57
|
-
lft = prev_item.rgt + 1 # Go accross. from rgt
|
58
|
-
rgt = prev_item.rgt + 2
|
59
|
-
end
|
60
|
-
|
61
|
-
# Make room for new item by shifting everything after me up by 2
|
62
|
-
menu_items.each do |item|
|
63
|
-
item.rgt = (item.rgt + 2) if item.rgt > (lft - 1)
|
64
|
-
item.lft = (item.lft + 2) if item.lft > (lft - 1)
|
65
|
-
end
|
66
|
-
|
67
|
-
atts = build_menu_item_attributes(title, '', options).merge({:lft => lft, :rgt => rgt})
|
68
|
-
|
69
|
-
dropdown = menu_items.build(atts)
|
70
|
-
dropdown.parent = true
|
71
|
-
|
72
|
-
instance_exec(&block)
|
73
|
-
|
74
|
-
# Level up
|
75
|
-
dropdown.rgt = menu_items.last.rgt + 1 # Level up
|
76
|
-
dropdown.parent = false
|
77
|
-
menu_items << menu_items.delete(dropdown) # Put myself on the end of the array
|
78
|
-
end
|
79
|
-
|
80
|
-
# The URL parameter can be:
|
81
|
-
# - an Effective::Page object
|
82
|
-
# - the symbol :divider
|
83
|
-
# - a symbol or string that ends with _path
|
84
|
-
# - or a string that is the url
|
85
|
-
|
86
|
-
def item(title, url = '#', options = {})
|
87
|
-
raise 'item third parameter expects a Hash' unless options.kind_of?(Hash)
|
88
|
-
|
89
|
-
prev_item = menu_items.last
|
90
|
-
|
91
|
-
if prev_item.parent == true # This came from root or dropdown
|
92
|
-
lft = prev_item.lft + 1 # Go down. from lft
|
93
|
-
rgt = prev_item.rgt + 1
|
94
|
-
else
|
95
|
-
lft = prev_item.rgt + 1 # Go accross, from rgt
|
96
|
-
rgt = prev_item.rgt + 2
|
97
|
-
end
|
98
|
-
|
99
|
-
menu_items.each do |item|
|
100
|
-
item.rgt = (item.rgt + 2) if item.rgt > (lft - 1)
|
101
|
-
item.lft = (item.lft + 2) if item.lft > (lft - 1)
|
102
|
-
end
|
103
|
-
|
104
|
-
atts = build_menu_item_attributes(title, url, options).merge({:lft => lft, :rgt => rgt})
|
105
|
-
|
106
|
-
menu_items.build(atts)
|
107
|
-
end
|
108
|
-
|
109
|
-
def divider(options = {})
|
110
|
-
item(:divider, :divider, options)
|
111
|
-
end
|
112
|
-
|
113
|
-
def build_menu_item_attributes(title, url, options)
|
114
|
-
options[:roles_mask] ||= 0 if (options.delete(:signed_in) || options.delete(:private))
|
115
|
-
options[:roles_mask] ||= -1 if (options.delete(:signed_out) || options.delete(:guest))
|
116
|
-
|
117
|
-
if options[:roles]
|
118
|
-
options[:roles_mask] = EffectiveRoles.roles_mask_for(options.delete(:roles))
|
119
|
-
end
|
120
|
-
|
121
|
-
options[:classes] = options.delete(:class)
|
122
|
-
|
123
|
-
if title == :divider || url == :divider || options[:divider] == true
|
124
|
-
options[:title] = 'divider'
|
125
|
-
options[:special] = 'divider'
|
126
|
-
elsif title.kind_of?(Effective::Page)
|
127
|
-
options[:title] = title.title
|
128
|
-
options[:menuable] = title
|
129
|
-
options[:url] = '#'
|
130
|
-
elsif url.kind_of?(Effective::Page)
|
131
|
-
options[:title] = title.presence || url.title
|
132
|
-
options[:menuable] = url
|
133
|
-
options[:url] = '#'
|
134
|
-
elsif url.to_s.end_with?('_path')
|
135
|
-
options[:title] = title
|
136
|
-
options[:special] = url
|
137
|
-
else
|
138
|
-
options[:title] = title
|
139
|
-
options[:url] = url
|
140
|
-
end
|
141
|
-
|
142
|
-
options
|
143
|
-
end
|
144
|
-
|
145
|
-
|
146
|
-
end
|
147
|
-
|
148
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
module Effective
|
2
|
-
class MenuItem < ActiveRecord::Base
|
3
|
-
attr_accessor :parent # This gets set on the Root node and a node created by Dropdown, so the item function knows whether to go down or to go accross
|
4
|
-
|
5
|
-
belongs_to :menu, inverse_of: :menu_items
|
6
|
-
belongs_to :menuable, polymorphic: true # Optionaly belong to an object
|
7
|
-
|
8
|
-
self.table_name = EffectivePages.menu_items_table_name.to_s
|
9
|
-
|
10
|
-
acts_as_role_restricted
|
11
|
-
|
12
|
-
effective_resource do
|
13
|
-
title :string
|
14
|
-
|
15
|
-
url :string
|
16
|
-
special :string # divider / search / *_path
|
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
|
21
|
-
|
22
|
-
lft :integer
|
23
|
-
rgt :integer
|
24
|
-
|
25
|
-
timestamps
|
26
|
-
end
|
27
|
-
|
28
|
-
validates :title, presence: true, length: { maximum: 255 }
|
29
|
-
validates :url, length: { maximum: 255 }
|
30
|
-
validates :special, length: { maximum: 255 }
|
31
|
-
validates :classes, length: { maximum: 255 }
|
32
|
-
validates :new_window, inclusion: { in: [true, false] }
|
33
|
-
|
34
|
-
validates :lft, presence: true
|
35
|
-
validates :rgt, presence: true
|
36
|
-
|
37
|
-
scope :deep, -> { includes(:menuable) }
|
38
|
-
scope :sorted, -> { order(:lft) }
|
39
|
-
|
40
|
-
def leaf?
|
41
|
-
(rgt.to_i - lft.to_i) == 1
|
42
|
-
end
|
43
|
-
|
44
|
-
def dropdown?
|
45
|
-
!leaf?
|
46
|
-
end
|
47
|
-
|
48
|
-
def divider?
|
49
|
-
leaf? && special == 'divider'
|
50
|
-
end
|
51
|
-
|
52
|
-
# For now it's just logged in or not?
|
53
|
-
# This will work with effective_roles one day...
|
54
|
-
def visible_for?(user)
|
55
|
-
can_view_page = (
|
56
|
-
if dropdown?
|
57
|
-
true
|
58
|
-
elsif menuable.kind_of?(Effective::Page)
|
59
|
-
menuable.roles_permit?(user)
|
60
|
-
else
|
61
|
-
true
|
62
|
-
end
|
63
|
-
)
|
64
|
-
|
65
|
-
can_view_menu_item = (
|
66
|
-
if roles_mask == nil
|
67
|
-
true
|
68
|
-
elsif roles_mask == -1 # Am I logged out?
|
69
|
-
user.blank?
|
70
|
-
elsif roles_mask == 0 # Am I logged in?
|
71
|
-
user.present?
|
72
|
-
else
|
73
|
-
roles_permit?(user)
|
74
|
-
end
|
75
|
-
)
|
76
|
-
|
77
|
-
can_view_page && can_view_menu_item
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
.menu-item
|
2
|
-
= form.fields_for :menu_items, item do |f|
|
3
|
-
= f.hidden_field :title, :autocomplete => 'off'
|
4
|
-
= f.hidden_field :menuable_id, :autocomplete => 'off'
|
5
|
-
= f.hidden_field :menuable_type, :autocomplete => 'off'
|
6
|
-
= f.hidden_field :url, :autocomplete => 'off'
|
7
|
-
= f.hidden_field :special, :autocomplete => 'off'
|
8
|
-
= f.hidden_field :new_window, :autocomplete => 'off'
|
9
|
-
= f.hidden_field :classes, :autocomplete => 'off'
|
10
|
-
= f.hidden_field :roles_mask, :autocomplete => 'off'
|
11
|
-
= f.hidden_field :lft, :autocomplete => 'off'
|
12
|
-
= f.hidden_field :rgt, :autocomplete => 'off'
|
13
|
-
= f.hidden_field :_destroy, :autocomplete => 'off'
|
@@ -1,39 +0,0 @@
|
|
1
|
-
%h1.effective-admin-heading= @page_title
|
2
|
-
|
3
|
-
- if defined?(EffectiveRegions)
|
4
|
-
.row.effective-admin-actions
|
5
|
-
.col-sm-6
|
6
|
-
%p
|
7
|
-
All menu editing may be done from the fullscreen editor. Just drag and drop menu items.
|
8
|
-
.col-sm-6
|
9
|
-
%p.text-right
|
10
|
-
= link_to "Edit #{@menu}", effective_regions.edit_path('/'), class: 'btn btn-primary', 'data-no-turbolink': true, 'data-turbolinks': false, target: '_blank'
|
11
|
-
|
12
|
-
- if defined?(EffectiveRoles)
|
13
|
-
%h2 Menu Items
|
14
|
-
|
15
|
-
- if @menu.menu_items.length > 1
|
16
|
-
%table.table
|
17
|
-
%thead
|
18
|
-
%th Menu Item
|
19
|
-
%th.text-center Public
|
20
|
-
%th.text-center Signed In
|
21
|
-
- EffectiveRoles.roles.each do |role|
|
22
|
-
%th.text-center= ":#{role}"
|
23
|
-
|
24
|
-
%tbody
|
25
|
-
- stack = [@menu.menu_items.first]
|
26
|
-
- @menu.menu_items.each_with_index do |menu_item, index|
|
27
|
-
- next if index == 0
|
28
|
-
- stack.pop while menu_item.rgt > stack.last.rgt if stack.size > 1
|
29
|
-
%tr
|
30
|
-
%td
|
31
|
-
= (" " * (stack.size-1)).html_safe
|
32
|
-
= (menu_item.divider? ? ':divider' : menu_item.title)
|
33
|
-
%td.text-center= visible_badge(menu_item, stack, Proc.new { |item| item.roles_mask == nil || item.roles_mask == -1 })
|
34
|
-
%td.text-center= visible_badge(menu_item, stack, Proc.new { |item| item.roles_mask == nil || item.roles_mask == 0 })
|
35
|
-
- EffectiveRoles.roles.each do |role|
|
36
|
-
%td.text-center= visible_badge(menu_item, stack, Proc.new { |item| item.visible_for?(role) })
|
37
|
-
- stack.push(menu_item)
|
38
|
-
- else
|
39
|
-
%p No menu items.
|
@@ -1 +0,0 @@
|
|
1
|
-
= f.checks :roles, EffectiveRoles.roles_collection(f.object), hint: '* leave blank for a regular public page that anyone can view'
|