module GuidesStyle18F::FrontMatter
Constants
- EXTNAMES
Public Class Methods
load(basedir)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 12 def self.load(basedir) # init_file_to_front_matter_map is initializing the map with a nil value # for every file that _should_ contain front matter as far as the # navigation menu is concerned. Any nil values that remain after merging # with the site_file_to_front_matter map will result in a validation # error. init_file_to_front_matter_map(basedir).merge( site_file_to_front_matter(init_site(basedir))) end
validate(front_matter)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 33 def self.validate(front_matter) front_matter.map do |file, data| next [file, ['no front matter defined']] if data.nil? errors = missing_property_errors(data) + permalink_errors(data) [file, errors] unless errors.empty? end.compact.to_h end
validate_with_message_upon_error(front_matter)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 22 def self.validate_with_message_upon_error(front_matter) files_with_errors = validate front_matter return if files_with_errors.empty? message = ['The following files have errors in their front matter:'] files_with_errors.each do |file, errors| message << " #{file}:" message.concat errors.map { |error| " #{error}" } end message.join "\n" unless message.size == 1 end
Private Class Methods
adjust_config_paths(basedir, config)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 54 def self.adjust_config_paths(basedir, config) source = config['source'] config['source'] = source.nil? ? basedir : File.join(basedir, source) destination = config['destination'] destination = '_site' if destination.nil? config['destination'] = File.join(basedir, destination) end
init_file_to_front_matter_map(basedir)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 89 def self.init_file_to_front_matter_map(basedir) file_to_front_matter = {} Dir.chdir(basedir) do pages_dir = Dir.exist?('_pages') ? '_pages' : 'pages' Dir[File.join(pages_dir, '**', '*')].each do |file_name| extname = File.extname(file_name) next unless File.file?(file_name) && EXTNAMES.include?(extname) file_to_front_matter[file_name] = nil end end file_to_front_matter end
init_site(basedir)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 43 def self.init_site(basedir) Dir.chdir(basedir) do config = SafeYAML.load_file('_config.yml', safe: true) adjust_config_paths(basedir, config) site = Jekyll::Site.new(Jekyll.configuration(config)) site.reset site.read site end end
missing_property_errors(data)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 102 def self.missing_property_errors(data) properties = %w(title permalink) properties.map { |p| "no `#{p}:` property" if data[p].nil? }.compact end
permalink_errors(data)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 107 def self.permalink_errors(data) pl = data['permalink'] return [] if pl.nil? errors = [] errors << "`permalink:` does not begin with '/'" unless pl.start_with? '/' errors << "`permalink:` does not end with '/'" unless pl.end_with? '/' errors end
site_file_to_front_matter(site)
click to toggle source
# File lib/guides_style_18f/navigation.rb, line 62 def self.site_file_to_front_matter(site) site_pages(site).map do |page| [page.relative_path, page.data] end.to_h end
site_pages(site)
click to toggle source
We're supporting two possible configurations:
-
a `pages/` directory in which documents appear as part of the regular site.pages collection; we have to filter by page.relative_path, and we do not assign a permalink so that validation (in a later step) will ensure that each page has a permalink assigned
-
an actual `pages` collection, stored in a `_pages` directory; no filtering is necessary, and we can reliably set the permalink to page.url as a default
# File lib/guides_style_18f/navigation.rb, line 78 def self.site_pages(site) pages = site.collections['pages'] if pages.nil? site.pages.select do |page| page.relative_path.start_with?('/pages') || page.url == '/' end else pages.docs.each { |page| page.data['permalink'] ||= page.url } end end