bridgetown-core 0.21.2 → 1.0.0.alpha2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +35 -0
- data/Rakefile +5 -5
- data/bin/bridgetown +2 -0
- data/bridgetown-core.gemspec +3 -0
- data/lib/bridgetown-core/cache.rb +3 -5
- data/lib/bridgetown-core/cleaner.rb +2 -10
- data/lib/bridgetown-core/collection.rb +62 -86
- data/lib/bridgetown-core/commands/base.rb +62 -2
- data/lib/bridgetown-core/commands/build.rb +33 -12
- data/lib/bridgetown-core/commands/concerns/actions.rb +2 -2
- data/lib/bridgetown-core/commands/concerns/build_options.rb +3 -10
- data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +3 -1
- data/lib/bridgetown-core/commands/console.rb +3 -3
- data/lib/bridgetown-core/commands/doctor.rb +13 -11
- data/lib/bridgetown-core/commands/new.rb +14 -6
- data/lib/bridgetown-core/commands/plugins.rb +8 -11
- data/lib/bridgetown-core/commands/serve/servlet.rb +4 -4
- data/lib/bridgetown-core/commands/serve.rb +37 -37
- data/lib/bridgetown-core/commands/start.rb +106 -0
- data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +2 -2
- data/lib/bridgetown-core/commands/webpack.rb +1 -1
- data/lib/bridgetown-core/component.rb +1 -5
- data/lib/bridgetown-core/concerns/site/configurable.rb +1 -13
- data/lib/bridgetown-core/concerns/site/content.rb +17 -118
- data/lib/bridgetown-core/concerns/site/extensible.rb +3 -4
- data/lib/bridgetown-core/concerns/site/localizable.rb +3 -1
- data/lib/bridgetown-core/concerns/site/processable.rb +9 -20
- data/lib/bridgetown-core/concerns/site/renderable.rb +19 -30
- data/lib/bridgetown-core/concerns/site/ssr.rb +53 -0
- data/lib/bridgetown-core/concerns/site/writable.rb +6 -9
- data/lib/bridgetown-core/configuration.rb +19 -48
- data/lib/bridgetown-core/configurations/minitesting.rb +1 -1
- data/lib/bridgetown-core/configurations/turbo.rb +1 -1
- data/lib/bridgetown-core/converter.rb +1 -0
- data/lib/bridgetown-core/converters/erb_templates.rb +3 -2
- data/lib/bridgetown-core/converters/liquid_templates.rb +3 -2
- data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
- data/lib/bridgetown-core/converters/smartypants.rb +1 -0
- data/lib/bridgetown-core/current.rb +4 -0
- data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
- data/lib/bridgetown-core/drops/drop.rb +4 -4
- data/lib/bridgetown-core/drops/generated_page_drop.rb +23 -0
- data/lib/bridgetown-core/drops/resource_drop.rb +3 -3
- data/lib/bridgetown-core/drops/site_drop.rb +3 -47
- data/lib/bridgetown-core/entry_filter.rb +1 -0
- data/lib/bridgetown-core/errors.rb +0 -2
- data/lib/bridgetown-core/filters/url_filters.rb +2 -0
- data/lib/bridgetown-core/filters.rb +11 -12
- data/lib/bridgetown-core/frontmatter_defaults.rb +52 -90
- data/lib/bridgetown-core/{page.rb → generated_page.rb} +34 -60
- data/lib/bridgetown-core/generators/prototype_generator.rb +49 -61
- data/lib/bridgetown-core/helpers.rb +8 -3
- data/lib/bridgetown-core/hooks.rb +2 -2
- data/lib/bridgetown-core/layout.rb +15 -4
- data/lib/bridgetown-core/liquid_renderer.rb +1 -3
- data/lib/bridgetown-core/log_adapter.rb +1 -1
- data/lib/bridgetown-core/log_writer.rb +7 -1
- data/lib/bridgetown-core/model/base.rb +12 -4
- data/lib/bridgetown-core/model/builder_origin.rb +23 -11
- data/lib/bridgetown-core/model/origin.rb +3 -0
- data/lib/bridgetown-core/model/plugin_origin.rb +34 -0
- data/lib/bridgetown-core/model/repo_origin.rb +1 -1
- data/lib/bridgetown-core/plugin_manager.rb +10 -10
- data/lib/bridgetown-core/publisher.rb +1 -1
- data/lib/bridgetown-core/rack/boot.rb +47 -0
- data/lib/bridgetown-core/rack/logger.rb +22 -0
- data/lib/bridgetown-core/rack/roda.rb +66 -0
- data/lib/bridgetown-core/rack/routes.rb +88 -0
- data/lib/bridgetown-core/rack/static_indexes.rb +30 -0
- data/lib/bridgetown-core/reader.rb +20 -47
- data/lib/bridgetown-core/readers/layout_reader.rb +2 -2
- data/lib/bridgetown-core/readers/plugin_content_reader.rb +8 -7
- data/lib/bridgetown-core/renderer.rb +2 -12
- data/lib/bridgetown-core/resource/base.rb +51 -27
- data/lib/bridgetown-core/resource/permalink_processor.rb +23 -12
- data/lib/bridgetown-core/resource/relations.rb +2 -3
- data/lib/bridgetown-core/resource/taxonomy_term.rb +1 -5
- data/lib/bridgetown-core/resource/transformer.rb +8 -6
- data/lib/bridgetown-core/ruby_template_view.rb +6 -8
- data/lib/bridgetown-core/site.rb +4 -8
- data/lib/bridgetown-core/static_file.rb +14 -21
- data/lib/bridgetown-core/tags/find.rb +6 -6
- data/lib/bridgetown-core/tags/highlight.rb +5 -5
- data/lib/bridgetown-core/tags/include.rb +22 -32
- data/lib/bridgetown-core/tags/link.rb +4 -0
- data/lib/bridgetown-core/tags/live_reload_dev_js.rb +13 -0
- data/lib/bridgetown-core/tags/post_url.rb +9 -14
- data/lib/bridgetown-core/tags/render_content.rb +2 -2
- data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +54 -0
- data/lib/bridgetown-core/url.rb +5 -4
- data/lib/bridgetown-core/utils/aux.rb +57 -0
- data/lib/bridgetown-core/utils/ruby_exec.rb +3 -45
- data/lib/bridgetown-core/utils/ruby_front_matter.rb +22 -7
- data/lib/bridgetown-core/utils.rb +60 -33
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/bridgetown-core/watcher.rb +4 -6
- data/lib/bridgetown-core.rb +16 -23
- data/lib/site_template/Gemfile.erb +6 -2
- data/lib/site_template/README.md +6 -6
- data/lib/site_template/Rakefile +49 -0
- data/lib/site_template/bridgetown.config.yml +2 -3
- data/lib/site_template/config/puma.rb +27 -0
- data/lib/site_template/config.ru +7 -0
- data/lib/site_template/frontend/javascript/index.js.erb +3 -3
- data/lib/site_template/package.json.erb +7 -12
- data/lib/site_template/server/roda_app.rb +22 -0
- data/lib/site_template/server/routes/hello.rb.sample +10 -0
- data/lib/site_template/src/_components/head.liquid +2 -1
- data/lib/site_template/src/about.md +0 -1
- data/lib/site_template/src/posts.md +2 -3
- metadata +63 -18
- data/lib/bridgetown-core/concerns/data_accessible.rb +0 -20
- data/lib/bridgetown-core/concerns/validatable.rb +0 -56
- data/lib/bridgetown-core/document.rb +0 -437
- data/lib/bridgetown-core/drops/document_drop.rb +0 -80
- data/lib/bridgetown-core/drops/excerpt_drop.rb +0 -19
- data/lib/bridgetown-core/drops/page_drop.rb +0 -18
- data/lib/bridgetown-core/excerpt.rb +0 -200
- data/lib/bridgetown-core/readers/data_reader.rb +0 -89
- data/lib/bridgetown-core/readers/page_reader.rb +0 -26
- data/lib/bridgetown-core/readers/post_reader.rb +0 -109
- data/lib/bridgetown-core/regenerator.rb +0 -202
- data/lib/bridgetown-core/related_posts.rb +0 -55
- data/lib/site_template/config/.keep +0 -0
- data/lib/site_template/start.js +0 -17
- data/lib/site_template/sync.js +0 -35
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bridgetown
|
|
4
|
-
class Excerpt
|
|
5
|
-
extend Forwardable
|
|
6
|
-
include LiquidRenderable
|
|
7
|
-
|
|
8
|
-
attr_accessor :doc
|
|
9
|
-
attr_accessor :content, :ext
|
|
10
|
-
attr_writer :output
|
|
11
|
-
|
|
12
|
-
def_delegators :@doc,
|
|
13
|
-
:site, :name, :ext, :extname,
|
|
14
|
-
:collection, :related_posts, :type,
|
|
15
|
-
:yaml_file?,
|
|
16
|
-
:url, :next_doc, :previous_doc
|
|
17
|
-
|
|
18
|
-
private :yaml_file?
|
|
19
|
-
|
|
20
|
-
# Initialize this Excerpt instance.
|
|
21
|
-
#
|
|
22
|
-
# doc - The Document.
|
|
23
|
-
#
|
|
24
|
-
# Returns the new Excerpt.
|
|
25
|
-
def initialize(doc)
|
|
26
|
-
self.doc = doc
|
|
27
|
-
self.content = extract_excerpt(doc.content)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Fetch YAML front-matter data from related doc, without layout key
|
|
31
|
-
#
|
|
32
|
-
# Returns Hash of doc data
|
|
33
|
-
def data
|
|
34
|
-
@data ||= doc.data.dup
|
|
35
|
-
@data.delete("layout")
|
|
36
|
-
@data.delete("excerpt")
|
|
37
|
-
@data
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def trigger_hooks(*); end
|
|
41
|
-
|
|
42
|
-
# 'Path' of the excerpt.
|
|
43
|
-
#
|
|
44
|
-
# Returns the path for the doc this excerpt belongs to with #excerpt appended
|
|
45
|
-
def path
|
|
46
|
-
File.join(doc.path, "#excerpt")
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# 'Relative Path' of the excerpt.
|
|
50
|
-
#
|
|
51
|
-
# Returns the relative_path for the doc this excerpt belongs to with #excerpt appended
|
|
52
|
-
def relative_path
|
|
53
|
-
@relative_path ||= File.join(doc.relative_path, "#excerpt")
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Check if excerpt includes a string
|
|
57
|
-
#
|
|
58
|
-
# Returns true if the string passed in
|
|
59
|
-
def include?(something)
|
|
60
|
-
output&.include?(something) || content.include?(something)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# The UID for this doc (useful in feeds).
|
|
64
|
-
# e.g. /2008/11/05/my-awesome-doc
|
|
65
|
-
#
|
|
66
|
-
# Returns the String UID.
|
|
67
|
-
def id
|
|
68
|
-
"#{doc.id}#excerpt"
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def to_s
|
|
72
|
-
output || content
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def to_liquid
|
|
76
|
-
Bridgetown::Drops::ExcerptDrop.new(self)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Returns the shorthand String identifier of this doc.
|
|
80
|
-
def inspect
|
|
81
|
-
"<#{self.class} id=#{id}>"
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def output
|
|
85
|
-
@output || (
|
|
86
|
-
Renderer.new(doc.site, self).run
|
|
87
|
-
@output
|
|
88
|
-
)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def place_in_layout?
|
|
92
|
-
false
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
protected
|
|
96
|
-
|
|
97
|
-
# Internal: Extract excerpt from the content
|
|
98
|
-
#
|
|
99
|
-
# By default excerpt is your first paragraph of a doc: everything before
|
|
100
|
-
# the first two new lines:
|
|
101
|
-
#
|
|
102
|
-
# ---
|
|
103
|
-
# title: Example
|
|
104
|
-
# ---
|
|
105
|
-
#
|
|
106
|
-
# First paragraph with [link][1].
|
|
107
|
-
#
|
|
108
|
-
# Second paragraph.
|
|
109
|
-
#
|
|
110
|
-
# [1]: http://example.com/
|
|
111
|
-
#
|
|
112
|
-
# This is fairly good option for Markdown and Textile files. But might cause
|
|
113
|
-
# problems for HTML docs (which is quite unusual for Bridgetown). If default
|
|
114
|
-
# excerpt delimiter is not good for you, you might want to set your own via
|
|
115
|
-
# configuration option `excerpt_separator`. For example, following is a good
|
|
116
|
-
# alternative for HTML docs:
|
|
117
|
-
#
|
|
118
|
-
# # file: bridgetown.config.yml
|
|
119
|
-
# excerpt_separator: "<!-- more -->"
|
|
120
|
-
#
|
|
121
|
-
# Notice that all markdown-style link references will be appended to the
|
|
122
|
-
# excerpt. So the example doc above will have this excerpt source:
|
|
123
|
-
#
|
|
124
|
-
# First paragraph with [link][1].
|
|
125
|
-
#
|
|
126
|
-
# [1]: http://example.com/
|
|
127
|
-
#
|
|
128
|
-
# Excerpts are rendered same time as content is rendered.
|
|
129
|
-
#
|
|
130
|
-
# Returns excerpt String
|
|
131
|
-
|
|
132
|
-
LIQUID_TAG_REGEX = %r!{%-?\s*(\w+)\s*.*?-?%}!m.freeze
|
|
133
|
-
MKDWN_LINK_REF_REGEX = %r!^ {0,3}(?:(\[[^\]]+\])(:.+))$!.freeze
|
|
134
|
-
|
|
135
|
-
def extract_excerpt(doc_content)
|
|
136
|
-
head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
|
|
137
|
-
return head if tail.empty?
|
|
138
|
-
|
|
139
|
-
head = sanctify_liquid_tags(head) if head.include?("{%")
|
|
140
|
-
definitions = extract_markdown_link_reference_defintions(head, tail)
|
|
141
|
-
return head if definitions.empty?
|
|
142
|
-
|
|
143
|
-
head << "\n\n" << definitions.join("\n")
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
private
|
|
147
|
-
|
|
148
|
-
# append appropriate closing tag(s) (for each Liquid block), to the `head` if the
|
|
149
|
-
# partitioning resulted in leaving the closing tag somewhere in the `tail` partition.
|
|
150
|
-
def sanctify_liquid_tags(head)
|
|
151
|
-
modified = false
|
|
152
|
-
tag_names = head.scan(LIQUID_TAG_REGEX)
|
|
153
|
-
tag_names.flatten!
|
|
154
|
-
tag_names.reverse_each do |tag_name|
|
|
155
|
-
next unless liquid_block?(tag_name)
|
|
156
|
-
next if endtag_regex_stash(tag_name).match?(head)
|
|
157
|
-
|
|
158
|
-
modified = true
|
|
159
|
-
head << "\n{% end#{tag_name} %}"
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
print_build_warning if modified
|
|
163
|
-
head
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def extract_markdown_link_reference_defintions(head, tail)
|
|
167
|
-
[].tap do |definitions|
|
|
168
|
-
tail.scan(MKDWN_LINK_REF_REGEX).each do |segments|
|
|
169
|
-
definitions << segments.join if head.include?(segments[0])
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def endtag_regex_stash(tag_name)
|
|
175
|
-
@endtag_regex_stash ||= {}
|
|
176
|
-
@endtag_regex_stash[tag_name] ||= %r!{%-?\s*end#{tag_name}.*?\s*-?%}!m
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def liquid_block?(tag_name)
|
|
180
|
-
return false unless tag_name.is_a?(String)
|
|
181
|
-
return false unless Liquid::Template.tags[tag_name]
|
|
182
|
-
|
|
183
|
-
Liquid::Template.tags[tag_name].ancestors.include?(Liquid::Block)
|
|
184
|
-
rescue NoMethodError
|
|
185
|
-
Bridgetown.logger.error "Error:", "A Liquid tag in the excerpt of" \
|
|
186
|
-
" #{doc.relative_path} couldn't be parsed."
|
|
187
|
-
raise
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def print_build_warning
|
|
191
|
-
Bridgetown.logger.warn "Warning:", "Excerpt modified in #{doc.relative_path}!"
|
|
192
|
-
Bridgetown.logger.warn "", "Found a Liquid block containing the excerpt separator" \
|
|
193
|
-
" #{doc.excerpt_separator.inspect}. "
|
|
194
|
-
Bridgetown.logger.warn "", "The block has been modified with the appropriate closing tag."
|
|
195
|
-
Bridgetown.logger.warn "", "Feel free to define a custom excerpt or excerpt_separator in the"
|
|
196
|
-
Bridgetown.logger.warn "", "document's Front Matter if the generated excerpt is" \
|
|
197
|
-
" unsatisfactory."
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
end
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bridgetown
|
|
4
|
-
# TODO: to be retired once the Resource engine is made official
|
|
5
|
-
class DataReader
|
|
6
|
-
attr_reader :site, :content
|
|
7
|
-
|
|
8
|
-
def initialize(site)
|
|
9
|
-
@site = site
|
|
10
|
-
@content = {}
|
|
11
|
-
@entry_filter = EntryFilter.new(site)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Read all the files in <dir> and adds them to @content
|
|
15
|
-
#
|
|
16
|
-
# dir - The String relative path of the directory to read.
|
|
17
|
-
#
|
|
18
|
-
# Returns @content, a Hash of the .yaml, .yml,
|
|
19
|
-
# .json, and .csv files in the base directory
|
|
20
|
-
def read
|
|
21
|
-
base = site.in_source_dir(site.config.data_dir)
|
|
22
|
-
read_data_to(base, @content)
|
|
23
|
-
merge_environment_specific_metadata!
|
|
24
|
-
@content = @content.with_dot_access
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Read and parse all .yaml, .yml, .json, .csv and .tsv
|
|
28
|
-
# files under <dir> and add them to the <data> variable.
|
|
29
|
-
#
|
|
30
|
-
# dir - The string absolute path of the directory to read.
|
|
31
|
-
# data - The variable to which data will be added.
|
|
32
|
-
#
|
|
33
|
-
# Returns nothing
|
|
34
|
-
def read_data_to(dir, data)
|
|
35
|
-
return unless File.directory?(dir)
|
|
36
|
-
|
|
37
|
-
entries = Dir.chdir(dir) do
|
|
38
|
-
Dir["*.{yaml,yml,json,csv,tsv}"] + Dir["*"].select { |fn| File.directory?(fn) }
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
entries.each do |entry|
|
|
42
|
-
path = @site.in_source_dir(dir, entry)
|
|
43
|
-
|
|
44
|
-
if File.directory?(path)
|
|
45
|
-
read_data_to(
|
|
46
|
-
path,
|
|
47
|
-
data[sanitize_filename(entry)] = {}
|
|
48
|
-
)
|
|
49
|
-
else
|
|
50
|
-
key = sanitize_filename(File.basename(entry, ".*"))
|
|
51
|
-
data[key] = read_data_file(path)
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Determines how to read a data file.
|
|
57
|
-
#
|
|
58
|
-
# Returns the contents of the data file.
|
|
59
|
-
def read_data_file(path)
|
|
60
|
-
case File.extname(path).downcase
|
|
61
|
-
when ".csv"
|
|
62
|
-
CSV.read(path,
|
|
63
|
-
headers: true,
|
|
64
|
-
encoding: site.config["encoding"]).map(&:to_hash)
|
|
65
|
-
when ".tsv"
|
|
66
|
-
CSV.read(path,
|
|
67
|
-
col_sep: "\t",
|
|
68
|
-
headers: true,
|
|
69
|
-
encoding: site.config["encoding"]).map(&:to_hash)
|
|
70
|
-
else
|
|
71
|
-
YAMLParser.load_file(path)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def merge_environment_specific_metadata!
|
|
76
|
-
if @content["site_metadata"]
|
|
77
|
-
@content["site_metadata"][Bridgetown.environment]&.each_key do |k|
|
|
78
|
-
@content["site_metadata"][k] = @content["site_metadata"][Bridgetown.environment][k]
|
|
79
|
-
end
|
|
80
|
-
@content["site_metadata"].delete(Bridgetown.environment)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def sanitize_filename(name)
|
|
85
|
-
name.gsub(%r![^\w\s-]+|(?<=^|\b\s)\s+(?=$|\s?\b)!, "")
|
|
86
|
-
.gsub(%r!\s+!, "_")
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bridgetown
|
|
4
|
-
# TODO: to be retired once the Resource engine is made official
|
|
5
|
-
class PageReader
|
|
6
|
-
attr_reader :site, :dir, :unfiltered_content
|
|
7
|
-
|
|
8
|
-
def initialize(site, dir)
|
|
9
|
-
@site = site
|
|
10
|
-
@dir = dir
|
|
11
|
-
@unfiltered_content = []
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Create a new `Bridgetown::Page` object for each entry in a given array.
|
|
15
|
-
#
|
|
16
|
-
# files - An array of file names inside `@dir`
|
|
17
|
-
#
|
|
18
|
-
# Returns an array of publishable `Bridgetown::Page` objects.
|
|
19
|
-
def read(files)
|
|
20
|
-
files.each do |page|
|
|
21
|
-
@unfiltered_content << Page.new(@site, @site.source, @dir, page)
|
|
22
|
-
end
|
|
23
|
-
@unfiltered_content.select { |page| site.publisher.publish?(page) }
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bridgetown
|
|
4
|
-
# TODO: to be retired once the Resource engine is made official
|
|
5
|
-
class PostReader
|
|
6
|
-
attr_reader :site, :unfiltered_content
|
|
7
|
-
|
|
8
|
-
def initialize(site)
|
|
9
|
-
@site = site
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# Read all the files in <source>/<dir>/_posts and create a new Document
|
|
13
|
-
# object with each one.
|
|
14
|
-
#
|
|
15
|
-
# dir - The String relative path of the directory to read.
|
|
16
|
-
#
|
|
17
|
-
# Returns nothing.
|
|
18
|
-
def read_posts(dir)
|
|
19
|
-
read_publishable(dir, "_posts", Document::DATE_FILENAME_MATCHER)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Read all the files in <source>/<dir>/<magic_dir> and create a new
|
|
23
|
-
# Document object with each one insofar as it matches the regexp matcher.
|
|
24
|
-
#
|
|
25
|
-
# @param dir [String] relative path of the directory to read.
|
|
26
|
-
#
|
|
27
|
-
# @return [Array<Document, StaticFile>]
|
|
28
|
-
def read_publishable(dir, magic_dir, matcher)
|
|
29
|
-
read_content(dir, magic_dir, matcher)
|
|
30
|
-
.tap { |items| items.select { |item| item.respond_to?(:read) }.each(&:read) }
|
|
31
|
-
.select { |item| item_added_to_site?(item) }
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Read all the content files from <source>/<dir>/magic_dir
|
|
35
|
-
# and return them with the type klass.
|
|
36
|
-
#
|
|
37
|
-
# dir - The String relative path of the directory to read.
|
|
38
|
-
# magic_dir - The String relative directory to <dir>,
|
|
39
|
-
# looks for content here.
|
|
40
|
-
# klass - The return type of the content.
|
|
41
|
-
#
|
|
42
|
-
# Returns klass type of content files
|
|
43
|
-
def read_content(dir, magic_dir, matcher)
|
|
44
|
-
@site.reader.get_entries(dir, magic_dir).map do |entry|
|
|
45
|
-
path = @site.in_source_dir(File.join(dir, magic_dir, entry))
|
|
46
|
-
|
|
47
|
-
if matcher.match?(entry) || Utils.has_yaml_header?(path)
|
|
48
|
-
# Process as Document
|
|
49
|
-
Document.new(path,
|
|
50
|
-
site: @site,
|
|
51
|
-
collection: @site.collections.posts)
|
|
52
|
-
else
|
|
53
|
-
# Process as Static File
|
|
54
|
-
read_static_file(
|
|
55
|
-
path,
|
|
56
|
-
File.join(dir, magic_dir, File.dirname(entry).sub(".", ""))
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
end.reject(&:nil?)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
def read_static_file(full_path, relative_dir)
|
|
65
|
-
StaticFile.new(
|
|
66
|
-
site,
|
|
67
|
-
site.source,
|
|
68
|
-
relative_dir,
|
|
69
|
-
File.basename(full_path),
|
|
70
|
-
@site.collections.posts
|
|
71
|
-
)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def processable?(item)
|
|
75
|
-
return true if item.is_a?(StaticFile)
|
|
76
|
-
|
|
77
|
-
if item.content.nil?
|
|
78
|
-
Bridgetown.logger.debug "Skipping:", "Content in #{item.relative_path} is nil"
|
|
79
|
-
false
|
|
80
|
-
elsif !item.content.valid_encoding?
|
|
81
|
-
Bridgetown.logger.debug "Skipping:", "#{item.relative_path} is not valid UTF-8"
|
|
82
|
-
false
|
|
83
|
-
else
|
|
84
|
-
publishable?(item)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def publishable?(item)
|
|
89
|
-
site.publisher.publish?(item).tap do |will_publish|
|
|
90
|
-
if !will_publish && site.publisher.hidden_in_the_future?(item)
|
|
91
|
-
Bridgetown.logger.warn "Skipping:", "#{item.relative_path} has a future date"
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def item_added_to_site?(item)
|
|
97
|
-
return false unless processable?(item)
|
|
98
|
-
|
|
99
|
-
if item.is_a?(Document)
|
|
100
|
-
site.collections.posts.docs << item
|
|
101
|
-
elsif item.is_a?(StaticFile)
|
|
102
|
-
site.collections.posts.static_files << item
|
|
103
|
-
site.static_files << item
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
true
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bridgetown
|
|
4
|
-
class Regenerator
|
|
5
|
-
attr_reader :site, :metadata, :cache
|
|
6
|
-
attr_accessor :disabled
|
|
7
|
-
private :disabled, :disabled=
|
|
8
|
-
|
|
9
|
-
def initialize(site)
|
|
10
|
-
@site = site
|
|
11
|
-
|
|
12
|
-
# Read metadata from file
|
|
13
|
-
read_metadata
|
|
14
|
-
|
|
15
|
-
# Initialize cache to an empty hash
|
|
16
|
-
clear_cache
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# Checks if a renderable object needs to be regenerated
|
|
20
|
-
#
|
|
21
|
-
# Returns a boolean.
|
|
22
|
-
def regenerate?(document) # rubocop:todo Metrics/CyclomaticComplexity
|
|
23
|
-
return true if disabled
|
|
24
|
-
|
|
25
|
-
case document
|
|
26
|
-
when Page
|
|
27
|
-
regenerate_page?(document)
|
|
28
|
-
when Document
|
|
29
|
-
regenerate_document?(document)
|
|
30
|
-
when Bridgetown::Resource::Base
|
|
31
|
-
regenerate_resource?(document)
|
|
32
|
-
else
|
|
33
|
-
source_path = document.respond_to?(:path) ? document.path : nil
|
|
34
|
-
dest_path = document.destination(@site.dest) if document.respond_to?(:destination)
|
|
35
|
-
source_modified_or_dest_missing?(source_path, dest_path)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Add a path to the metadata
|
|
40
|
-
#
|
|
41
|
-
# Returns true, also on failure.
|
|
42
|
-
def add(path)
|
|
43
|
-
return true unless File.exist?(path)
|
|
44
|
-
|
|
45
|
-
metadata[path] = {
|
|
46
|
-
"mtime" => File.mtime(path),
|
|
47
|
-
"deps" => [],
|
|
48
|
-
}
|
|
49
|
-
cache[path] = true
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Force a path to regenerate
|
|
53
|
-
#
|
|
54
|
-
# Returns true.
|
|
55
|
-
def force(path)
|
|
56
|
-
cache[path] = true
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Clear the metadata and cache
|
|
60
|
-
#
|
|
61
|
-
# Returns nothing
|
|
62
|
-
def clear
|
|
63
|
-
@metadata = {}
|
|
64
|
-
clear_cache
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Clear just the cache
|
|
68
|
-
#
|
|
69
|
-
# Returns nothing
|
|
70
|
-
def clear_cache
|
|
71
|
-
@cache = {}
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# Checks if the source has been modified or the
|
|
75
|
-
# destination is missing
|
|
76
|
-
#
|
|
77
|
-
# returns a boolean
|
|
78
|
-
def source_modified_or_dest_missing?(source_path, dest_path)
|
|
79
|
-
modified?(source_path) || (dest_path && !File.exist?(dest_path))
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Checks if a path's (or one of its dependencies)
|
|
83
|
-
# mtime has changed
|
|
84
|
-
#
|
|
85
|
-
# Returns a boolean.
|
|
86
|
-
def modified?(path)
|
|
87
|
-
return true if disabled?
|
|
88
|
-
|
|
89
|
-
# objects that don't have a path are always regenerated
|
|
90
|
-
return true if path.nil?
|
|
91
|
-
|
|
92
|
-
# Check for path in cache
|
|
93
|
-
return cache[path] if cache.key? path
|
|
94
|
-
|
|
95
|
-
if metadata[path]
|
|
96
|
-
# If we have seen this file before,
|
|
97
|
-
# check if it or one of its dependencies has been modified
|
|
98
|
-
existing_file_modified?(path)
|
|
99
|
-
else
|
|
100
|
-
# If we have not seen this file before, add it to the metadata and regenerate it
|
|
101
|
-
add(path)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Add a dependency of a path
|
|
106
|
-
#
|
|
107
|
-
# Returns nothing.
|
|
108
|
-
def add_dependency(path, dependency)
|
|
109
|
-
return if metadata[path].nil? || disabled
|
|
110
|
-
|
|
111
|
-
unless metadata[path]["deps"].include? dependency
|
|
112
|
-
metadata[path]["deps"] << dependency
|
|
113
|
-
add(dependency) unless metadata.include?(dependency)
|
|
114
|
-
end
|
|
115
|
-
regenerate? dependency
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Write the metadata to disk
|
|
119
|
-
#
|
|
120
|
-
# Returns nothing.
|
|
121
|
-
def write_metadata
|
|
122
|
-
unless disabled?
|
|
123
|
-
Bridgetown.logger.debug "Writing Metadata:", ".bridgetown-metadata"
|
|
124
|
-
File.binwrite(metadata_file, Marshal.dump(metadata))
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# Produce the absolute path of the metadata file
|
|
129
|
-
#
|
|
130
|
-
# Returns the String path of the file.
|
|
131
|
-
def metadata_file
|
|
132
|
-
@metadata_file ||= site.in_root_dir(".bridgetown-metadata")
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# Check if metadata has been disabled
|
|
136
|
-
#
|
|
137
|
-
# Returns a Boolean (true for disabled, false for enabled).
|
|
138
|
-
def disabled?
|
|
139
|
-
self.disabled = !site.incremental? if disabled.nil?
|
|
140
|
-
disabled
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
private
|
|
144
|
-
|
|
145
|
-
# Read metadata from the metadata file, if no file is found,
|
|
146
|
-
# initialize with an empty hash
|
|
147
|
-
#
|
|
148
|
-
# Returns the read metadata.
|
|
149
|
-
def read_metadata
|
|
150
|
-
@metadata =
|
|
151
|
-
if !disabled? && File.file?(metadata_file)
|
|
152
|
-
content = File.binread(metadata_file)
|
|
153
|
-
|
|
154
|
-
begin
|
|
155
|
-
Marshal.load(content)
|
|
156
|
-
rescue TypeError
|
|
157
|
-
YAMLParser.load(content)
|
|
158
|
-
rescue ArgumentError => e
|
|
159
|
-
Bridgetown.logger.warn("Failed to load #{metadata_file}: #{e}")
|
|
160
|
-
{}
|
|
161
|
-
end
|
|
162
|
-
else
|
|
163
|
-
{}
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def regenerate_page?(document)
|
|
168
|
-
document.data["regenerate"] ||
|
|
169
|
-
source_modified_or_dest_missing?(
|
|
170
|
-
site.in_source_dir(document.relative_path), document.destination(@site.dest)
|
|
171
|
-
)
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def regenerate_document?(document)
|
|
175
|
-
!document.write? || document.data["regenerate"] ||
|
|
176
|
-
source_modified_or_dest_missing?(
|
|
177
|
-
document.path, document.destination(@site.dest)
|
|
178
|
-
)
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
# TODO: need to manage dependencies, but for now always regenerate
|
|
182
|
-
def regenerate_resource?(_resource)
|
|
183
|
-
true
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def existing_file_modified?(path)
|
|
187
|
-
# If one of this file dependencies have been modified,
|
|
188
|
-
# set the regeneration bit for both the dependency and the file to true
|
|
189
|
-
metadata[path]["deps"].each do |dependency|
|
|
190
|
-
return cache[dependency] = cache[path] = true if modified?(dependency)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
if File.exist?(path) && metadata[path]["mtime"].eql?(File.mtime(path))
|
|
194
|
-
# If this file has not been modified, set the regeneration bit to false
|
|
195
|
-
cache[path] = false
|
|
196
|
-
else
|
|
197
|
-
# If it has been modified, set it to true
|
|
198
|
-
add(path)
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bridgetown
|
|
4
|
-
# TODO: to be retired once the Resource engine is made official
|
|
5
|
-
class RelatedPosts
|
|
6
|
-
class << self
|
|
7
|
-
attr_accessor :lsi
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
attr_reader :post, :site
|
|
11
|
-
|
|
12
|
-
def initialize(post)
|
|
13
|
-
@post = post
|
|
14
|
-
@site = post.site
|
|
15
|
-
if site.config.lsi
|
|
16
|
-
Bridgetown::Utils::RequireGems.require_with_graceful_fail("classifier-reborn")
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def build
|
|
21
|
-
return [] unless site.collections.posts.docs.size > 1
|
|
22
|
-
|
|
23
|
-
if site.config.lsi
|
|
24
|
-
build_index
|
|
25
|
-
lsi_related_posts
|
|
26
|
-
else
|
|
27
|
-
most_recent_posts
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def build_index
|
|
32
|
-
self.class.lsi ||= begin
|
|
33
|
-
lsi = ClassifierReborn::LSI.new(auto_rebuild: false)
|
|
34
|
-
Bridgetown.logger.info("Populating LSI...")
|
|
35
|
-
|
|
36
|
-
site.collections.posts.docs.each do |x|
|
|
37
|
-
lsi.add_item(x)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
Bridgetown.logger.info("Rebuilding index...")
|
|
41
|
-
lsi.build_index
|
|
42
|
-
Bridgetown.logger.info("")
|
|
43
|
-
lsi
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def lsi_related_posts
|
|
48
|
-
self.class.lsi.find_related(post, 11) - [post]
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def most_recent_posts
|
|
52
|
-
@most_recent_posts ||= (site.collections.posts.docs.last(11).reverse - [post]).first(10)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
File without changes
|
data/lib/site_template/start.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const concurrently = require('concurrently');
|
|
2
|
-
|
|
3
|
-
// By default, configure Bridgetown to use port 4001 so Browsersync can use 4000
|
|
4
|
-
// See also Browsersync settings in sync.js
|
|
5
|
-
const port = 4001
|
|
6
|
-
|
|
7
|
-
/////////////////
|
|
8
|
-
// Concurrently
|
|
9
|
-
/////////////////
|
|
10
|
-
concurrently([
|
|
11
|
-
{ command: "yarn webpack-dev", name: "Webpack", prefixColor: "yellow"},
|
|
12
|
-
{ command: "sleep 4; yarn serve --port " + port, name: "Bridgetown", prefixColor: "green"},
|
|
13
|
-
{ command: "sleep 8; yarn sync", name: "Live", prefixColor: "blue"}
|
|
14
|
-
], {
|
|
15
|
-
restartTries: 3,
|
|
16
|
-
killOthers: ['failure', 'success'],
|
|
17
|
-
}).then(() => { console.log("Done.");console.log('\033[0G'); }, () => {});
|