Class: Middleman::NavTree::NavTreeExtension

Inherits:
Extension
  • Object
show all
Defined in:
lib/middleman-navtree/extension.rb

Overview

Extension namespace @todo: Test the extension against a vanilla Middleman install. @todo: Test the extension against a middleman-blog install.

Instance Method Summary collapse

Constructor Details

#initialize(app, options_hash = {}, &block) ⇒ NavTreeExtension

Returns a new instance of NavTreeExtension.



23
24
25
26
27
28
29
30
31
32
33
# 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

Instance Method Details

#after_configurationObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 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.settings.js_dir
  options.ignore_dir << app.settings.css_dir
  options.ignore_dir << app.settings.fonts_dir
  options.ignore_dir << app.settings.images_dir
  options.ignore_dir << app.settings.helpers_dir
  options.ignore_dir << app.settings.layouts_dir
  options.ignore_dir << app.settings.partials_dir

  # Build a hash out of our directory information
  tree_hash = scan_directory(app.settings.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.settings.data_dir)

    data_path = app.settings.data_dir + '/' + options.data_file
    IO.write(data_path, YAML::dump(tree_hash))
  end
end

#promote_files(tree_hash, options) ⇒ Object

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.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# 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) ⇒ Object

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/



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# 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.settings.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.settings.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