Module: GuidesStyle18F::NavigationMenu

Defined in:
lib/guides_style_18f/navigation.rb

Class Method Summary collapse

Class Method Details

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



192
193
194
195
196
197
198
199
200
# File 'lib/guides_style_18f/navigation.rb', line 192

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



202
203
204
205
206
207
208
209
210
211
212
# File 'lib/guides_style_18f/navigation.rb', line 202

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



214
215
216
217
218
219
220
# File 'lib/guides_style_18f/navigation.rb', line 214

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

.map_nav_items_by_url(parent_url, nav_data) ⇒ Object



145
146
147
148
149
150
# File 'lib/guides_style_18f/navigation.rb', line 145

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


160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/guides_style_18f/navigation.rb', line 160

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



185
186
187
188
189
190
# File 'lib/guides_style_18f/navigation.rb', line 185

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



173
174
175
176
177
178
179
180
181
182
183
# File 'lib/guides_style_18f/navigation.rb', line 173

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



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/guides_style_18f/navigation.rb', line 133

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



152
153
154
155
156
157
158
# File 'lib/guides_style_18f/navigation.rb', line 152

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