module Slices::Tree
Containers the tree behaviour.
Public Instance Methods
A list of the page's ancestors
@return [Array<Page>]
# File lib/slices/tree.rb, line 130 def ancestors ancestors = [] parent_page = parent while parent_page ancestors << parent_page parent_page = parent_page.parent end ancestors end
A list of pages descended from this page ordered by position
@return [Mongoid::Criteria]
# File lib/slices/tree.rb, line 122 def children Page.where(page_id: self.id).ascending(:position) end
Is the current page a descendant of page
@param [Page] page
# File lib/slices/tree.rb, line 144 def descended_from?(page) ancestors.include?(page) end
A list of children which are neither {Page} or {SetPage}
@return [Mongoid::Criteria]
# File lib/slices/tree.rb, line 242 def entry_children children.where(:_type.nin => ['Page', 'SetPage']) end
Is this page the first child of its parent
# File lib/slices/tree.rb, line 202 def first_sibling? parent.nil? ? false : peers.first == self end
Generate a new path
for the page, using it's parent's path and the permalink.
@return [String]
# File lib/slices/tree.rb, line 264 def generate_path unless home? File.join(parent.path, permalink) else '/' end end
Is this page the home page
# File lib/slices/tree.rb, line 114 def home? path == '/' end
Is this page the last child of its parent
# File lib/slices/tree.rb, line 208 def last_sibling? parent.nil? ? false : peers.last == self end
The next page(of the parent's active children), or nil if this is the last page.
@return [Page]
# File lib/slices/tree.rb, line 226 def next_sibling peers[index_in_peers + 1] end
A list of children which are either {Page} or {SetPage}
@return [Mongoid::Criteria]
# File lib/slices/tree.rb, line 234 def page_children children.where(:_type.in => [nil, 'Page', 'SetPage']) end
Get the parent page.
@return [Page]
# File lib/slices/tree.rb, line 99 def parent page end
Set the parent.
@param [Page] page The new parent @return [Page]
# File lib/slices/tree.rb, line 108 def parent=(page) self.page = page end
The parent pages's navigable children, including this page
@return [Mongoid::Criteria]
# File lib/slices/tree.rb, line 179 def peers parent.nil? ? [] : parent.navigable_children end
The permalink for the page
@return [String]
# File lib/slices/tree.rb, line 276 def permalink if path File.basename(path) else name.to_url end end
Don't store permalink
@return nil
# File lib/slices/tree.rb, line 288 def permalink=(args) end
The previous page(of the parent's active children), or nil if this is the first page.
@return [Page]
# File lib/slices/tree.rb, line 217 def previous_sibling index_in_peers < 1 ? nil : peers[index_in_peers - 1] end
An array of the parent page's children excluding this page
@return [Mongoid::Criteria]
# File lib/slices/tree.rb, line 187 def siblings parent.nil? ? [] : parent.children.where(:_id.nin => [id]) end
An array of the parent page's children excluding this page, ordered by position
@return [Mongoid::Criteria]
# File lib/slices/tree.rb, line 196 def siblings_by_position siblings.ascending(:position) end
Recusivly decend from this page and update each descendants path, useful when changing permalinks.
@return [Mongoid::Criteria]
# File lib/slices/tree.rb, line 251 def update_path_for_children children.each do |child| child.path = child.generate_path child.save! child.update_path_for_children end end
Private Instance Methods
Make sure that a page's path is unique amoungst it's siblings, if there is a dupliacation then -1
is appended
@return [void]
# File lib/slices/tree.rb, line 298 def ensure_path_unique if parent.present? && path_changed? matching_paths = siblings.where(path: /#{path}(-\d+)?$/) if matching_paths.any? self.path << "-#{matching_paths.length}" end end end
The page's position amoung it's peers
@return [Integer]
# File lib/slices/tree.rb, line 311 def index_in_peers parent.nil? ? 0 : peers.only(:id).entries.index(self) end