Module: Slices::Tree

Extended by:
ActiveSupport::Concern
Included in:
Page
Defined in:
lib/slices/tree.rb

Overview

Containers the tree behaviour.

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#external_urlString

An optional url override for the page, if this is set then this page will link to the url in any navigation block. Usefull when linking to a different website.



# File 'lib/slices/tree.rb', line 13


#pathString

The path for the page, this is a unique identifier and directly maps to the page’s url.



# File 'lib/slices/tree.rb', line 7


#positionInteger

The page’s position amongst it’s siblings



# File 'lib/slices/tree.rb', line 20


#show_in_navBoolean

If the page should be shown in any navigation block.



# File 'lib/slices/tree.rb', line 25


Class Method Details

.minimalMongoid::Criteria

A scope with the minmial attributes needed to render navigaiton



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/slices/tree.rb', line 36

included do
  field :path
  field :external_url, type: String, default: ''
  field :position, type: Integer
  field :show_in_nav, type: Boolean, default: false

  scope :minimal, only: %w(page_id path external_url name has_content)
  index :path

  belongs_to :page

  attr_accessor :parent_id

  before_create :ensure_path_unique
  before_save :ensure_path_unique
end

Instance Method Details

#ancestorsArray<Page>

A list of the page’s ancestors



128
129
130
131
132
133
134
135
136
# File 'lib/slices/tree.rb', line 128

def ancestors
  ancestors = []
  parent_page = parent
  while parent_page
    ancestors << parent_page
    parent_page = parent_page.parent
  end
  ancestors
end

#childrenMongoid::Criteria

A list of pages descended from this page ordered by position



120
121
122
# File 'lib/slices/tree.rb', line 120

def children
  Page.where(page_id: self.id).ascending(:position)
end

#descended_from?(page) ⇒ Boolean

Is the current page a descendant of page



142
143
144
# File 'lib/slices/tree.rb', line 142

def descended_from?(page)
  ancestors.include?(page)
end

#entry_childrenMongoid::Criteria

A list of children which are neither Page or SetPage



240
241
242
# File 'lib/slices/tree.rb', line 240

def entry_children
  children.where(:_type.nin => ['Page', 'SetPage'])
end

#first_sibling?Boolean

Is this page the first child of its parent



200
201
202
# File 'lib/slices/tree.rb', line 200

def first_sibling?
  parent.nil? ? false : peers.first == self
end

#generate_pathString

Generate a new path for the page, using it’s parent’s path and the permalink.



262
263
264
265
266
267
268
# File 'lib/slices/tree.rb', line 262

def generate_path
  unless home?
    File.join(parent.path, permalink)
  else
    '/'
  end
end

#home?Boolean

Is this page the home page



112
113
114
# File 'lib/slices/tree.rb', line 112

def home?
  path == '/'
end

#last_sibling?Boolean

Is this page the last child of its parent



206
207
208
# File 'lib/slices/tree.rb', line 206

def last_sibling?
  parent.nil? ? false : peers.last == self
end

A list of child pages which have both active and show_in_nav set to true. Only the attributes needed to render #navigation are returned, these are: page_id, path, external_url, name and has_content.



169
170
171
# File 'lib/slices/tree.rb', line 169

def navigable_children
  page_children.minimal.where(active: true, show_in_nav: true)
end

The navigaiton path for a page, the navigation differers from path in a few important ways. If #external_url is set then it is returned. If the page has no content and children then the path of it’s first child is returned



153
154
155
156
157
158
159
160
161
# File 'lib/slices/tree.rb', line 153

def navigation_path
  if external_url?
    external_url
  elsif home? || has_content?
    path
  else
    navigable_children.first ? navigable_children.first.path : path
  end
end

#next_siblingPage

The next page(of the parent’s active children), or nil if this is the last page.



224
225
226
# File 'lib/slices/tree.rb', line 224

def next_sibling
  peers[index_in_peers + 1]
end

#page_childrenMongoid::Criteria

A list of children which are either Page or SetPage



232
233
234
# File 'lib/slices/tree.rb', line 232

def page_children
  children.where(:_type.in => [nil, 'Page', 'SetPage'])
end

#parentPage

Get the parent page.



97
98
99
# File 'lib/slices/tree.rb', line 97

def parent
  page
end

#parent=(page) ⇒ Page

Set the parent.



106
107
108
# File 'lib/slices/tree.rb', line 106

def parent=(page)
  self.page = page
end

#peersMongoid::Criteria

The parent pages’s navigable children, including this page



177
178
179
# File 'lib/slices/tree.rb', line 177

def peers
  parent.nil? ? [] : parent.navigable_children
end

The permalink for the page



274
275
276
277
278
279
280
# File 'lib/slices/tree.rb', line 274

def permalink
  if path
    File.basename(path)
  else
    name.to_url
  end
end

#previous_siblingPage

The previous page(of the parent’s active children), or nil if this is the first page.



215
216
217
# File 'lib/slices/tree.rb', line 215

def previous_sibling
  index_in_peers < 1 ? nil : peers[index_in_peers - 1]
end

#siblingsMongoid::Criteria

An array of the parent page’s children excluding this page



185
186
187
# File 'lib/slices/tree.rb', line 185

def siblings
  parent.nil? ? [] : parent.children.where(:_id.nin => [id])
end

#siblings_by_positionMongoid::Criteria

An array of the parent page’s children excluding this page, ordered by position



194
195
196
# File 'lib/slices/tree.rb', line 194

def siblings_by_position
  siblings.ascending(:position)
end

#update_path_for_childrenMongoid::Criteria

Recusivly decend from this page and update each descendants path, useful when changing permalinks.



249
250
251
252
253
254
255
# File 'lib/slices/tree.rb', line 249

def update_path_for_children
  children.each do |child|
    child.path = child.generate_path
    child.save!
    child.update_path_for_children
  end
end