class Middleman::NavTree::NavTreeExtension
Extension namespace @todo: Test the extension against a vanilla Middleman
install. @todo: Test the extension against a middleman-blog install.
Public Class Methods
new(app, options_hash={}, &block)
click to toggle source
Calls superclass method
# File lib/middleman-navtree/extension.rb, line 23 def initialize(app, options_hash={}, &block) # Call super to build options from the options_hash super # Require libraries only when activated require 'yaml' require 'titleize' @existing_promotes = [] end
Public Instance Methods
after_configuration()
click to toggle source
# File lib/middleman-navtree/extension.rb, line 35 def after_configuration # Add the user's config directories to the "ignore_dir" option because # these are all things we won't need printed in a NavTree. options.ignore_dir << app.config[:js_dir] options.ignore_dir << app.config[:css_dir] options.ignore_dir << app.config[:fonts_dir] options.ignore_dir << app.config[:images_dir] options.ignore_dir << app.config[:helpers_dir] options.ignore_dir << app.config[:layouts_dir] options.ignore_dir << app.config[:partials_dir] # Build a hash out of our directory information tree_hash = scan_directory(app.config[:source], options) # Promote any promoted files to the beginning of our hash. tree_hash = promote_files(tree_hash, options) # Write our directory tree to file as YAML. # @todo: This step doesn't rebuild during live-reload, which causes errors if you move files # around during development. It may not be that hard to set up. Low priority though. if options.automatic_tree_updates FileUtils.mkdir_p(app.config[:data_dir]) data_path = app.config[:data_dir] + '/' + options.data_file IO.write(data_path, YAML::dump(tree_hash)) end end
promote_files(tree_hash, options)
click to toggle source
Method for appending promoted files to the front of our source tree. @todo: Currently, options.promote_files only expects a filename, which means that
if multiple files in different directories have the same filename, they will both be promoted, and one will not appear (due to the 'no-two-identical -indices-in-a-hash' rule).
@todo: This system also assumes filenames only have a single extension,
which may not be the case (like index.html.erb)
@todo: Basically, this is not elegent at all.
# File lib/middleman-navtree/extension.rb, line 116 def promote_files(tree_hash, options) if @existing_promotes.any? ordered_matches = [] # The purpose of this loop is to get my list of existing promotes # in the order specified in the options array, so it can be promoted # properly. options.promote_files.each do |filename| # Get filename without extension (index.md => index) filename_without_ext = filename.chomp(File.extname(filename)) # Test against each existing_promote, and store matches @existing_promotes.each do |pathname| # Get another filename without extension from the pathname (/book/index.html => index) pathname_without_ext = File.basename(pathname, ".*") # Add matches to our ordered matches array. if filename_without_ext == pathname_without_ext ordered_matches << [filename, pathname] end end end # Promote all files found in both the promotes list and the file structure. This is an array # of arrays ordered_matches.reverse.each do |match| tree_hash = Hash[match[0], match[1]].merge!(tree_hash) end end return tree_hash end
scan_directory(path, options, name=nil)
click to toggle source
Method for storing the directory structure in an ordered hash. See more on ordered hashes at www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/
# File lib/middleman-navtree/extension.rb, line 66 def scan_directory(path, options, name=nil) data = {} Dir.foreach(path) do |filename| # Check to see if we should skip this file. We skip invisible files # (starts with "."), ignored files, and promoted files (which are # handled later in the process). next if (filename[0] == '.') next if (filename == '..' || filename == '.') next if options.ignore_files.include? filename if options.promote_files.include? filename original_path = path.sub(/^#{app.config[:source]}/, '') + '/' + filename @existing_promotes << original_path next end full_path = File.join(path, filename) if File.directory?(full_path) # This item is a directory. # Check to see if we should ignore this directory. next if options.ignore_dir.include? filename # Loop through the method again. data.store(filename.gsub(' ', '%20'), scan_directory(full_path, options, filename)) else # This item is a file. if !options.ext_whitelist.empty? # Skip any whitelisted extensions. next unless options.ext_whitelist.include? File.extname(filename) end original_path = path.sub(/^#{app.config[:source]}/, '') + '/' + filename data.store(filename.gsub(' ', '%20'), original_path.gsub(' ', '%20')) end end # Return this level's data as a hash sorted by keys. return Hash[data.sort] end