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,437 +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 Document
|
|
6
|
-
extend Forwardable
|
|
7
|
-
include DataAccessible
|
|
8
|
-
include Comparable
|
|
9
|
-
include LayoutPlaceable
|
|
10
|
-
include LiquidRenderable
|
|
11
|
-
include Publishable
|
|
12
|
-
|
|
13
|
-
attr_reader :path, :site, :extname, :collection, :type
|
|
14
|
-
attr_accessor :content, :output
|
|
15
|
-
|
|
16
|
-
def_delegator :self, :read_post_data, :post_read
|
|
17
|
-
|
|
18
|
-
YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
|
|
19
|
-
DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!.freeze
|
|
20
|
-
DATE_FILENAME_MATCHER = %r!^(?>.+/)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)(\.[^.]+)$!.freeze
|
|
21
|
-
|
|
22
|
-
YAML_FILE_EXTS = %w(.yaml .yml).freeze
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
# Class-wide cache to stash and retrieve regexp to detect "super-directories"
|
|
27
|
-
# of a particular Bridgetown::Document object.
|
|
28
|
-
#
|
|
29
|
-
# dirname - The *special directory* for the Document.
|
|
30
|
-
# e.g. "_posts" for Documents from the `site.posts` collection.
|
|
31
|
-
def self.superdirs_regex(dirname)
|
|
32
|
-
@superdirs_regex ||= {}
|
|
33
|
-
@superdirs_regex[dirname] ||= %r!#{dirname}.*!
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
# Create a new Document.
|
|
39
|
-
#
|
|
40
|
-
# path - the path to the file
|
|
41
|
-
# relations - a hash with keys :site and :collection, the values of which
|
|
42
|
-
# are the Bridgetown::Site and Bridgetown::Collection to which this
|
|
43
|
-
# Document belong.
|
|
44
|
-
#
|
|
45
|
-
# Returns nothing.
|
|
46
|
-
def initialize(path, relations = {})
|
|
47
|
-
@site = relations[:site]
|
|
48
|
-
@path = path
|
|
49
|
-
@extname = File.extname(path)
|
|
50
|
-
@collection = relations[:collection]
|
|
51
|
-
@type = @collection.label.to_sym
|
|
52
|
-
|
|
53
|
-
@has_yaml_header = nil
|
|
54
|
-
|
|
55
|
-
data.default_proc = proc do |_, key|
|
|
56
|
-
site.frontmatter_defaults.find(relative_path, type, key.to_s)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
trigger_hooks(:post_init)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Fetch the Document's data.
|
|
63
|
-
#
|
|
64
|
-
# Returns a Hash containing the data. An empty hash is returned if
|
|
65
|
-
# no data was read.
|
|
66
|
-
def data
|
|
67
|
-
@data ||= HashWithDotAccess::Hash.new
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Merge some data in with this document's data.
|
|
71
|
-
#
|
|
72
|
-
# Returns the merged data.
|
|
73
|
-
def merge_data!(other, source: "YAML front matter")
|
|
74
|
-
merge_categories!(other)
|
|
75
|
-
Utils.deep_merge_hashes!(data, other)
|
|
76
|
-
merge_date!(source)
|
|
77
|
-
data
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Returns the document date. If metadata is not present then calculates it
|
|
81
|
-
# based on Bridgetown::Site#time or the document file modification time.
|
|
82
|
-
#
|
|
83
|
-
# Return document date string.
|
|
84
|
-
def date
|
|
85
|
-
data["date"] ||= site.time # TODO: this doesn't reflect documented behavior
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Return document file modification time in the form of a Time object.
|
|
89
|
-
#
|
|
90
|
-
# Return document file modification Time object.
|
|
91
|
-
def source_file_mtime
|
|
92
|
-
File.mtime(path)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# The path to the document, relative to the collections_dir.
|
|
96
|
-
#
|
|
97
|
-
# Returns a String path which represents the relative path from the collections_dir
|
|
98
|
-
# to this document.
|
|
99
|
-
def relative_path
|
|
100
|
-
@relative_path ||= path.sub("#{site.collections_path}/", "")
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# FIXME: spinning up a new Renderer object just to get an extension
|
|
104
|
-
# seems excessive
|
|
105
|
-
#
|
|
106
|
-
# The output extension of the document.
|
|
107
|
-
#
|
|
108
|
-
# Returns the output extension
|
|
109
|
-
def output_ext
|
|
110
|
-
@output_ext ||= Bridgetown::Renderer.new(site, self).output_ext
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
# The base filename of the document, without the file extname.
|
|
114
|
-
#
|
|
115
|
-
# Returns the basename without the file extname.
|
|
116
|
-
def basename_without_ext
|
|
117
|
-
@basename_without_ext ||= File.basename(path, ".*")
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# The base filename of the document.
|
|
121
|
-
#
|
|
122
|
-
# Returns the base filename of the document.
|
|
123
|
-
def basename
|
|
124
|
-
@basename ||= File.basename(path)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
# Produces a "cleaned" relative path.
|
|
128
|
-
# The "cleaned" relative path is the relative path without the extname
|
|
129
|
-
# and with the collection's directory removed as well.
|
|
130
|
-
# This method is useful when building the URL of the document.
|
|
131
|
-
#
|
|
132
|
-
# NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
|
|
133
|
-
#
|
|
134
|
-
# Examples:
|
|
135
|
-
# When relative_path is "_methods/site/generate...md":
|
|
136
|
-
# cleaned_relative_path
|
|
137
|
-
# # => "/site/generate"
|
|
138
|
-
#
|
|
139
|
-
# Returns the cleaned relative path of the document.
|
|
140
|
-
def cleaned_relative_path
|
|
141
|
-
@cleaned_relative_path ||=
|
|
142
|
-
relative_path[0..-extname.length - 1]
|
|
143
|
-
.sub(collection.relative_directory, "")
|
|
144
|
-
.gsub(%r!\.*\z!, "")
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# Determine whether the document is a YAML file.
|
|
148
|
-
#
|
|
149
|
-
# Returns true if the extname is either .yml or .yaml, false otherwise.
|
|
150
|
-
def yaml_file?
|
|
151
|
-
YAML_FILE_EXTS.include?(extname)
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# The URL template where the document would be accessible.
|
|
155
|
-
#
|
|
156
|
-
# Returns the URL template for the document.
|
|
157
|
-
def url_template
|
|
158
|
-
collection.url_template
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Construct a Hash of key-value pairs which contain a mapping between
|
|
162
|
-
# a key in the URL template and the corresponding value for this document.
|
|
163
|
-
#
|
|
164
|
-
# Returns the Hash of key-value pairs for replacement in the URL.
|
|
165
|
-
def url_placeholders
|
|
166
|
-
@url_placeholders ||= Drops::UrlDrop.new(self)
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
# The permalink for this Document.
|
|
170
|
-
# Permalink is set via the data Hash.
|
|
171
|
-
#
|
|
172
|
-
# Returns the permalink or nil if no permalink was set in the data.
|
|
173
|
-
def permalink
|
|
174
|
-
data&.permalink
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# The computed URL for the document. See `Bridgetown::URL#to_s` for more details.
|
|
178
|
-
#
|
|
179
|
-
# Returns the computed URL for the document.
|
|
180
|
-
def url
|
|
181
|
-
@url ||= URL.new(
|
|
182
|
-
template: url_template,
|
|
183
|
-
placeholders: url_placeholders,
|
|
184
|
-
permalink: permalink
|
|
185
|
-
).to_s
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
# The full path to the output file.
|
|
189
|
-
#
|
|
190
|
-
# base_directory - the base path of the output directory
|
|
191
|
-
#
|
|
192
|
-
# Returns the full path to the output file of this document.
|
|
193
|
-
def destination(base_directory)
|
|
194
|
-
dest = site.in_dest_dir(base_directory)
|
|
195
|
-
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
|
196
|
-
if url.end_with? "/"
|
|
197
|
-
path = File.join(path, "index.html")
|
|
198
|
-
else
|
|
199
|
-
path << output_ext unless path.end_with? output_ext
|
|
200
|
-
end
|
|
201
|
-
path
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
# Write the generated Document file to the destination directory.
|
|
205
|
-
#
|
|
206
|
-
# dest - The String path to the destination dir.
|
|
207
|
-
#
|
|
208
|
-
# Returns nothing.
|
|
209
|
-
def write(dest)
|
|
210
|
-
path = destination(dest)
|
|
211
|
-
FileUtils.mkdir_p(File.dirname(path))
|
|
212
|
-
Bridgetown.logger.debug "Writing:", path
|
|
213
|
-
File.write(path, output, mode: "wb")
|
|
214
|
-
|
|
215
|
-
trigger_hooks(:post_write)
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Read in the file and assign the content and data based on the file contents.
|
|
219
|
-
# Merge the frontmatter of the file with the frontmatter default
|
|
220
|
-
# values
|
|
221
|
-
#
|
|
222
|
-
# Returns nothing.
|
|
223
|
-
def read(opts = {})
|
|
224
|
-
Bridgetown.logger.debug "Reading:", relative_path
|
|
225
|
-
|
|
226
|
-
if yaml_file?
|
|
227
|
-
@data = YAMLParser.load_file(path)
|
|
228
|
-
else
|
|
229
|
-
begin
|
|
230
|
-
merge_defaults
|
|
231
|
-
read_content(**opts)
|
|
232
|
-
read_post_data
|
|
233
|
-
rescue StandardError => e
|
|
234
|
-
handle_read_error(e)
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
# Create a Liquid-understandable version of this Document.
|
|
240
|
-
#
|
|
241
|
-
# Returns a Hash representing this Document's data.
|
|
242
|
-
def to_liquid
|
|
243
|
-
@to_liquid ||= Drops::DocumentDrop.new(self)
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
# The inspect string for this document.
|
|
247
|
-
# Includes the relative path and the collection label.
|
|
248
|
-
#
|
|
249
|
-
# Returns the inspect string for this document.
|
|
250
|
-
def inspect
|
|
251
|
-
"#<#{self.class} #{relative_path} collection=#{collection.label}>"
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
# Compare this document against another document.
|
|
255
|
-
# Comparison is a comparison between the 2 paths of the documents.
|
|
256
|
-
#
|
|
257
|
-
# Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
|
|
258
|
-
# equal or greater than the other doc's path. See String#<=> for more details.
|
|
259
|
-
def <=>(other)
|
|
260
|
-
return nil unless other.respond_to?(:data)
|
|
261
|
-
|
|
262
|
-
cmp = data["date"] <=> other.data["date"]
|
|
263
|
-
cmp = path <=> other.path if cmp.nil? || cmp.zero?
|
|
264
|
-
cmp
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
# Determine whether this document should be written.
|
|
268
|
-
# Based on the Collection to which it belongs.
|
|
269
|
-
#
|
|
270
|
-
# True if the document has a collection and if that collection's #write?
|
|
271
|
-
# method returns true, and if the site's Publisher will publish the document.
|
|
272
|
-
# False otherwise.
|
|
273
|
-
def write?
|
|
274
|
-
collection&.write? && site.publisher.publish?(self)
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
# The Document excerpt_separator, from the YAML Front-Matter or site
|
|
278
|
-
# default excerpt_separator value
|
|
279
|
-
#
|
|
280
|
-
# Returns the document excerpt_separator
|
|
281
|
-
def excerpt_separator
|
|
282
|
-
@excerpt_separator ||= (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
# Whether to generate an excerpt
|
|
286
|
-
#
|
|
287
|
-
# Returns true if the excerpt separator is configured.
|
|
288
|
-
def generate_excerpt?
|
|
289
|
-
!excerpt_separator.empty?
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
def next_doc
|
|
293
|
-
pos = collection.docs.index { |post| post.equal?(self) }
|
|
294
|
-
collection.docs[pos + 1] if pos && pos < collection.docs.length - 1
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
def previous_doc
|
|
298
|
-
pos = collection.docs.index { |post| post.equal?(self) }
|
|
299
|
-
collection.docs[pos - 1] if pos&.positive?
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
def trigger_hooks(hook_name, *args)
|
|
303
|
-
Bridgetown::Hooks.trigger collection.label.to_sym, hook_name, self, *args if collection
|
|
304
|
-
Bridgetown::Hooks.trigger :documents, hook_name, self, *args
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
def id
|
|
308
|
-
@id ||= File.join(File.dirname(url), (data["slug"] || basename_without_ext).to_s)
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
# Calculate related posts.
|
|
312
|
-
#
|
|
313
|
-
# Returns an Array of related Posts.
|
|
314
|
-
def related_posts
|
|
315
|
-
@related_posts ||= Bridgetown::RelatedPosts.new(self).build
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# Override of method_missing to check in @data for the key.
|
|
319
|
-
def method_missing(method, *args, &blck)
|
|
320
|
-
if data.key?(method.to_s)
|
|
321
|
-
Bridgetown::Deprecator.deprecation_message "Document##{method} is now a key "\
|
|
322
|
-
"in the #data hash."
|
|
323
|
-
Bridgetown::Deprecator.deprecation_message "Called by #{caller(0..0)}."
|
|
324
|
-
data[method.to_s]
|
|
325
|
-
else
|
|
326
|
-
super
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
def respond_to_missing?(method, *)
|
|
331
|
-
data.key?(method.to_s) || super
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
private
|
|
335
|
-
|
|
336
|
-
def merge_categories!(other)
|
|
337
|
-
if other.key?("categories") && !other["categories"].nil?
|
|
338
|
-
other["categories"] = other["categories"].split if other["categories"].is_a?(String)
|
|
339
|
-
other["categories"] = (data["categories"] || []) | other["categories"]
|
|
340
|
-
end
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
def merge_date!(source)
|
|
344
|
-
if data.key?("date")
|
|
345
|
-
data["date"] = Utils.parse_date(
|
|
346
|
-
data["date"].to_s,
|
|
347
|
-
"Document '#{relative_path}' does not have a valid date in the #{source}."
|
|
348
|
-
)
|
|
349
|
-
end
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
def merge_defaults
|
|
353
|
-
defaults = @site.frontmatter_defaults.all(relative_path, type)
|
|
354
|
-
merge_data!(defaults, source: "front matter defaults") unless defaults.empty?
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
def read_content(**opts)
|
|
358
|
-
self.content = File.read(path, **Utils.merged_file_read_opts(site, opts))
|
|
359
|
-
if content =~ YAML_FRONT_MATTER_REGEXP
|
|
360
|
-
self.content = $POSTMATCH
|
|
361
|
-
data_file = YAMLParser.load(Regexp.last_match(1))
|
|
362
|
-
merge_data!(data_file, source: "YAML front matter") if data_file
|
|
363
|
-
end
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
def read_post_data
|
|
367
|
-
populate_title
|
|
368
|
-
populate_categories
|
|
369
|
-
populate_tags
|
|
370
|
-
determine_locale
|
|
371
|
-
generate_excerpt
|
|
372
|
-
end
|
|
373
|
-
|
|
374
|
-
def handle_read_error(error)
|
|
375
|
-
if error.is_a? Psych::SyntaxError
|
|
376
|
-
Bridgetown.logger.error "Error:", "YAML Exception reading #{path}: #{error.message}"
|
|
377
|
-
else
|
|
378
|
-
Bridgetown.logger.error "Error:", "could not read file #{path}: #{error.message}"
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
if site.config["strict_front_matter"] || error.is_a?(Bridgetown::Errors::FatalException)
|
|
382
|
-
raise error
|
|
383
|
-
end
|
|
384
|
-
end
|
|
385
|
-
|
|
386
|
-
def populate_title
|
|
387
|
-
if relative_path =~ DATE_FILENAME_MATCHER
|
|
388
|
-
date, slug, ext = Regexp.last_match.captures
|
|
389
|
-
modify_date(date)
|
|
390
|
-
elsif relative_path =~ DATELESS_FILENAME_MATCHER
|
|
391
|
-
slug, ext = Regexp.last_match.captures
|
|
392
|
-
end
|
|
393
|
-
|
|
394
|
-
# slugs shouldn't end with a period
|
|
395
|
-
# `String#gsub!` removes all trailing periods (in comparison to `String#chomp!`)
|
|
396
|
-
slug.gsub!(%r!\.*\z!, "")
|
|
397
|
-
|
|
398
|
-
# Try to ensure the user gets a title.
|
|
399
|
-
data["title"] ||= Utils.titleize_slug(slug)
|
|
400
|
-
# Only overwrite slug & ext if they aren't specified.
|
|
401
|
-
data["slug"] ||= slug
|
|
402
|
-
data["ext"] ||= ext
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
def populate_categories
|
|
406
|
-
data.categories = Utils.pluralized_array_from_hash(
|
|
407
|
-
data, :category, :categories
|
|
408
|
-
).map(&:to_s)
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
def populate_tags
|
|
412
|
-
data.tags = Utils.pluralized_array_from_hash(data, :tag, :tags)
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
def determine_locale
|
|
416
|
-
unless data["locale"]
|
|
417
|
-
# if locale key isn't directly set, look for alternative front matter
|
|
418
|
-
# or look at the filename pattern: slug.locale.ext
|
|
419
|
-
alernative = data["language"] || data["lang"] ||
|
|
420
|
-
basename_without_ext.split(".")[1..-1].last
|
|
421
|
-
|
|
422
|
-
data["locale"] = alernative if !alernative.nil? &&
|
|
423
|
-
site.config[:available_locales].include?(alernative)
|
|
424
|
-
end
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
def modify_date(date)
|
|
428
|
-
if !data["date"] || data["date"].to_i == site.time.to_i
|
|
429
|
-
merge_data!({ "date" => date }, source: "filename")
|
|
430
|
-
end
|
|
431
|
-
end
|
|
432
|
-
|
|
433
|
-
def generate_excerpt
|
|
434
|
-
data["excerpt"] ||= Bridgetown::Excerpt.new(self) if generate_excerpt?
|
|
435
|
-
end
|
|
436
|
-
end
|
|
437
|
-
end
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bridgetown
|
|
4
|
-
module Drops
|
|
5
|
-
class DocumentDrop < Drop
|
|
6
|
-
extend Forwardable
|
|
7
|
-
|
|
8
|
-
NESTED_OBJECT_FIELD_BLACKLIST = %w(
|
|
9
|
-
content output excerpt next previous
|
|
10
|
-
).freeze
|
|
11
|
-
|
|
12
|
-
mutable false
|
|
13
|
-
|
|
14
|
-
def_delegator :@obj, :relative_path, :path
|
|
15
|
-
def_delegators :@obj,
|
|
16
|
-
:id,
|
|
17
|
-
:output,
|
|
18
|
-
:content,
|
|
19
|
-
:to_s,
|
|
20
|
-
:relative_path,
|
|
21
|
-
:url,
|
|
22
|
-
:date,
|
|
23
|
-
:related_posts
|
|
24
|
-
|
|
25
|
-
private def_delegator :@obj, :data, :fallback_data
|
|
26
|
-
|
|
27
|
-
def collection
|
|
28
|
-
@collection ||= @obj.collection.to_liquid
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def excerpt
|
|
32
|
-
fallback_data["excerpt"].to_s
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def <=>(other)
|
|
36
|
-
return nil unless other.is_a? DocumentDrop
|
|
37
|
-
|
|
38
|
-
cmp = self["date"] <=> other["date"]
|
|
39
|
-
cmp = self["path"] <=> other["path"] if cmp.nil? || cmp.zero?
|
|
40
|
-
cmp
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def previous
|
|
44
|
-
@previous ||= @obj.previous_doc.to_liquid
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def next
|
|
48
|
-
@next ||= @obj.next_doc.to_liquid
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Generate a Hash for use in generating JSON.
|
|
52
|
-
# This is useful if fields need to be cleared before the JSON can generate.
|
|
53
|
-
#
|
|
54
|
-
# state - the JSON::State object which determines the state of current processing.
|
|
55
|
-
#
|
|
56
|
-
# Returns a Hash ready for JSON generation.
|
|
57
|
-
def hash_for_json(state = nil)
|
|
58
|
-
to_h.tap do |hash|
|
|
59
|
-
# use collection label in the hash
|
|
60
|
-
hash["collection"] = hash["collection"]["label"] if hash["collection"]
|
|
61
|
-
|
|
62
|
-
if state && state.depth >= 2
|
|
63
|
-
hash["previous"] = collapse_document(hash["previous"]) if hash["previous"]
|
|
64
|
-
hash["next"] = collapse_document(hash["next"]) if hash["next"]
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Generate a Hash which breaks the recursive chain.
|
|
70
|
-
# Certain fields which are normally available are omitted.
|
|
71
|
-
#
|
|
72
|
-
# Returns a Hash with only non-recursive fields present.
|
|
73
|
-
def collapse_document(doc)
|
|
74
|
-
doc.keys.each_with_object({}) do |(key, _), result|
|
|
75
|
-
result[key] = doc[key] unless NESTED_OBJECT_FIELD_BLACKLIST.include?(key)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Bridgetown
|
|
4
|
-
module Drops
|
|
5
|
-
class PageDrop < Drop
|
|
6
|
-
extend Forwardable
|
|
7
|
-
|
|
8
|
-
mutable false
|
|
9
|
-
|
|
10
|
-
def_delegators :@obj, :content, :dir, :name, :path, :url, :pager
|
|
11
|
-
private def_delegator :@obj, :data, :fallback_data
|
|
12
|
-
|
|
13
|
-
def relative_url
|
|
14
|
-
@obj.relative_url
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|