bridgetown-core 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +42 -0
  3. data/bridgetown-core.gemspec +46 -0
  4. data/lib/bridgetown-core.rb +202 -0
  5. data/lib/bridgetown-core/cache.rb +190 -0
  6. data/lib/bridgetown-core/cleaner.rb +111 -0
  7. data/lib/bridgetown-core/collection.rb +279 -0
  8. data/lib/bridgetown-core/command.rb +106 -0
  9. data/lib/bridgetown-core/commands/build.rb +96 -0
  10. data/lib/bridgetown-core/commands/clean.rb +43 -0
  11. data/lib/bridgetown-core/commands/console.rb +56 -0
  12. data/lib/bridgetown-core/commands/doctor.rb +172 -0
  13. data/lib/bridgetown-core/commands/help.rb +34 -0
  14. data/lib/bridgetown-core/commands/new.rb +148 -0
  15. data/lib/bridgetown-core/commands/serve.rb +273 -0
  16. data/lib/bridgetown-core/commands/serve/servlet.rb +68 -0
  17. data/lib/bridgetown-core/configuration.rb +323 -0
  18. data/lib/bridgetown-core/converter.rb +54 -0
  19. data/lib/bridgetown-core/converters/identity.rb +39 -0
  20. data/lib/bridgetown-core/converters/markdown.rb +108 -0
  21. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +132 -0
  22. data/lib/bridgetown-core/converters/smartypants.rb +69 -0
  23. data/lib/bridgetown-core/convertible.rb +237 -0
  24. data/lib/bridgetown-core/deprecator.rb +50 -0
  25. data/lib/bridgetown-core/document.rb +475 -0
  26. data/lib/bridgetown-core/drops/bridgetown_drop.rb +32 -0
  27. data/lib/bridgetown-core/drops/collection_drop.rb +20 -0
  28. data/lib/bridgetown-core/drops/document_drop.rb +69 -0
  29. data/lib/bridgetown-core/drops/drop.rb +215 -0
  30. data/lib/bridgetown-core/drops/excerpt_drop.rb +19 -0
  31. data/lib/bridgetown-core/drops/page_drop.rb +14 -0
  32. data/lib/bridgetown-core/drops/site_drop.rb +62 -0
  33. data/lib/bridgetown-core/drops/static_file_drop.rb +14 -0
  34. data/lib/bridgetown-core/drops/unified_payload_drop.rb +26 -0
  35. data/lib/bridgetown-core/drops/url_drop.rb +132 -0
  36. data/lib/bridgetown-core/entry_filter.rb +108 -0
  37. data/lib/bridgetown-core/errors.rb +20 -0
  38. data/lib/bridgetown-core/excerpt.rb +202 -0
  39. data/lib/bridgetown-core/external.rb +62 -0
  40. data/lib/bridgetown-core/filters.rb +467 -0
  41. data/lib/bridgetown-core/filters/date_filters.rb +110 -0
  42. data/lib/bridgetown-core/filters/grouping_filters.rb +64 -0
  43. data/lib/bridgetown-core/filters/url_filters.rb +79 -0
  44. data/lib/bridgetown-core/frontmatter_defaults.rb +238 -0
  45. data/lib/bridgetown-core/generator.rb +5 -0
  46. data/lib/bridgetown-core/hooks.rb +103 -0
  47. data/lib/bridgetown-core/layout.rb +57 -0
  48. data/lib/bridgetown-core/liquid_extensions.rb +22 -0
  49. data/lib/bridgetown-core/liquid_renderer.rb +71 -0
  50. data/lib/bridgetown-core/liquid_renderer/file.rb +67 -0
  51. data/lib/bridgetown-core/liquid_renderer/table.rb +75 -0
  52. data/lib/bridgetown-core/log_adapter.rb +151 -0
  53. data/lib/bridgetown-core/log_writer.rb +60 -0
  54. data/lib/bridgetown-core/mime.types +867 -0
  55. data/lib/bridgetown-core/page.rb +214 -0
  56. data/lib/bridgetown-core/page_without_a_file.rb +14 -0
  57. data/lib/bridgetown-core/path_manager.rb +31 -0
  58. data/lib/bridgetown-core/plugin.rb +80 -0
  59. data/lib/bridgetown-core/plugin_manager.rb +60 -0
  60. data/lib/bridgetown-core/publisher.rb +23 -0
  61. data/lib/bridgetown-core/reader.rb +185 -0
  62. data/lib/bridgetown-core/readers/collection_reader.rb +22 -0
  63. data/lib/bridgetown-core/readers/data_reader.rb +75 -0
  64. data/lib/bridgetown-core/readers/layout_reader.rb +48 -0
  65. data/lib/bridgetown-core/readers/page_reader.rb +24 -0
  66. data/lib/bridgetown-core/readers/post_reader.rb +74 -0
  67. data/lib/bridgetown-core/readers/static_file_reader.rb +24 -0
  68. data/lib/bridgetown-core/regenerator.rb +195 -0
  69. data/lib/bridgetown-core/related_posts.rb +52 -0
  70. data/lib/bridgetown-core/renderer.rb +261 -0
  71. data/lib/bridgetown-core/site.rb +469 -0
  72. data/lib/bridgetown-core/static_file.rb +205 -0
  73. data/lib/bridgetown-core/tags/component.rb +34 -0
  74. data/lib/bridgetown-core/tags/highlight.rb +111 -0
  75. data/lib/bridgetown-core/tags/include.rb +220 -0
  76. data/lib/bridgetown-core/tags/link.rb +41 -0
  77. data/lib/bridgetown-core/tags/post_url.rb +107 -0
  78. data/lib/bridgetown-core/url.rb +164 -0
  79. data/lib/bridgetown-core/utils.rb +367 -0
  80. data/lib/bridgetown-core/utils/ansi.rb +57 -0
  81. data/lib/bridgetown-core/utils/exec.rb +26 -0
  82. data/lib/bridgetown-core/utils/internet.rb +37 -0
  83. data/lib/bridgetown-core/utils/platforms.rb +80 -0
  84. data/lib/bridgetown-core/utils/thread_event.rb +31 -0
  85. data/lib/bridgetown-core/utils/win_tz.rb +75 -0
  86. data/lib/bridgetown-core/version.rb +5 -0
  87. data/lib/bridgetown-core/watcher.rb +139 -0
  88. data/lib/site_template/.gitignore +6 -0
  89. data/lib/site_template/bridgetown.config.yml +21 -0
  90. data/lib/site_template/frontend/javascript/index.js +3 -0
  91. data/lib/site_template/frontend/styles/index.scss +17 -0
  92. data/lib/site_template/package.json +23 -0
  93. data/lib/site_template/src/404.html +9 -0
  94. data/lib/site_template/src/_data/site_metadata.yml +11 -0
  95. data/lib/site_template/src/_includes/footer.html +3 -0
  96. data/lib/site_template/src/_includes/head.html +9 -0
  97. data/lib/site_template/src/_includes/navbar.html +4 -0
  98. data/lib/site_template/src/_layouts/default.html +15 -0
  99. data/lib/site_template/src/_layouts/home.html +7 -0
  100. data/lib/site_template/src/_layouts/page.html +7 -0
  101. data/lib/site_template/src/_layouts/post.html +7 -0
  102. data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +26 -0
  103. data/lib/site_template/src/about.md +11 -0
  104. data/lib/site_template/src/index.md +7 -0
  105. data/lib/site_template/webpack.config.js +60 -0
  106. data/rake/release.rake +30 -0
  107. metadata +106 -1
@@ -0,0 +1,214 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Page
5
+ include Convertible
6
+
7
+ attr_writer :dir
8
+ attr_accessor :site, :pager
9
+ attr_accessor :name, :ext, :basename
10
+ attr_accessor :data, :content, :output
11
+
12
+ alias_method :extname, :ext
13
+
14
+ # Attributes for Liquid templates
15
+ ATTRIBUTES_FOR_LIQUID = %w(
16
+ content
17
+ dir
18
+ name
19
+ path
20
+ url
21
+ ).freeze
22
+
23
+ # A set of extensions that are considered HTML or HTML-like so we
24
+ # should not alter them, this includes .xhtml through XHTM5.
25
+
26
+ HTML_EXTENSIONS = %w(
27
+ .html
28
+ .xhtml
29
+ .htm
30
+ ).freeze
31
+
32
+ # Initialize a new Page.
33
+ #
34
+ # site - The Site object.
35
+ # base - The String path to the source.
36
+ # dir - The String path between the source and the file.
37
+ # name - The String filename of the file.
38
+ def initialize(site, base, dir, name)
39
+ @site = site
40
+ @base = base
41
+ @dir = dir
42
+ @name = name
43
+ @path = site.in_source_dir(base, dir, name)
44
+
45
+ process(name)
46
+ read_yaml(PathManager.join(base, dir), name)
47
+
48
+ data.default_proc = proc do |_, key|
49
+ site.frontmatter_defaults.find(relative_path, type, key)
50
+ end
51
+
52
+ Bridgetown::Hooks.trigger :pages, :post_init, self
53
+ end
54
+
55
+ # The generated directory into which the page will be placed
56
+ # upon generation. This is derived from the permalink or, if
57
+ # permalink is absent, will be '/'
58
+ #
59
+ # Returns the String destination directory.
60
+ def dir
61
+ if url.end_with?("/")
62
+ url
63
+ else
64
+ url_dir = File.dirname(url)
65
+ url_dir.end_with?("/") ? url_dir : "#{url_dir}/"
66
+ end
67
+ end
68
+
69
+ # For backwards-compatibility in subclasses that do not redefine
70
+ # the `:to_liquid` method, stash existing definition under a new name
71
+ #
72
+ # TODO: Remove in Bridgetown 5.0
73
+ alias_method :legacy_to_liquid, :to_liquid
74
+ private :legacy_to_liquid
75
+
76
+ # Private
77
+ # Subclasses can choose to optimize their `:to_liquid` method by wrapping
78
+ # it around this definition.
79
+ #
80
+ # TODO: Remove in Bridgetown 5.0
81
+ def liquid_drop
82
+ @liquid_drop ||= begin
83
+ defaults = site.frontmatter_defaults.all(relative_path, type)
84
+ unless defaults.empty?
85
+ Utils.deep_merge_hashes!(data, Utils.deep_merge_hashes!(defaults, data))
86
+ end
87
+ Drops::PageDrop.new(self)
88
+ end
89
+ end
90
+ private :liquid_drop
91
+
92
+ # Public
93
+ #
94
+ # Liquid representation of current page
95
+ #
96
+ # TODO: Remove optional parameter in Bridgetown 5.0
97
+ def to_liquid(attrs = nil)
98
+ self.class == Bridgetown::Page ? liquid_drop : legacy_to_liquid(attrs)
99
+ end
100
+
101
+ # The full path and filename of the post. Defined in the YAML of the post
102
+ # body.
103
+ #
104
+ # Returns the String permalink or nil if none has been set.
105
+ def permalink
106
+ data.nil? ? nil : data["permalink"]
107
+ end
108
+
109
+ # The template of the permalink.
110
+ #
111
+ # Returns the template String.
112
+ def template
113
+ if !html?
114
+ "/:path/:basename:output_ext"
115
+ elsif index?
116
+ "/:path/"
117
+ else
118
+ Utils.add_permalink_suffix("/:path/:basename", site.permalink_style)
119
+ end
120
+ end
121
+
122
+ # The generated relative url of this page. e.g. /about.html.
123
+ #
124
+ # Returns the String url.
125
+ def url
126
+ @url ||= URL.new(
127
+ :template => template,
128
+ :placeholders => url_placeholders,
129
+ :permalink => permalink
130
+ ).to_s
131
+ end
132
+
133
+ # Returns a hash of URL placeholder names (as symbols) mapping to the
134
+ # desired placeholder replacements. For details see "url.rb"
135
+ def url_placeholders
136
+ {
137
+ :path => @dir,
138
+ :basename => basename,
139
+ :output_ext => output_ext,
140
+ }
141
+ end
142
+
143
+ # Extract information from the page filename.
144
+ #
145
+ # name - The String filename of the page file.
146
+ #
147
+ # NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
148
+ # Returns nothing.
149
+ def process(name)
150
+ self.ext = File.extname(name)
151
+ self.basename = name[0..-ext.length - 1].gsub(%r!\.*\z!, "")
152
+ end
153
+
154
+ # Add any necessary layouts to this post
155
+ #
156
+ # layouts - The Hash of {"name" => "layout"}.
157
+ # site_payload - The site payload Hash.
158
+ #
159
+ # Returns String rendered page.
160
+ def render(layouts, site_payload)
161
+ site_payload["page"] = to_liquid
162
+ site_payload["paginator"] = pager.to_liquid
163
+
164
+ do_layout(site_payload, layouts)
165
+ end
166
+
167
+ # The path to the source file
168
+ #
169
+ # Returns the path to the source file
170
+ def path
171
+ data.fetch("path") { relative_path }
172
+ end
173
+
174
+ # The path to the page source file, relative to the site source
175
+ def relative_path
176
+ @relative_path ||= File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).sub(%r!\A\/!, "")
177
+ end
178
+
179
+ # Obtain destination path.
180
+ #
181
+ # dest - The String path to the destination dir.
182
+ #
183
+ # Returns the destination file path String.
184
+ def destination(dest)
185
+ path = site.in_dest_dir(dest, URL.unescape_path(url))
186
+ path = File.join(path, "index") if url.end_with?("/")
187
+ path << output_ext unless path.end_with? output_ext
188
+ path
189
+ end
190
+
191
+ # Returns the object as a debug String.
192
+ def inspect
193
+ "#<#{self.class} @relative_path=#{relative_path.inspect}>"
194
+ end
195
+
196
+ # Returns the Boolean of whether this Page is HTML or not.
197
+ def html?
198
+ HTML_EXTENSIONS.include?(output_ext)
199
+ end
200
+
201
+ # Returns the Boolean of whether this Page is an index file or not.
202
+ def index?
203
+ basename == "index"
204
+ end
205
+
206
+ def trigger_hooks(hook_name, *args)
207
+ Bridgetown::Hooks.trigger :pages, hook_name, self, *args
208
+ end
209
+
210
+ def write?
211
+ true
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ # A Bridgetown::Page subclass to handle processing files without reading it to
5
+ # determine the page-data and page-content based on Front Matter delimiters.
6
+ #
7
+ # The class instance is basically just a bare-bones entity with just
8
+ # attributes "dir", "name", "path", "url" defined on it.
9
+ class PageWithoutAFile < Page
10
+ def read_yaml(*)
11
+ @data ||= {}
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ # A singleton class that caches frozen instances of path strings returned from its methods.
5
+ #
6
+ # NOTE:
7
+ # This class exists because `File.join` allocates an Array and returns a new String on every
8
+ # call using **the same arguments**. Caching the result means reduced memory usage.
9
+ # However, the caches are never flushed so that they can be used even when a site is
10
+ # regenerating. The results are frozen to deter mutation of the cached string.
11
+ #
12
+ # Therefore, employ this class only for situations where caching the result is necessary
13
+ # for performance reasons.
14
+ #
15
+ class PathManager
16
+ # This class cannot be initialized from outside
17
+ private_class_method :new
18
+
19
+ # Wraps `File.join` to cache the frozen result.
20
+ # Reassigns `nil`, empty strings and empty arrays to a frozen empty string beforehand.
21
+ #
22
+ # Returns a frozen string.
23
+ def self.join(base, item)
24
+ base = "" if base.nil? || base.empty?
25
+ item = "" if item.nil? || item.empty?
26
+ @join ||= {}
27
+ @join[base] ||= {}
28
+ @join[base][item] ||= File.join(base, item).freeze
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Plugin
5
+ PRIORITIES = {
6
+ :low => -10,
7
+ :highest => 100,
8
+ :lowest => -100,
9
+ :normal => 0,
10
+ :high => 10,
11
+ }.freeze
12
+
13
+ #
14
+
15
+ def self.inherited(const)
16
+ catch_inheritance(const) do |const_|
17
+ catch_inheritance(const_)
18
+ end
19
+ end
20
+
21
+ #
22
+
23
+ def self.catch_inheritance(const)
24
+ const.define_singleton_method :inherited do |const_|
25
+ (@children ||= Set.new).add const_
26
+ yield const_ if block_given?
27
+ end
28
+ end
29
+
30
+ #
31
+
32
+ def self.descendants
33
+ @children ||= Set.new
34
+ out = @children.map(&:descendants)
35
+ out << self unless superclass == Plugin
36
+ Set.new(out).flatten
37
+ end
38
+
39
+ # Get or set the priority of this plugin. When called without an
40
+ # argument it returns the priority. When an argument is given, it will
41
+ # set the priority.
42
+ #
43
+ # priority - The Symbol priority (default: nil). Valid options are:
44
+ # :lowest, :low, :normal, :high, :highest
45
+ #
46
+ # Returns the Symbol priority.
47
+ def self.priority(priority = nil)
48
+ @priority ||= nil
49
+ @priority = priority if priority && PRIORITIES.key?(priority)
50
+ @priority || :normal
51
+ end
52
+
53
+ # Spaceship is priority [higher -> lower]
54
+ #
55
+ # other - The class to be compared.
56
+ #
57
+ # Returns -1, 0, 1.
58
+ def self.<=>(other)
59
+ PRIORITIES[other.priority] <=> PRIORITIES[priority]
60
+ end
61
+
62
+ # Spaceship is priority [higher -> lower]
63
+ #
64
+ # other - The class to be compared.
65
+ #
66
+ # Returns -1, 0, 1.
67
+ def <=>(other)
68
+ self.class <=> other.class
69
+ end
70
+
71
+ # Initialize a new plugin. This should be overridden by the subclass.
72
+ #
73
+ # config - The Hash of configuration options.
74
+ #
75
+ # Returns a new instance.
76
+ def initialize(config = {})
77
+ # no-op for default
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class PluginManager
5
+ attr_reader :site
6
+
7
+ # Create an instance of this class.
8
+ #
9
+ # site - the instance of Bridgetown::Site we're concerned with
10
+ #
11
+ # Returns nothing
12
+ def initialize(site)
13
+ @site = site
14
+ end
15
+
16
+ # Require all the plugins which are allowed.
17
+ #
18
+ # Returns nothing
19
+ def conscientious_require
20
+ require_plugin_files
21
+ end
22
+
23
+ def self.require_from_bundler
24
+ if !ENV["BRIDGETOWN_NO_BUNDLER_REQUIRE"] && File.file?("Gemfile")
25
+ require "bundler"
26
+
27
+ Bundler.setup
28
+ required_gems = Bundler.require(:bridgetown_plugins)
29
+ message = "Required #{required_gems.map(&:name).join(", ")}"
30
+ Bridgetown.logger.debug("PluginManager:", message)
31
+ ENV["BRIDGETOWN_NO_BUNDLER_REQUIRE"] = "true"
32
+
33
+ true
34
+ else
35
+ false
36
+ end
37
+ end
38
+
39
+ # Require all .rb files
40
+ #
41
+ # Returns nothing.
42
+ def require_plugin_files
43
+ plugins_path.each do |plugin_search_path|
44
+ plugin_files = Utils.safe_glob(plugin_search_path, File.join("**", "*.rb"))
45
+ Bridgetown::External.require_with_graceful_fail(plugin_files)
46
+ end
47
+ end
48
+
49
+ # Public: Setup the plugin search path
50
+ #
51
+ # Returns an Array of plugin search paths
52
+ def plugins_path
53
+ if site.config["plugins_dir"].eql? Bridgetown::Configuration::DEFAULTS["plugins_dir"]
54
+ [site.in_root_dir(site.config["plugins_dir"])]
55
+ else
56
+ Array(site.config["plugins_dir"]).map { |d| File.expand_path(d) }
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Publisher
5
+ def initialize(site)
6
+ @site = site
7
+ end
8
+
9
+ def publish?(thing)
10
+ can_be_published?(thing) && !hidden_in_the_future?(thing)
11
+ end
12
+
13
+ def hidden_in_the_future?(thing)
14
+ thing.respond_to?(:date) && !@site.future && thing.date.to_i > @site.time.to_i
15
+ end
16
+
17
+ private
18
+
19
+ def can_be_published?(thing)
20
+ thing.data.fetch("published", true) || @site.unpublished
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Reader
5
+ attr_reader :site
6
+
7
+ def initialize(site)
8
+ @site = site
9
+ end
10
+
11
+ # Read Site data from disk and load it into internal data structures.
12
+ #
13
+ # Returns nothing.
14
+ def read
15
+ @site.layouts = LayoutReader.new(site).read
16
+ read_directories
17
+ read_included_excludes
18
+ sort_files!
19
+ @site.data = DataReader.new(site).read(site.config["data_dir"])
20
+ CollectionReader.new(site).read
21
+ end
22
+
23
+ # Sorts posts, pages, and static files.
24
+ def sort_files!
25
+ site.collections.each_value { |c| c.docs.sort! }
26
+ site.pages.sort_by!(&:name)
27
+ site.static_files.sort_by!(&:relative_path)
28
+ end
29
+
30
+ # Recursively traverse directories to find pages and static files
31
+ # that will become part of the site according to the rules in
32
+ # filter_entries.
33
+ #
34
+ # dir - The String relative path of the directory to read. Default: ''.
35
+ #
36
+ # Returns nothing.
37
+ def read_directories(dir = "")
38
+ base = site.in_source_dir(dir)
39
+
40
+ return unless File.directory?(base)
41
+
42
+ dot_dirs = []
43
+ dot_pages = []
44
+ dot_static_files = []
45
+
46
+ dot = Dir.chdir(base) { filter_entries(Dir.entries("."), base) }
47
+ dot.each do |entry|
48
+ file_path = @site.in_source_dir(base, entry)
49
+ if File.directory?(file_path)
50
+ dot_dirs << entry
51
+ elsif Utils.has_yaml_header?(file_path)
52
+ dot_pages << entry
53
+ else
54
+ dot_static_files << entry
55
+ end
56
+ end
57
+
58
+ retrieve_posts(dir)
59
+ retrieve_dirs(base, dir, dot_dirs)
60
+ retrieve_pages(dir, dot_pages)
61
+ retrieve_static_files(dir, dot_static_files)
62
+ end
63
+
64
+ # Retrieves all the posts(posts) from the given directory
65
+ # and add them to the site and sort them.
66
+ #
67
+ # dir - The String representing the directory to retrieve the posts from.
68
+ #
69
+ # Returns nothing.
70
+ def retrieve_posts(dir)
71
+ return if outside_configured_directory?(dir)
72
+
73
+ site.posts.docs.concat(post_reader.read_posts(dir))
74
+ end
75
+
76
+ # Recursively traverse directories with the read_directories function.
77
+ #
78
+ # base - The String representing the site's base directory.
79
+ # dir - The String representing the directory to traverse down.
80
+ # dot_dirs - The Array of subdirectories in the dir.
81
+ #
82
+ # Returns nothing.
83
+ def retrieve_dirs(_base, dir, dot_dirs)
84
+ dot_dirs.each do |file|
85
+ dir_path = site.in_source_dir(dir, file)
86
+ rel_path = PathManager.join(dir, file)
87
+ @site.reader.read_directories(rel_path) unless @site.dest.chomp("/") == dir_path
88
+ end
89
+ end
90
+
91
+ # Retrieve all the pages from the current directory,
92
+ # add them to the site and sort them.
93
+ #
94
+ # dir - The String representing the directory retrieve the pages from.
95
+ # dot_pages - The Array of pages in the dir.
96
+ #
97
+ # Returns nothing.
98
+ def retrieve_pages(dir, dot_pages)
99
+ site.pages.concat(PageReader.new(site, dir).read(dot_pages))
100
+ end
101
+
102
+ # Retrieve all the static files from the current directory,
103
+ # add them to the site and sort them.
104
+ #
105
+ # dir - The directory retrieve the static files from.
106
+ # dot_static_files - The static files in the dir.
107
+ #
108
+ # Returns nothing.
109
+ def retrieve_static_files(dir, dot_static_files)
110
+ site.static_files.concat(StaticFileReader.new(site, dir).read(dot_static_files))
111
+ end
112
+
113
+ # Filter out any files/directories that are hidden or backup files (start
114
+ # with "." or "#" or end with "~"), or contain site content (start with "_"),
115
+ # or are excluded in the site configuration, unless they are web server
116
+ # files such as '.htaccess'.
117
+ #
118
+ # entries - The Array of String file/directory entries to filter.
119
+ # base_directory - The string representing the optional base directory.
120
+ #
121
+ # Returns the Array of filtered entries.
122
+ def filter_entries(entries, base_directory = nil)
123
+ EntryFilter.new(site, base_directory).filter(entries)
124
+ end
125
+
126
+ # Read the entries from a particular directory for processing
127
+ #
128
+ # dir - The String representing the relative path of the directory to read.
129
+ # subfolder - The String representing the directory to read.
130
+ #
131
+ # Returns the list of entries to process
132
+ def get_entries(dir, subfolder)
133
+ base = site.in_source_dir(dir, subfolder)
134
+ return [] unless File.exist?(base)
135
+
136
+ entries = Dir.chdir(base) { filter_entries(Dir["**/*"], base) }
137
+ entries.delete_if { |e| File.directory?(site.in_source_dir(base, e)) }
138
+ end
139
+
140
+ private
141
+
142
+ # Internal
143
+ #
144
+ # Determine if the directory is supposed to contain posts.
145
+ # If the user has defined a custom collections_dir, then attempt to read
146
+ # posts only from within that directory.
147
+ #
148
+ # Returns true if a custom collections_dir has been set but current directory lies
149
+ # outside that directory.
150
+ def outside_configured_directory?(dir)
151
+ collections_dir = site.config["collections_dir"]
152
+ !collections_dir.empty? && !dir.start_with?("/#{collections_dir}")
153
+ end
154
+
155
+ # Create a single PostReader instance to retrieve posts from all valid
156
+ # directories in current site.
157
+ def post_reader
158
+ @post_reader ||= PostReader.new(site)
159
+ end
160
+
161
+ def read_included_excludes
162
+ entry_filter = EntryFilter.new(site)
163
+
164
+ site.include.each do |entry|
165
+ next if entry == ".htaccess"
166
+
167
+ entry_path = site.in_source_dir(entry)
168
+ next if File.directory?(entry_path)
169
+ next if entry_filter.symlink?(entry_path)
170
+
171
+ read_included_file(entry_path) if File.file?(entry_path)
172
+ end
173
+ end
174
+
175
+ def read_included_file(entry_path)
176
+ dir = File.dirname(entry_path).sub(site.source, "")
177
+ file = Array(File.basename(entry_path))
178
+ if Utils.has_yaml_header?(entry_path)
179
+ site.pages.concat(PageReader.new(site, dir).read(file))
180
+ else
181
+ site.static_files.concat(StaticFileReader.new(site, dir).read(file))
182
+ end
183
+ end
184
+ end
185
+ end