we5-browsercms 3.0.2 → 3.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +1 -0
- data/app/controllers/cms/content_block_controller.rb +25 -2
- data/app/controllers/cms/content_controller.rb +31 -2
- data/app/controllers/cms/dashboard_controller.rb +2 -1
- data/app/controllers/cms/error_handling.rb +9 -2
- data/app/controllers/cms/links_controller.rb +2 -0
- data/app/controllers/cms/pages_controller.rb +22 -18
- data/app/controllers/cms/section_nodes_controller.rb +1 -1
- data/app/controllers/cms/sections_controller.rb +12 -7
- data/app/controllers/cms/sessions_controller.rb +17 -10
- data/app/controllers/cms/users_controller.rb +8 -6
- data/app/helpers/cms/application_helper.rb +2 -6
- data/app/helpers/cms/menu_helper.rb +118 -146
- data/app/helpers/cms/page_helper.rb +2 -2
- data/app/models/attachment.rb +2 -2
- data/app/models/forgot_password_mailer.rb +12 -0
- data/app/models/group.rb +13 -2
- data/app/models/guest_user.rb +9 -3
- data/app/models/link.rb +2 -2
- data/app/models/page.rb +1 -1
- data/app/models/section.rb +7 -2
- data/app/models/user.rb +35 -17
- data/app/portlets/forgot_password_portlet.rb +27 -0
- data/app/portlets/reset_password_portlet.rb +28 -0
- data/app/views/cms/blocks/_toolbar_for_member.html.erb +3 -3
- data/app/views/cms/blocks/index.html.erb +11 -6
- data/app/views/cms/content/show.html.erb +3 -3
- data/app/views/cms/forgot_password_mailer/reset_password.text.html.erb +3 -0
- data/app/views/cms/forgot_password_mailer/reset_password.text.plain.erb +3 -0
- data/app/views/cms/menus/_menu.html.erb +9 -0
- data/app/views/cms/menus/_menu_item.html.erb +11 -0
- data/app/views/cms/pages/_edit_connector.html.erb +1 -1
- data/app/views/cms/pages/_edit_container.html.erb +1 -1
- data/app/views/cms/section_nodes/_node.html.erb +1 -1
- data/app/views/cms/sections/_form.html.erb +36 -34
- data/app/views/cms/shared/access_denied.html.erb +3 -0
- data/app/views/cms/users/change_password.html.erb +8 -6
- data/app/views/cms/users/index.html.erb +1 -1
- data/app/views/cms/users/show.html.erb +50 -0
- data/app/views/layouts/_cms_toolbar.html.erb +1 -1
- data/app/views/layouts/_page_toolbar.html.erb +7 -7
- data/app/views/layouts/cms/administration.html.erb +24 -7
- data/app/views/portlets/forgot_password/_form.html.erb +5 -0
- data/app/views/portlets/forgot_password/render.html.erb +14 -0
- data/app/views/portlets/reset_password/_form.html.erb +3 -0
- data/app/views/portlets/reset_password/render.html.erb +24 -0
- data/{we5-browsercms.gemspec → browsercms.gemspec} +72 -54
- data/db/migrate/20091109175123_browsercms_3_0_5.rb +9 -0
- data/lib/acts_as_list.rb +8 -4
- data/lib/cms/acts/content_block.rb +1 -1
- data/lib/cms/authentication/controller.rb +26 -7
- data/lib/cms/behaviors/attaching.rb +3 -3
- data/lib/cms/behaviors/publishing.rb +12 -1
- data/lib/cms/behaviors/rendering.rb +17 -4
- data/lib/cms/behaviors/versioning.rb +2 -2
- data/lib/cms/routes.rb +4 -0
- data/lib/tasks/cms.rake +0 -18
- data/public/javascripts/cms/content_library.js +36 -0
- data/public/javascripts/cms/sitemap.js +21 -9
- data/public/stylesheets/cms/form_layout.css +16 -2
- data/public/stylesheets/cms/nav.css +4 -3
- data/test/functional/cms/content_block_controller_test.rb +120 -0
- data/test/functional/cms/content_controller_test.rb +135 -80
- data/test/functional/cms/links_controller_test.rb +89 -1
- data/test/functional/cms/pages_controller_test.rb +138 -0
- data/test/functional/cms/section_nodes_controller_test.rb +45 -5
- data/test/functional/cms/sections_controller_test.rb +148 -1
- data/test/functional/cms/sessions_controller_test.rb +26 -2
- data/test/functional/cms/users_controller_test.rb +49 -2
- data/test/integration/cms/password_management_test.rb +57 -0
- data/test/test_helper.rb +3 -1
- data/test/unit/behaviors/attaching_test.rb +26 -0
- data/test/unit/helpers/menu_helper_test.rb +118 -278
- data/test/unit/models/group_test.rb +6 -0
- data/test/unit/models/user_test.rb +127 -29
- metadata +20 -3
@@ -24,12 +24,8 @@ module Cms
|
|
24
24
|
text
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
29
|
-
if logged_in? && @mode == "edit"
|
30
|
-
if connectable.class.versioned?
|
31
|
-
connectable = connectable.as_of_version(connector.connectable_version)
|
32
|
-
end
|
27
|
+
def render_connector_and_connectable(connector, connectable)
|
28
|
+
if logged_in? && @mode == "edit" && current_user.able_to_edit?(connector.page)
|
33
29
|
render :partial => 'cms/pages/edit_connector',
|
34
30
|
:locals => { :connector => connector, :connectable => connectable}
|
35
31
|
else
|
@@ -1,30 +1,63 @@
|
|
1
1
|
module Cms
|
2
2
|
module MenuHelper
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
3
|
+
# Renders a menu. There are two options, neither are required:
|
4
|
+
#
|
5
|
+
# ==== Options
|
6
|
+
# * <tt>:items</tt> - The items which should appear in the menu. This defaults to calling
|
7
|
+
# menu_items which generates items automatically based on the current page. But you can use
|
8
|
+
# this option to pass in a custom menu structure.
|
9
|
+
# * <tt>:partial</tt> - The partial used to render the menu. By default this is "partials/menu",
|
10
|
+
# which can be customised through the CMS. The partial gets a local variable <tt>items</tt>.
|
11
|
+
#
|
12
|
+
# ==== Structure of items
|
11
13
|
#
|
14
|
+
# The items should be an array of hashes, in a tree. Each hash can have the following keys (name
|
15
|
+
# and url are required, others are optional):
|
16
|
+
#
|
17
|
+
# * <tt>:name</tt> - The name which appears in the menu
|
18
|
+
# * <tt>:url</tt> - The URL to link to
|
19
|
+
# * <tt>:id</tt> - The id for the menu item
|
20
|
+
# * <tt>:selected</tt> - Boolean value to indicate whether the menu item is the current page
|
21
|
+
# * <tt>:target</tt> - The target attribute for the link
|
22
|
+
# * <tt>:children</tt> - An array of hashes containing the child menu items. This is where the
|
23
|
+
# tree structure comes in.
|
24
|
+
def render_menu(options = {})
|
25
|
+
options[:items] ||= menu_items(options)
|
26
|
+
options[:partial] ||= "cms/menus/menu"
|
27
|
+
options[:id] ||= "menu"
|
28
|
+
options[:class] ||= "menu"
|
29
|
+
render :partial => options[:partial], :locals => { :items => options[:items], :css_id => options[:id], :css_class => options[:class] }
|
30
|
+
end
|
31
|
+
|
32
|
+
# This will render generate an array-of-hashes tree structure based on the page, which can be
|
33
|
+
# passed to render_menu in order to generate a menu.
|
34
|
+
#
|
35
|
+
# With no options passed, it will generate a structure that includes all the child sections of
|
36
|
+
# the root and then it will include the path of decendent sections all the way to the current
|
37
|
+
# page.
|
38
|
+
#
|
39
|
+
# Hidden pages will not be included, but if the first page in a Section is hidden, it will be
|
40
|
+
# used as the URL for that Section. This is commonly done to have a page for a Section and avoid
|
41
|
+
# having duplicates in the navigation.
|
42
|
+
#
|
12
43
|
# You can change the behavior with the following options, all of these are optional:
|
13
44
|
#
|
14
45
|
# ==== Options
|
15
|
-
# * <tt>:page</tt> - What page should be used as the current page. If this value is omitted,
|
16
|
-
#
|
17
|
-
#
|
46
|
+
# * <tt>:page</tt> - What page should be used as the current page. If this value is omitted,
|
47
|
+
# the value in @page will be used.
|
48
|
+
# * <tt>:path</tt> - This will be used to look up a section and that section will used to
|
49
|
+
# generate the menu structure. The current page will still be the value of the page option or
|
50
|
+
# @page. Note that this is the path to a section, not a path to a page.
|
18
51
|
# * <tt>:from_top</tt> - How many below levels from the root the tree should start at.
|
19
52
|
# All sections at this level will be shown. The default is 0, which means show all
|
20
|
-
#
|
53
|
+
# nodes that are direct children of the root
|
21
54
|
# * <tt>:depth</tt> - How many levels deep should the tree go, relative to from_top.
|
22
55
|
# If no value is supplied, the tree will go all the way down to the current page.
|
23
56
|
# If a value is supplied, the tree will be that many levels underneath from_top deep.
|
24
57
|
# * <tt>:limit</tt> - Limits the number of top-level elements that will be included in the list
|
25
|
-
# * <tt>:
|
26
|
-
#
|
27
|
-
#
|
58
|
+
# * <tt>:show_all_siblings</tt> - Passing true for this option will make all sibilings appear in
|
59
|
+
# the tree. The default is false, in which case only the siblings of nodes within the open
|
60
|
+
# path will appear.
|
28
61
|
#
|
29
62
|
# ==== Examples
|
30
63
|
#
|
@@ -32,89 +65,41 @@ module Cms
|
|
32
65
|
# with teams being a Page, everything else a Section. Also, assume we are on the
|
33
66
|
# Baltimore Ravens page. If you're not a footbal fan, see http://sports.yahoo.com/nfl/teams
|
34
67
|
#
|
35
|
-
#
|
36
|
-
# # =>
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# <li id="page_6">
|
51
|
-
# <a href="/cin">Cincinnati Bengals</a>
|
52
|
-
# </li>
|
53
|
-
# <li id="page_7">
|
54
|
-
# <a href="/cle">Cleveland Browns</a>
|
55
|
-
# </li>
|
56
|
-
# <li id="page_8" class="last">
|
57
|
-
# <a href="/pit">Pittsburgh Steelers</a>
|
58
|
-
# </li>
|
59
|
-
# </ul>
|
60
|
-
# </li>
|
61
|
-
# <li id="section_5">
|
62
|
-
# <a href="/hou">South</a>
|
63
|
-
# </li>
|
64
|
-
# <li id="section_6" class="last">
|
65
|
-
# <a href="/den">West</a>
|
66
|
-
# </li>
|
67
|
-
# </ul>
|
68
|
-
# </li>
|
69
|
-
# <li id="section_7" class="last">
|
70
|
-
# <a href="/dal">NFC</a>
|
71
|
-
# </li>
|
72
|
-
# </ul>
|
73
|
-
# </div>
|
68
|
+
# menu_items
|
69
|
+
# # => [
|
70
|
+
# { :id => "section_2", :url => "/buf", :name => "AFC", :children => [
|
71
|
+
# { :id => "section_3", :url => "/buf", :name => "East" },
|
72
|
+
# { :id => "section_4", :url => "/bal", :name => "North", :children => [
|
73
|
+
# { :id => "page_5", :selected => true, :url => "/bal", :name => "Baltimore Ravens" },
|
74
|
+
# { :id => "page_6", :url => "/cin", :name => "Cincinnati Bengals" },
|
75
|
+
# { :id => "page_7", :url => "/cle", :name => "Cleveland Browns" },
|
76
|
+
# { :id => "page_8", :url => "/pit", :name => "Pittsburgh Steelers" }
|
77
|
+
# ] },
|
78
|
+
# { :id => "section_9", :url => "/hou", :name => "South" },
|
79
|
+
# { :id => "section_10}", :url => "/den", :name => "West" }
|
80
|
+
# ] },
|
81
|
+
# { :id => "section_11", :url => "/dal", :name => "NFC" }
|
82
|
+
# ]
|
74
83
|
#
|
75
|
-
#
|
76
|
-
# # =>
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
# </li>
|
95
|
-
# <li id="section_7" class="last">
|
96
|
-
# <a href="/dal">NFC</a>
|
97
|
-
# <ul>
|
98
|
-
# <li id="section_8" class="first">
|
99
|
-
# <a href="/dal">East</a>
|
100
|
-
# </li>
|
101
|
-
# <li id="section_9">
|
102
|
-
# <a href="/chi">North</a>
|
103
|
-
# </li>
|
104
|
-
# <li id="section_10">
|
105
|
-
# <a href="/atl">South</a>
|
106
|
-
# </li>
|
107
|
-
# <li id="section_11" class="last">
|
108
|
-
# <a href="/ari">West</a>
|
109
|
-
# </li>
|
110
|
-
# </ul>
|
111
|
-
# </li>
|
112
|
-
# </ul>
|
113
|
-
# </div>
|
114
|
-
def render_menu(options={})
|
115
|
-
#Intialize parameters
|
116
|
-
page = options[:page] || @page
|
117
|
-
return nil unless page
|
84
|
+
# menu_items(:depth => 2, :show_all_siblings => true)
|
85
|
+
# # => [
|
86
|
+
# { :id => "section_2", :url => "/buf", :name => "AFC", :children => [
|
87
|
+
# { :id => "section_3", :url => "/buf", :name => "East" },
|
88
|
+
# { :id => "section_4", :url => "/bal", :name => "North" },
|
89
|
+
# { :id => "section_5", :url => "/hou", :name => "South" },
|
90
|
+
# { :id => "section_6", :url => "/den", :name => "West" }
|
91
|
+
# ] },
|
92
|
+
# { :id => "section_7", :url => "/dal", :name => "NFC", :children => [
|
93
|
+
# { :id => "section_8", :url => "/dal", :name => "East" },
|
94
|
+
# { :id => "section_9", :url => "/chi", :name => "North" },
|
95
|
+
# { :id => "section_10", :url => "/atl", :name => "South" },
|
96
|
+
# { :id => "section_11", :url => "/ari", :name => "West" }
|
97
|
+
# ] }
|
98
|
+
# ]
|
99
|
+
def menu_items(options = {})
|
100
|
+
# Intialize parameters
|
101
|
+
selected_page = options[:page] || @page
|
102
|
+
return nil unless selected_page
|
118
103
|
|
119
104
|
# Path to the section
|
120
105
|
if options.has_key?(:path)
|
@@ -122,65 +107,52 @@ module Cms
|
|
122
107
|
raise "Could not find section for path '#{options[:path]}'" unless section_for_path
|
123
108
|
ancestors = section_for_path.ancestors(:include_self => true)
|
124
109
|
else
|
125
|
-
ancestors =
|
110
|
+
ancestors = selected_page.ancestors
|
126
111
|
end
|
127
112
|
|
128
|
-
|
129
|
-
|
130
|
-
id = options[:id] || "menu"
|
131
|
-
css_class = options[:class] || "menu"
|
132
|
-
show_all_siblings = !!(options[:show_all_siblings])
|
133
|
-
limit = options[:limit]
|
134
|
-
|
135
|
-
html = "<div id=\"#{id}\" class=\"#{css_class}\">\n"
|
136
|
-
|
137
|
-
if from_top > ancestors.size
|
138
|
-
return html << "</div>\n"
|
139
|
-
else
|
140
|
-
ancestors = ancestors[from_top..-1]
|
113
|
+
if options.has_key?(:from_top)
|
114
|
+
ancestors = ancestors[options[:from_top].to_i..-1] || []
|
141
115
|
end
|
142
116
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
#Construct the CSS classes that the LI should have
|
151
|
-
classes = ["depth-#{d}"]
|
152
|
-
if i == 0
|
153
|
-
classes << "first"
|
154
|
-
elsif i == nodes.size-1
|
155
|
-
classes << "last"
|
156
|
-
end
|
157
|
-
classes << "open" if ancestors.include?(sn.node)
|
158
|
-
classes << "on" if page == sn.node
|
159
|
-
cls = classes.empty? ? nil : classes.join(" ")
|
117
|
+
depth = options.has_key?(:depth) ? options[:depth].to_i : 1.0/0
|
118
|
+
show_all_siblings = options[:show_all_siblings] || false
|
119
|
+
|
120
|
+
# We are defining a recursive lambda that takes the top-level sections
|
121
|
+
fn = lambda do |section_nodes, current_depth|
|
122
|
+
section_nodes.map do |section_node|
|
123
|
+
node = section_node.node
|
160
124
|
|
161
|
-
|
125
|
+
item = {}
|
126
|
+
item[:selected] = true if selected_page == node
|
127
|
+
item[:id] = "#{section_node.node_type.underscore}_#{section_node.node_id}"
|
162
128
|
|
163
|
-
#
|
164
|
-
|
165
|
-
#But if is a page, we call the first_page_or_link method
|
166
|
-
p = sn.node_type == "Section" ? sn.node.first_page_or_link : sn.node
|
167
|
-
html << %Q{<a href="#{p ? p.path : '#'}"#{(p.respond_to?(:new_window) && p.new_window?) ? ' target="_blank"' : ''}>#{sn.node.name}</a>\n}.indent(indent+6)
|
129
|
+
# If we are showing a section item, we want to use the path for the first page
|
130
|
+
page = section_node.section? ? node.first_page_or_link : node
|
168
131
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
#and also if the current depth is less than the target depth
|
173
|
-
if sn.node_type == "Section" && (show_all_siblings || ancestors.include?(sn.node)) && d < depth
|
174
|
-
fn.call(sn.node.visible_child_nodes, d+1)
|
175
|
-
end
|
132
|
+
item[:url] = page && page.path || '#'
|
133
|
+
item[:name] = node.name
|
134
|
+
item[:target] = "_blank" if page.respond_to?(:new_window?) && page.new_window?
|
176
135
|
|
177
|
-
|
136
|
+
# Now if this is a section, we do the child nodes,
|
137
|
+
# but only if the show_all_siblings parameter is true,
|
138
|
+
# or if this section is one of the current page's ancestors
|
139
|
+
# and also if the current depth is less than the target depth
|
140
|
+
if section_node.section? &&
|
141
|
+
current_depth < depth &&
|
142
|
+
(show_all_siblings || ancestors.include?(node)) &&
|
143
|
+
!node.visible_child_nodes.empty?
|
144
|
+
item[:children] = fn.call(node.visible_child_nodes, current_depth + 1)
|
145
|
+
end
|
178
146
|
|
147
|
+
item
|
179
148
|
end
|
180
|
-
html << "</ul>\n".indent(indent+2)
|
181
149
|
end
|
182
|
-
|
183
|
-
|
150
|
+
|
151
|
+
if ancestors.empty?
|
152
|
+
[]
|
153
|
+
else
|
154
|
+
fn.call(ancestors.first.visible_child_nodes(:limit => options[:limit]), 1)
|
155
|
+
end
|
184
156
|
end
|
185
157
|
end
|
186
|
-
end
|
158
|
+
end
|
@@ -14,7 +14,7 @@ module Cms
|
|
14
14
|
|
15
15
|
def container(name)
|
16
16
|
content = instance_variable_get("@content_for_#{name}")
|
17
|
-
if logged_in? && @page && @mode == "edit"
|
17
|
+
if logged_in? && @page && @mode == "edit" && current_user.able_to_edit?(@page)
|
18
18
|
render :partial => 'cms/pages/edit_container', :locals => {:name => name, :content => content}
|
19
19
|
else
|
20
20
|
content
|
@@ -65,4 +65,4 @@ module Cms
|
|
65
65
|
end
|
66
66
|
|
67
67
|
end
|
68
|
-
end
|
68
|
+
end
|
data/app/models/attachment.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'digest/sha1'
|
2
|
-
require '
|
2
|
+
require 'fileutils'
|
3
3
|
|
4
4
|
class Attachment < ActiveRecord::Base
|
5
5
|
|
@@ -116,7 +116,7 @@ class Attachment < ActiveRecord::Base
|
|
116
116
|
unless temp_file.blank?
|
117
117
|
FileUtils.mkdir_p File.dirname(full_file_location)
|
118
118
|
if temp_file.local_path
|
119
|
-
|
119
|
+
FileUtils.copy temp_file.local_path, full_file_location
|
120
120
|
else
|
121
121
|
open(full_file_location, 'w') {|f| f << temp_file.read }
|
122
122
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class ForgotPasswordMailer < ActionMailer::Base
|
2
|
+
|
3
|
+
def reset_password(link, email)
|
4
|
+
@subject = "Account Management"
|
5
|
+
@body[:url] = link
|
6
|
+
@recipients = email
|
7
|
+
@from = 'do_not_reply@domain.com'
|
8
|
+
@sent_on = Time.now
|
9
|
+
template "cms/forgot_password_mailer/reset_password"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/app/models/group.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
|
+
#
|
2
|
+
# A group represents a collection of permissions. Each User can be assigned to one or more groups, and the sum of
|
3
|
+
# their permissions from all groups combined represents what they can do.
|
4
|
+
#
|
1
5
|
class Group < ActiveRecord::Base
|
2
|
-
|
6
|
+
|
7
|
+
GUEST_CODE = "guest"
|
8
|
+
|
3
9
|
has_many :user_group_memberships
|
4
10
|
has_many :users, :through => :user_group_memberships
|
5
11
|
|
@@ -26,5 +32,10 @@ class Group < ActiveRecord::Base
|
|
26
32
|
def cms_access?
|
27
33
|
group_type && group_type.cms_access?
|
28
34
|
end
|
29
|
-
|
35
|
+
|
36
|
+
# Finds the guest group, which is a special group that represents public non-logged in users.
|
37
|
+
def self.guest
|
38
|
+
with_code(GUEST_CODE).first
|
39
|
+
end
|
40
|
+
|
30
41
|
end
|
data/app/models/guest_user.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
+
#
|
2
|
+
# Guests are a special user that represents a non-logged in user. The main reason to create an explicit
|
3
|
+
# instance of this type of user is so that the permissions a Guest user can have can be set via the Admin interface.
|
4
|
+
#
|
5
|
+
# Every request that a non-logged in user makes will use this User's permissions to determine what they can/can't do.
|
6
|
+
#
|
1
7
|
class GuestUser < User
|
2
|
-
|
8
|
+
|
3
9
|
def initialize(attributes={})
|
4
|
-
super({:login =>
|
10
|
+
super({:login => Group::GUEST_CODE, :first_name => "Anonymous", :last_name => "User"}.merge(attributes))
|
5
11
|
@guest = true
|
6
12
|
end
|
7
13
|
|
@@ -18,7 +24,7 @@ class GuestUser < User
|
|
18
24
|
end
|
19
25
|
|
20
26
|
def group
|
21
|
-
@group ||= Group.
|
27
|
+
@group ||= Group.guest
|
22
28
|
end
|
23
29
|
|
24
30
|
def groups
|
data/app/models/link.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Link < ActiveRecord::Base
|
2
|
-
acts_as_content_block
|
2
|
+
acts_as_content_block :connectable => false
|
3
3
|
|
4
4
|
named_scope :named, lambda{|name| {:conditions => ['links.name = ?', name]}}
|
5
5
|
|
@@ -32,4 +32,4 @@ class Link < ActiveRecord::Base
|
|
32
32
|
url
|
33
33
|
end
|
34
34
|
|
35
|
-
end
|
35
|
+
end
|
data/app/models/page.rb
CHANGED
@@ -150,7 +150,7 @@ class Page < ActiveRecord::Base
|
|
150
150
|
|
151
151
|
def delete_connectors
|
152
152
|
connectors.for_page_version(version).all.each{|c| c.destroy }
|
153
|
-
end
|
153
|
+
end
|
154
154
|
|
155
155
|
#This is done to let copy_connectors know which version to pull from
|
156
156
|
#copy_connectors will get called later as an after_update callback
|
data/app/models/section.rb
CHANGED
@@ -75,7 +75,12 @@ class Section < ActiveRecord::Base
|
|
75
75
|
ancs = node ? node.ancestors : []
|
76
76
|
options[:include_self] ? ancs + [self] : ancs
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
|
+
def with_ancestors(options = {})
|
80
|
+
options.merge! :include_self => true
|
81
|
+
self.ancestors(options)
|
82
|
+
end
|
83
|
+
|
79
84
|
def move_to(section)
|
80
85
|
if root?
|
81
86
|
false
|
@@ -139,4 +144,4 @@ class Section < ActiveRecord::Base
|
|
139
144
|
end
|
140
145
|
end
|
141
146
|
|
142
|
-
end
|
147
|
+
end
|