Module: JekyllThemeGuidesMbland::NavigationMenu

Defined in:
lib/jekyll-theme-guides-mbland/navigation.rb

Class Method Summary collapse

Class Method Details

.apply_nav_update(url, nav, nav_data, original) ⇒ Object


217
218
219
220
221
222
223
224
225
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 217

def self.apply_nav_update(url, nav, nav_data, original)
  orig = original[url]
  if orig.nil?
    apply_new_nav_item(url, nav, nav_data, original)
  else
    orig['text'] = nav['text']
    orig.delete('generated')
  end
end

.apply_new_nav_item(url, nav, nav_data, original) ⇒ Object


227
228
229
230
231
232
233
234
235
236
237
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 227

def self.apply_new_nav_item(url, nav, nav_data, original)
  parent_url = File.dirname(url || '/')
  parent = original["#{parent_url}/"]
  if parent_url == '/'
    nav_data << (original[url] = nav)
  elsif parent.nil?
    nav_data << nav.merge(orphan_url: url)
  else
    (parent['children'] ||= []) << nav
  end
end

.check_for_orphaned_items(nav_data) ⇒ Object

Raises:

  • (StandardError)

239
240
241
242
243
244
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 239

def self.check_for_orphaned_items(nav_data)
  orphan_urls = nav_data.map { |nav| nav[:orphan_url] }.compact
  return if orphan_urls.empty?
  raise StandardError, "Parent pages missing for the following:\n  " +
    orphan_urls.join("\n  ")
end

.map_nav_items_by_url(parent_url, nav_data) ⇒ Object


169
170
171
172
173
174
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 169

def self.map_nav_items_by_url(parent_url, nav_data)
  nav_data.flat_map do |nav|
    url = File.join('', parent_url, nav['url'] || '')
    [[url, nav]].concat(map_nav_items_by_url(url, nav['children'] || []))
  end
end

185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 185

def self.page_nav(front_matter)
  url_components = front_matter['permalink'].split('/')[1..-1]
  result = {
    'text' => front_matter['navtitle'] || front_matter['title'],
    'url' => "#{url_components.nil? ? '' : url_components.last}/",
    'internal' => true,
  }
  # Delete the root URL so we don't have an empty `url:` property laying
  # around.
  result.delete 'url' if result['url'] == '/'
  result
end

.remove_stale_children(parent) ⇒ Object


210
211
212
213
214
215
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 210

def self.remove_stale_children(parent)
  children = (parent['children'] || [])
  children.delete_if { |nav| nav['delete'] }
  parent.delete 'children' if children.empty?
  children.each { |child| remove_stale_children(child) }
end

.remove_stale_nav_entries(nav_data, original, updated) ⇒ Object


198
199
200
201
202
203
204
205
206
207
208
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 198

def self.remove_stale_nav_entries(nav_data, original, updated)
  # Remove old entries whose pages have been deleted
  original.each do |url, nav|
    if !updated.member?(url) && nav['internal'] && !nav['generated']
      nav['delete'] = true
    end
  end
  original.delete_if { |_url, nav| nav['delete'] }
  nav_data.delete_if { |nav| nav['delete'] }
  nav_data.each { |nav| remove_stale_children(nav) }
end

.update_navigation_data(nav_data, basedir, config_data) ⇒ Object


157
158
159
160
161
162
163
164
165
166
167
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 157

def self.update_navigation_data(nav_data, basedir, config_data)
  original = map_nav_items_by_url('/', nav_data).to_h
  updated = updated_nav_data(basedir)
  remove_stale_nav_entries(nav_data, original, updated)
  updated.map { |url, nav| apply_nav_update(url, nav, nav_data, original) }
  if config_data['generate_nodes']
    GeneratedNodes.create_homes_for_orphans(original, nav_data)
  else
    check_for_orphaned_items(nav_data)
  end
end

.updated_nav_data(basedir) ⇒ Object


176
177
178
179
180
181
182
183
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 176

def self.updated_nav_data(basedir)
  front_matter = FrontMatter.load basedir
  errors = FrontMatter.validate_with_message_upon_error front_matter
  abort errors + "\n_config.yml not updated" if errors
  front_matter
    .values.sort_by { |fm| fm['permalink'] }
    .map { |fm| [fm['permalink'], page_nav(fm)] }.to_h
end

.validate_existing_data(nav_data) ⇒ Object


139
140
141
142
143
144
145
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 139

def self.validate_existing_data(nav_data)
  errors = []
  validate_existing_data_impl(nav_data, errors)
  err_msg = "Existing navigation entries contain errors:\n  " +
    errors.join("\n  ") + "\n_config.yml not updated"
  abort err_msg unless errors.empty?
end

.validate_existing_data_impl(nav_data, errors) ⇒ Object


147
148
149
150
151
152
153
154
155
# File 'lib/jekyll-theme-guides-mbland/navigation.rb', line 147

def self.validate_existing_data_impl(nav_data, errors)
  nav_data.each do |nav|
    if !nav['internal'] && nav['children']
      errors << "#{nav['text']}: external navigation URLs " \
        'cannot have children'
    end
    validate_existing_data_impl(nav['children'] || [], errors)
  end
end