effective_pages 3.0.0 → 3.0.5
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/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'
|