bridgetown-core 0.21.0 → 0.21.4

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bridgetown-core/collection.rb +11 -6
  3. data/lib/bridgetown-core/commands/concerns/build_options.rb +2 -2
  4. data/lib/bridgetown-core/commands/serve.rb +1 -1
  5. data/lib/bridgetown-core/commands/webpack/update.rb +21 -0
  6. data/lib/bridgetown-core/commands/webpack/webpack.config.js +15 -2
  7. data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +87 -91
  8. data/lib/bridgetown-core/commands/webpack.rb +8 -1
  9. data/lib/bridgetown-core/concerns/site/configurable.rb +16 -1
  10. data/lib/bridgetown-core/concerns/site/content.rb +10 -0
  11. data/lib/bridgetown-core/concerns/site/processable.rb +1 -0
  12. data/lib/bridgetown-core/configuration.rb +1 -1
  13. data/lib/bridgetown-core/configurations/tailwindcss/postcss.config.js +2 -2
  14. data/lib/bridgetown-core/configurations/tailwindcss.rb +8 -3
  15. data/lib/bridgetown-core/drops/resource_drop.rb +2 -1
  16. data/lib/bridgetown-core/drops/site_drop.rb +2 -0
  17. data/lib/bridgetown-core/errors.rb +0 -2
  18. data/lib/bridgetown-core/filters/url_filters.rb +4 -8
  19. data/lib/bridgetown-core/frontmatter_defaults.rb +11 -11
  20. data/lib/bridgetown-core/generators/prototype_generator.rb +3 -3
  21. data/lib/bridgetown-core/reader.rb +10 -5
  22. data/lib/bridgetown-core/resource/base.rb +26 -15
  23. data/lib/bridgetown-core/resource/destination.rb +3 -1
  24. data/lib/bridgetown-core/resource/permalink_processor.rb +7 -3
  25. data/lib/bridgetown-core/site.rb +1 -1
  26. data/lib/bridgetown-core/static_file.rb +3 -2
  27. data/lib/bridgetown-core/utils.rb +17 -23
  28. data/lib/bridgetown-core/version.rb +1 -1
  29. data/lib/bridgetown-core.rb +10 -1
  30. data/lib/site_template/bridgetown.config.yml +5 -1
  31. data/lib/site_template/frontend/javascript/index.js.erb +3 -3
  32. data/lib/site_template/package.json.erb +12 -12
  33. data/lib/site_template/src/_data/site_metadata.yml +1 -1
  34. data/lib/site_template/start.js +3 -3
  35. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4c0ce7bce739e63c69f338a2b614156fcf1b287f4d0742ae159055bbc64c8a6
4
- data.tar.gz: 3ecd352f397904b828a924fcc4e58813b8d9c0c37313bd17a7fab4a08600ba64
3
+ metadata.gz: 45adfcd2a3d839fa9857ba0458db4090ef70e0c89cb9015d5813d5e2c7969224
4
+ data.tar.gz: 9e4a491aad2846485a35aa3114fdc656fe6577bcb46559117c1f908aaced9f46
5
5
  SHA512:
6
- metadata.gz: 2d17ec6dea80449358e73cc7c7c0d8ac1b3be7dd9d5a55d4d05771fbe59d7d7f27504c08143cb56b8d97e9c0329245c9f68476bfed2708d8915201c16f6ce1bc
7
- data.tar.gz: 5ceb50825db51531cad5f9ae141d53a30791ef35ffeb44169911e764ce4ec6bcb082ce54f8a456da275853128dc8cd3768985fd1854001bab9cd0edc0ba057bc
6
+ metadata.gz: a376dd395a1e6c217479441a15edaca9be963b246b54d19ed07ead07e148838b84ada1dd077b6e8a62e07979cad979b13f36f7579af5a110f67d470a7df1d8db
7
+ data.tar.gz: aba8119209faee49d7180e29f1526e8e0aaf0726e164fb0ee384736e451f709f52be13ab897ef49500316b1e782d1f719fa8879ecb09281a684fb4c80ff897a0
@@ -242,7 +242,7 @@ module Bridgetown
242
242
  site.config.collections[label] || HashWithDotAccess::Hash.new
243
243
  end
244
244
 
245
- def merge_data_resources
245
+ def merge_data_resources # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
246
246
  data_contents = {}
247
247
 
248
248
  sanitize_filename = ->(name) do
@@ -256,11 +256,16 @@ module Bridgetown
256
256
  segments.each_with_index do |segment, index|
257
257
  sanitized_segment = sanitize_filename.(File.basename(segment, ".*"))
258
258
  hsh = nested.empty? ? data_contents : data_contents.dig(*nested)
259
- hsh[sanitized_segment] = if index == segments.length - 1
260
- data_resource.data.rows || data_resource.data
261
- else
262
- {}
263
- end
259
+ if !hsh.is_a?(Hash)
260
+ Bridgetown.logger.error(
261
+ "Error:",
262
+ "#{nested.join("/")} is not a Hash structure, #{segment} cannot be read"
263
+ )
264
+ elsif index == segments.length - 1
265
+ hsh[sanitized_segment] = data_resource.data.rows || data_resource.data
266
+ elsif !hsh.key?(sanitized_segment)
267
+ hsh[sanitized_segment] = {}
268
+ end
264
269
  nested << sanitized_segment
265
270
  end
266
271
  end
@@ -36,9 +36,9 @@ module Bridgetown
36
36
  klass.class_option :limit_posts,
37
37
  type: :numeric,
38
38
  desc: "Limits the number of posts to parse and publish"
39
- klass.class_option :baseurl,
39
+ klass.class_option :base_path,
40
40
  aliases: "-b",
41
- desc: "Serve the website from the given base URL"
41
+ desc: "Serve the website from the given base path"
42
42
  klass.class_option :force_polling,
43
43
  type: :boolean,
44
44
  desc: "Force watch to use polling"
@@ -119,7 +119,7 @@ module Bridgetown
119
119
 
120
120
  def start_up_webrick(opts, destination)
121
121
  @server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
122
- @server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
122
+ @server.mount(opts["base_path"].to_s, Servlet, destination, file_handler_opts)
123
123
 
124
124
  Bridgetown.logger.info "Server address:", server_address(@server, opts)
125
125
  launch_browser @server, opts if opts["open_url"]
@@ -1,3 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Layout/LineLength
4
+
5
+ required_packages = %w(esbuild esbuild-loader webpack@5.39.1 webpack-cli@4.7.2 webpack-manifest-plugin@3.1.1)
6
+ redundant_packages = %w(@babel/core @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime @babel/preset-env babel-loader)
7
+
3
8
  template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
9
+ say "🎉 Webpack configuration updated successfully!"
10
+
11
+ return if Bridgetown.environment.test?
12
+
13
+ say "Installing required packages"
14
+ run "yarn add -D #{required_packages.join(" ")}"
15
+
16
+ packages_to_remove = package_json["devDependencies"].slice(*redundant_packages).keys
17
+ unless packages_to_remove.empty?
18
+ confirm = ask "\nThe following packages will be removed: \n\n#{packages_to_remove.join("\n")}\n\nWould you like to continue? [Yn]"
19
+ return unless confirm.casecmp?("Y")
20
+
21
+ run "yarn remove #{packages_to_remove.join(" ")}"
22
+ end
23
+
24
+ # rubocop:enable Layout/LineLength
@@ -1,7 +1,9 @@
1
- const config = require("./config/webpack.defaults.js")
1
+ const { merge } = require('webpack-merge')
2
2
 
3
- // Add any overrides to the default webpack config here:
3
+ var config = require("./config/webpack.defaults.js")
4
4
 
5
+ // Add any overrides to the default webpack config here:
6
+ //
5
7
  // Eg:
6
8
  //
7
9
  // ```
@@ -9,6 +11,17 @@ const config = require("./config/webpack.defaults.js")
9
11
  // config.resolve.modules.push(path.resolve(__dirname, 'frontend', 'components'))
10
12
  // config.resolve.alias.frontendComponents = path.resolve(__dirname, 'frontend', 'components')
11
13
  // ```
14
+ //
15
+ // You can also merge in a custom config using the included `webpack-merge` package.
16
+ // Complete docs available at: https://github.com/survivejs/webpack-merge
17
+ //
18
+ // Eg:
19
+ //
20
+ // ```
21
+ // const customConfig = { ..... }
22
+ // config = merge(config, customConfig)
23
+ // ```
24
+
12
25
 
13
26
 
14
27
 
@@ -11,12 +11,89 @@
11
11
  const path = require("path");
12
12
  const rootDir = path.resolve(__dirname, "..")
13
13
  const MiniCssExtractPlugin = require("mini-css-extract-plugin");
14
- const ManifestPlugin = require("webpack-manifest-plugin");
14
+ const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
15
15
 
16
- module.exports = {
17
- entry: {
18
- main: path.resolve(rootDir, "frontend", "javascript", "index.js")
16
+ // Input and output
17
+
18
+ const entry = { main: path.resolve(rootDir, "frontend", "javascript", "index.js") }
19
+ const output = {
20
+ path: path.resolve(rootDir, "output", "_bridgetown", "static", "js"),
21
+ filename: "[name].[contenthash].js",
22
+ publicPath: "",
23
+ }
24
+
25
+ // Rules and Loaders
26
+
27
+ const jsRule = {
28
+ test: /\.(js|jsx)/,
29
+ use: {
30
+ loader: "esbuild-loader",
31
+ options: {
32
+ target: 'es2016'
33
+ },
34
+ },
35
+ }
36
+
37
+ const cssRules = {
38
+ test: /\.(s[ac]|c)ss$/,
39
+ use: [
40
+ MiniCssExtractPlugin.loader,
41
+ {
42
+ loader: "css-loader",
43
+ options: {
44
+ url: url => !url.startsWith('/'),
45
+ importLoaders: 1
46
+ }
47
+ }
48
+ ],
49
+ mode: '<%= self.config.uses_postcss? ? "postcss" : "sass" %>',
50
+
51
+ postcss: () => {
52
+ cssRules.use.push("postcss-loader")
53
+ return { test: cssRules.test, use: cssRules.use }
54
+ },
55
+
56
+ sass: () => {
57
+ cssRules.use.push({
58
+ loader: "sass-loader",
59
+ options: {
60
+ implementation: require("sass"),
61
+ sassOptions: {
62
+ fiber: false,
63
+ includePaths: [
64
+ path.resolve(rootDir, "src/_components")
65
+ ],
66
+ },
67
+ },
68
+ })
69
+ return { test: cssRules.test, use: cssRules.use }
70
+ }
71
+ }
72
+
73
+ const fontsRule = {
74
+ test: /\.woff2?$|\.ttf$|\.eot$/,
75
+ loader: "file-loader",
76
+ options: {
77
+ name: "[name]-[contenthash].[ext]",
78
+ outputPath: "../fonts",
79
+ publicPath: "../fonts",
80
+ },
81
+ }
82
+
83
+ const imagesRule = {
84
+ test: /\.png?$|\.gif$|\.jpg$|\.svg$/,
85
+ loader: "file-loader",
86
+ options: {
87
+ name: "[path][name]-[contenthash].[ext]",
88
+ outputPath: "../",
89
+ publicPath: "../",
19
90
  },
91
+ }
92
+
93
+ // Default configuration object
94
+
95
+ module.exports = {
96
+ entry: entry,
20
97
  devtool: "source-map",
21
98
  // Set some or all of these to true if you want more verbose logging:
22
99
  stats: {
@@ -25,10 +102,7 @@ module.exports = {
25
102
  timings: false,
26
103
  children: false,
27
104
  },
28
- output: {
29
- path: path.resolve(rootDir, "output", "_bridgetown", "static", "js"),
30
- filename: "[name].[contenthash].js",
31
- },
105
+ output: output,
32
106
  resolve: {
33
107
  extensions: [".js", ".jsx"],
34
108
  modules: [
@@ -44,91 +118,13 @@ module.exports = {
44
118
  new MiniCssExtractPlugin({
45
119
  filename: "../css/[name].[contenthash].css",
46
120
  }),
47
- new ManifestPlugin({
121
+ new WebpackManifestPlugin({
48
122
  fileName: path.resolve(rootDir, ".bridgetown-webpack", "manifest.json"),
49
123
  }),
50
124
  ],
51
125
  module: {
52
126
  rules: [
53
- {
54
- test: /\.(js|jsx)/,
55
- use: {
56
- loader: "babel-loader",
57
- options: {
58
- presets: ["@babel/preset-env"],
59
- plugins: [
60
- ["@babel/plugin-proposal-decorators", { "legacy": true }],
61
- ["@babel/plugin-proposal-class-properties", { "loose" : true }],
62
- [
63
- "@babel/plugin-transform-runtime",
64
- {
65
- helpers: false,
66
- },
67
- ],
68
- ["@babel/plugin-proposal-private-methods", { "loose": true }],
69
- ],
70
- },
71
- },
72
- },
73
- <% if self.config.uses_postcss? %>
74
- {
75
- test: /\.(s[ac]|c)ss$/,
76
- use: [
77
- MiniCssExtractPlugin.loader,
78
- {
79
- loader: "css-loader",
80
- options: {
81
- url: url => !url.startsWith('/'),
82
- importLoaders: 1
83
- }
84
- },
85
- "postcss-loader"
86
- ],
87
- },
88
- <% else %>
89
- {
90
- test: /\.(s[ac]|c)ss$/,
91
- use: [
92
- MiniCssExtractPlugin.loader,
93
- {
94
- loader: "css-loader",
95
- options: {
96
- url: url => !url.startsWith('/')
97
- }
98
- },
99
- {
100
- loader: "sass-loader",
101
- options: {
102
- implementation: require("sass"),
103
- sassOptions: {
104
- fiber: false,
105
- includePaths: [
106
- path.resolve(rootDir, "src/_components")
107
- ],
108
- },
109
- },
110
- },
111
- ],
112
- },
113
- <% end %>
114
- {
115
- test: /\.woff2?$|\.ttf$|\.eot$/,
116
- loader: "file-loader",
117
- options: {
118
- name: "[name]-[contenthash].[ext]",
119
- outputPath: "../fonts",
120
- publicPath: "../fonts",
121
- },
122
- },
123
- {
124
- test: /\.png?$|\.gif$|\.jpg$|\.svg$/,
125
- loader: "file-loader",
126
- options: {
127
- name: "[path][name]-[contenthash].[ext]",
128
- outputPath: "../",
129
- publicPath: "../",
130
- },
131
- },
132
- ],
133
- },
134
- };
127
+ jsRule, cssRules[cssRules.mode](), fontsRule, imagesRule
128
+ ]
129
+ }
130
+ }
@@ -41,11 +41,18 @@ module Bridgetown
41
41
  config.root_dir
42
42
  end
43
43
 
44
+ protected
45
+
44
46
  def config
45
47
  @config ||= Bridgetown.configuration({ root_dir: Dir.pwd })
46
48
  end
47
49
 
48
- protected
50
+ def package_json
51
+ @package_json ||= begin
52
+ package_json_file = File.read(Bridgetown.sanitized_path(config.root_dir, "package.json"))
53
+ JSON.parse(package_json_file)
54
+ end
55
+ end
49
56
 
50
57
  def perform(action)
51
58
  automation = find_in_source_paths("#{action}.rb")
@@ -24,7 +24,6 @@ class Bridgetown::Site
24
24
  configure_include_paths
25
25
  configure_file_read_opts
26
26
 
27
- self.baseurl = config.baseurl
28
27
  self.permalink_style = (config["permalink"] || "pretty").to_sym
29
28
 
30
29
  @config
@@ -34,6 +33,22 @@ class Bridgetown::Site
34
33
  config[:content_engine] == "resource"
35
34
  end
36
35
 
36
+ # Returns a base path from which the site is served (aka `/cool-site`) or
37
+ # `/` if served from root.
38
+ #
39
+ # @param strip_slash_only [Boolean] set to true if you wish "/" to be returned as ""
40
+ # @return [String]
41
+ def base_path(strip_slash_only: false)
42
+ (config[:base_path] || config[:baseurl]).yield_self do |path|
43
+ strip_slash_only ? path.to_s.sub(%r{^/$}, "") : path
44
+ end
45
+ end
46
+
47
+ def baseurl
48
+ Bridgetown::Deprecator.deprecation_message "Site#baseurl is now Site#base_path"
49
+ base_path(strip_slash_only: true).presence
50
+ end
51
+
37
52
  def defaults_reader
38
53
  @defaults_reader ||= Bridgetown::DefaultsReader.new(self)
39
54
  end
@@ -220,5 +220,15 @@ class Bridgetown::Site
220
220
  def add_generated_page(generated_page)
221
221
  generated_pages << generated_page
222
222
  end
223
+
224
+ # Loads and memoizes the parsed Webpack manifest file (if available)
225
+ # @return [Hash]
226
+ def frontend_manifest
227
+ @frontend_manifest ||= begin
228
+ manifest_file = in_root_dir(".bridgetown-webpack", "manifest.json")
229
+
230
+ JSON.parse(File.read(manifest_file)) if File.exist?(manifest_file)
231
+ end
232
+ end
223
233
  end
224
234
  end
@@ -34,6 +34,7 @@ class Bridgetown::Site
34
34
  self.pages = []
35
35
  self.static_files = []
36
36
  self.data = HashWithDotAccess::Hash.new
37
+ @frontend_manifest = nil
37
38
  @post_attr_hash = {}
38
39
  @collections = nil
39
40
  @documents = nil
@@ -54,7 +54,7 @@ module Bridgetown
54
54
  "detach" => false, # default to not detaching the server
55
55
  "port" => "4000",
56
56
  "host" => "127.0.0.1",
57
- "baseurl" => nil, # this mounts at /, i.e. no subdirectory
57
+ "base_path" => "/",
58
58
  "show_dir_listing" => false,
59
59
 
60
60
  # Output Configuration
@@ -6,7 +6,7 @@ module.exports = {
6
6
  autoprefixer: {
7
7
  flexbox: 'no-2009'
8
8
  },
9
- stage: 3
9
+ stage: 2
10
10
  }
11
11
  }
12
- }
12
+ }
@@ -21,9 +21,14 @@ run "npx tailwindcss init"
21
21
 
22
22
  copy_file "#{TEMPLATE_PATH}/postcss.config.js", "postcss.config.js", force: true
23
23
 
24
- prepend_to_file "frontend/styles/index.css",
25
- File.read("#{TEMPLATE_PATH}/css_imports.css")
26
-
27
24
  run "bundle exec bridgetown configure purgecss"
28
25
 
26
+ if File.exist?("frontend/styles/index.css")
27
+ prepend_to_file "frontend/styles/index.css",
28
+ File.read("#{TEMPLATE_PATH}/css_imports.css")
29
+ else
30
+ say "\nPlease add the following lines to your CSS index file:"
31
+ say File.read("#{TEMPLATE_PATH}/css_imports.css")
32
+ end
33
+
29
34
  # rubocop:enable all
@@ -17,6 +17,7 @@ module Bridgetown
17
17
  :data,
18
18
  :output,
19
19
  :content,
20
+ :summary,
20
21
  :to_s,
21
22
  :absolute_url,
22
23
  :relative_path,
@@ -48,7 +49,7 @@ module Bridgetown
48
49
  end
49
50
 
50
51
  def next
51
- @next ||= @obj.previous_resource.to_liquid
52
+ @next ||= @obj.next_resource.to_liquid
52
53
  end
53
54
 
54
55
  # Generate a Hash for use in generating JSON.
@@ -8,6 +8,8 @@ module Bridgetown
8
8
  mutable false
9
9
 
10
10
  def_delegators :@obj,
11
+ :baseurl, # deprecated
12
+ :base_path,
11
13
  :data,
12
14
  :locale,
13
15
  :time,
@@ -14,7 +14,5 @@ module Bridgetown
14
14
  PostURLError = Class.new(FatalException)
15
15
  InvalidURLError = Class.new(FatalException)
16
16
  InvalidConfigurationError = Class.new(FatalException)
17
-
18
- WebpackAssetError = Class.new(FatalException)
19
17
  end
20
18
  end
@@ -5,7 +5,7 @@ module Bridgetown
5
5
  module URLFilters
6
6
  extend self
7
7
 
8
- # Produces an absolute URL based on site.url and site.baseurl.
8
+ # Produces an absolute URL based on site.url and site.base_path.
9
9
  #
10
10
  # input - the URL to make absolute.
11
11
  #
@@ -15,7 +15,7 @@ module Bridgetown
15
15
  cache[input] ||= compute_absolute_url(input)
16
16
  end
17
17
 
18
- # Produces a URL relative to the domain root based on site.baseurl
18
+ # Produces a URL relative to the domain root based on site.base_path
19
19
  # unless it is already an absolute url with an authority (host).
20
20
  #
21
21
  # input - the URL to make relative to the domain root
@@ -70,17 +70,13 @@ module Bridgetown
70
70
  input = input.url if input.respond_to?(:url)
71
71
  return input if Addressable::URI.parse(input.to_s).absolute?
72
72
 
73
- parts = [sanitized_baseurl, input]
73
+ site = @context.registers[:site]
74
+ parts = [site.base_path.chomp("/"), input]
74
75
  Addressable::URI.parse(
75
76
  parts.compact.map { |part| ensure_leading_slash(part.to_s) }.join
76
77
  ).normalize.to_s
77
78
  end
78
79
 
79
- def sanitized_baseurl
80
- site = @context.registers[:site]
81
- site.config["baseurl"].to_s.chomp("/")
82
- end
83
-
84
80
  def ensure_leading_slash(input)
85
81
  return input if input.nil? || input.empty? || input.start_with?("/")
86
82
 
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- # This class handles custom defaults for YAML frontmatter settings.
5
- # These are set in bridgetown.config.yml and apply both to internal use (e.g. layout)
6
- # and the data available to liquid.
7
- #
4
+ # This class handles custom defaults for YAML frontmatter variables.
8
5
  # It is exposed via the frontmatter_defaults method on the site class.
6
+ # TODO: needs simplification/refactoring.
9
7
  class FrontmatterDefaults
10
- # Initializes a new instance.
8
+ # @return [Bridgetown::Site]
9
+ attr_reader :site
10
+
11
11
  def initialize(site)
12
12
  @site = site
13
13
  end
@@ -45,7 +45,7 @@ module Bridgetown
45
45
  set
46
46
  end
47
47
 
48
- # Finds a default value for a given setting, filtered by path and type
48
+ # TODO: deprecated. See `all` method instead
49
49
  #
50
50
  # path - the path (relative to the source) of the page or
51
51
  # post the default is used in
@@ -96,8 +96,8 @@ module Bridgetown
96
96
  private
97
97
 
98
98
  def merge_data_cascade_for_path(path, merged_data)
99
- absolute_path = @site.in_source_dir(path)
100
- @site.defaults_reader.path_defaults
99
+ absolute_path = site.in_source_dir(path)
100
+ site.defaults_reader.path_defaults
101
101
  .select { |k, _v| absolute_path.include? k }
102
102
  .sort_by { |k, _v| k.length }
103
103
  .each do |defaults|
@@ -130,7 +130,7 @@ module Bridgetown
130
130
  end
131
131
 
132
132
  def glob_scope(sanitized_path, rel_scope_path)
133
- site_source = Pathname.new(@site.source)
133
+ site_source = Pathname.new(site.source)
134
134
  abs_scope_path = site_source.join(rel_scope_path).to_s
135
135
 
136
136
  glob_cache(abs_scope_path).each do |scope_path|
@@ -152,7 +152,7 @@ module Bridgetown
152
152
  end
153
153
 
154
154
  def strip_collections_dir(path)
155
- collections_dir = @site.config["collections_dir"]
155
+ collections_dir = site.config["collections_dir"]
156
156
  slashed_coll_dir = collections_dir.empty? ? "/" : "#{collections_dir}/"
157
157
  return path if collections_dir.empty? || !path.to_s.start_with?(slashed_coll_dir)
158
158
 
@@ -226,7 +226,7 @@ module Bridgetown
226
226
  #
227
227
  # Returns an array of hashes
228
228
  def valid_sets
229
- sets = @site.config["defaults"]
229
+ sets = site.config["defaults"]
230
230
  return [] unless sets.is_a?(Array)
231
231
 
232
232
  sets.map do |set|
@@ -79,11 +79,11 @@ module Bridgetown
79
79
  # @return [String, nil]
80
80
  def validate_search_term(prototype_page)
81
81
  # @type [String]
82
- search_term = prototype_page.data["prototype"]["term"]
83
- return nil unless search_term.is_a?(String)
82
+ search_term = prototype_page.data["prototype"]["term"].to_s
83
+ return nil unless search_term.present?
84
84
 
85
85
  if prototype_page.data["prototype"]["collection"]
86
- @configured_collection = prototype_page.data["prototype"]["collection"]
86
+ @configured_collection = prototype_page.data["prototype"]["collection"].to_s
87
87
  end
88
88
 
89
89
  unless site.collections[@configured_collection]
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Bridgetown
4
4
  class Reader
5
+ # @return [Bridgetown::Site]
5
6
  attr_reader :site
6
7
 
7
8
  def initialize(site)
@@ -17,12 +18,13 @@ module Bridgetown
17
18
  read_directories
18
19
  read_included_excludes
19
20
  sort_files!
20
- read_collections
21
21
  site.data = if site.uses_resource?
22
+ site.collections.data.read
22
23
  site.collections.data.merge_data_resources
23
24
  else
24
25
  DataReader.new(site).read
25
26
  end
27
+ read_collections
26
28
  Bridgetown::PluginManager.source_manifests.map(&:content).compact.each do |plugin_content_dir|
27
29
  PluginContentReader.new(site, plugin_content_dir).read
28
30
  end
@@ -30,15 +32,17 @@ module Bridgetown
30
32
 
31
33
  def read_collections
32
34
  site.collections.each_value do |collection|
33
- collection.read unless !site.uses_resource? &&
34
- collection.legacy_reader?
35
+ next if site.uses_resource? && collection.data?
36
+ next if !site.uses_resource? && collection.legacy_reader?
37
+
38
+ collection.read
35
39
  end
36
40
  end
37
41
 
38
42
  # Sorts posts, pages, and static files.
39
43
  def sort_files!
40
- site.collections.each_value { |c| c.docs.sort! }
41
- site.pages.sort_by!(&:name)
44
+ site.collections.posts.docs.sort! unless site.uses_resource?
45
+ site.generated_pages.sort_by!(&:name)
42
46
  site.static_files.sort_by!(&:relative_path)
43
47
  end
44
48
 
@@ -197,6 +201,7 @@ module Bridgetown
197
201
  dir = File.dirname(entry_path).sub(site.source, "")
198
202
  file = Array(File.basename(entry_path))
199
203
  if Utils.has_yaml_header?(entry_path)
204
+ # TODO: does this need to get incorporated into the resource engine?
200
205
  site.pages.concat(PageReader.new(site, dir).read(file))
201
206
  else
202
207
  retrieve_static_files(dir, file)
@@ -30,9 +30,9 @@ module Bridgetown
30
30
  def initialize(model:)
31
31
  @model = model
32
32
  @site = model.site
33
- self.data = HashWithDotAccess::Hash.new
33
+ @data = front_matter_defaults
34
34
 
35
- trigger_hooks(:post_init)
35
+ trigger_hooks :post_init
36
36
  end
37
37
 
38
38
  # Collection associated with this resource
@@ -75,20 +75,21 @@ module Bridgetown
75
75
  @relations ||= Bridgetown::Resource::Relations.new(self)
76
76
  end
77
77
 
78
+ # Loads in any default front matter associated with the resource.
79
+ #
80
+ # @return [HashWithDotAccess::Hash]
81
+ def front_matter_defaults
82
+ site.frontmatter_defaults.all(
83
+ relative_path.to_s,
84
+ collection.label.to_sym
85
+ ).with_dot_access
86
+ end
87
+
88
+ # Merges new data into the existing data hash.
89
+ #
78
90
  # @param new_data [HashWithDotAccess::Hash]
79
91
  def data=(new_data)
80
- unless new_data.is_a?(HashWithDotAccess::Hash)
81
- raise "#{self.class} data should be of type HashWithDotAccess::Hash"
82
- end
83
-
84
- @data = new_data
85
- @data.default_proc = proc do |_, key|
86
- site.frontmatter_defaults.find(
87
- relative_path.to_s,
88
- collection.label.to_sym,
89
- key.to_s
90
- )
91
- end
92
+ @data = @data.merge(new_data)
92
93
  end
93
94
 
94
95
  # @return [Bridgetown::Resource::Base]
@@ -107,7 +108,7 @@ module Bridgetown
107
108
 
108
109
  @destination = Destination.new(self) if requires_destination?
109
110
 
110
- trigger_hooks(:post_read)
111
+ trigger_hooks :post_read
111
112
 
112
113
  self
113
114
  end
@@ -181,6 +182,16 @@ module Bridgetown
181
182
  data["date"] ||= site.time
182
183
  end
183
184
 
185
+ # Ask the configured summary extension to output a summary of the content,
186
+ # otherwise return the first line.
187
+ #
188
+ # @return [String]
189
+ def summary
190
+ return summary_extension_output if respond_to?(:summary_extension_output)
191
+
192
+ content.to_s.strip.lines.first.to_s.strip.html_safe
193
+ end
194
+
184
195
  # @return [Hash<String, Hash<String => Bridgetown::Resource::TaxonomyType,
185
196
  # Array<Bridgetown::Resource::TaxonomyTerm>>>]
186
197
  def taxonomies
@@ -32,7 +32,9 @@ module Bridgetown
32
32
 
33
33
  def output_path
34
34
  path = URL.unescape_path(relative_url)
35
- path = path.delete_prefix(resource.site.baseurl) if resource.site.baseurl.present?
35
+ if resource.site.base_path.present?
36
+ path = path.delete_prefix resource.site.base_path(strip_slash_only: true)
37
+ end
36
38
  path = resource.site.in_dest_dir(path)
37
39
  path = File.join(path, "index.html") if relative_url.end_with? "/"
38
40
  path
@@ -40,7 +40,7 @@ module Bridgetown
40
40
  # No relative URLs should ever end in /index.html
41
41
  new_url.sub!(%r{/index$}, "") if final_ext == ".html"
42
42
 
43
- add_baseurl finalize_permalink(new_url, permalink)
43
+ add_base_path finalize_permalink(new_url, permalink)
44
44
  end
45
45
 
46
46
  def process_segment(segment)
@@ -96,8 +96,12 @@ module Bridgetown
96
96
  end
97
97
  end
98
98
 
99
- def add_baseurl(permalink)
100
- resource.site.baseurl.present? ? "#{resource.site.baseurl}#{permalink}" : permalink
99
+ def add_base_path(permalink)
100
+ if resource.site.base_path.present?
101
+ return "#{resource.site.base_path(strip_slash_only: true)}#{permalink}"
102
+ end
103
+
104
+ permalink
101
105
  end
102
106
 
103
107
  ### Default Placeholders Processors
@@ -30,7 +30,7 @@ module Bridgetown
30
30
  # is default
31
31
  alias_method :generated_pages, :pages
32
32
 
33
- attr_accessor :permalink_style, :time, :baseurl, :data,
33
+ attr_accessor :permalink_style, :time, :data,
34
34
  :file_read_opts, :plugin_manager, :converters,
35
35
  :generators, :reader
36
36
 
@@ -58,8 +58,9 @@ module Bridgetown
58
58
  def destination(dest)
59
59
  dest = site.in_dest_dir(dest)
60
60
  dest_url = url
61
- dest_url = dest_url.delete_prefix(site.baseurl) if site.uses_resource? &&
62
- site.baseurl.present? && collection
61
+ if site.uses_resource? && site.base_path.present? && collection
62
+ dest_url = dest_url.delete_prefix site.base_path(strip_slash_only: true)
63
+ end
63
64
  site.in_dest_dir(dest, Bridgetown::URL.unescape_path(dest_url))
64
65
  end
65
66
 
@@ -354,33 +354,24 @@ module Bridgetown
354
354
  # @raise [WebpackAssetError] if unable to find css or js in the manifest
355
355
  # file
356
356
  def parse_webpack_manifest_file(site, asset_type)
357
- manifest_file = site.in_root_dir(".bridgetown-webpack", "manifest.json")
358
- return "MISSING_WEBPACK_MANIFEST" unless File.exist?(manifest_file)
357
+ return log_webpack_asset_error("Webpack manifest") if site.frontend_manifest.nil?
359
358
 
360
- manifest = JSON.parse(File.read(manifest_file))
359
+ asset_path = if %w(js css).include?(asset_type)
360
+ site.frontend_manifest["main.#{asset_type}"]
361
+ else
362
+ site.frontend_manifest.find do |item, _|
363
+ item.sub(%r{^../(frontend/|src/)?}, "") == asset_type
364
+ end&.last
365
+ end
361
366
 
362
- known_assets = %w(js css)
363
- asset_path = nil
364
- if known_assets.include?(asset_type)
365
- asset_path = manifest["main.#{asset_type}"]
366
- log_webpack_asset_error(asset_type) && return if asset_path.nil?
367
- else
368
- asset_path = manifest.find do |item, _|
369
- item.sub(%r{^../(frontend/|src/)?}, "") == asset_type
370
- end&.last
371
- end
367
+ return log_webpack_asset_error(asset_type) if asset_path.nil?
372
368
 
373
- if asset_path
374
- static_frontend_path(site, ["js", asset_path])
375
- else
376
- Bridgetown.logger.error("Unknown Webpack asset type", asset_type)
377
- nil
378
- end
369
+ static_frontend_path site, ["js", asset_path]
379
370
  end
380
371
 
381
372
  def static_frontend_path(site, additional_parts = [])
382
373
  path_parts = [
383
- site.config["baseurl"].to_s.gsub(%r(^/|/$), ""),
374
+ site.base_path.gsub(%r(^/|/$), ""),
384
375
  "_bridgetown/static",
385
376
  *additional_parts,
386
377
  ]
@@ -389,10 +380,13 @@ module Bridgetown
389
380
  end
390
381
 
391
382
  def log_webpack_asset_error(asset_type)
392
- error_message = "There was an error parsing your #{asset_type} files. \
393
- Please check your #{asset_type} for any errors."
383
+ Bridgetown.logger.warn(
384
+ "Webpack:",
385
+ "There was an error parsing your #{asset_type} file. \
386
+ Please check your #{asset_type} file for any errors."
387
+ )
394
388
 
395
- Bridgetown.logger.warn(Errors::WebpackAssetError, error_message)
389
+ "MISSING_WEBPACK_MANIFEST_FILE"
396
390
  end
397
391
 
398
392
  def default_github_branch_name(repo_url)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "0.21.0"
4
+ VERSION = "0.21.4"
5
5
  CODE_NAME = "Broughton Beach"
6
6
  end
@@ -257,7 +257,16 @@ end
257
257
 
258
258
  module Bridgetown
259
259
  module Model; end
260
- module Resource; end
260
+ module Resource
261
+ def self.register_extension(mod)
262
+ if mod.const_defined?(:LiquidResource)
263
+ Bridgetown::Drops::ResourceDrop.include mod.const_get(:LiquidResource)
264
+ end
265
+ if mod.const_defined?(:RubyResource)
266
+ Bridgetown::Resource::Base.include mod.const_get(:RubyResource)
267
+ end
268
+ end
269
+ end
261
270
  end
262
271
 
263
272
  # This method is available in Ruby 3, monkey patching for older versions
@@ -15,9 +15,13 @@
15
15
  # https://learnxinyminutes.com/docs/yaml/
16
16
  #
17
17
 
18
- baseurl: "" # OPTIONAL: the subpath of your site, e.g. /blog
19
18
  url: "" # the base hostname & protocol for your site, e.g. https://example.com
20
19
 
21
20
  permalink: pretty
22
21
 
22
+ # Other options you might want to investigate:
23
+ #
24
+ # base_path: "/" # the subpath of your site, e.g. /blog
23
25
  # timezone: America/Los_Angeles
26
+ # pagination:
27
+ # enabled: true
@@ -1,8 +1,8 @@
1
- <% if options["use-postcss"] %>
1
+ <%- if options["use-postcss"] -%>
2
2
  import "index.css"
3
- <% else %>
3
+ <%- else -%>
4
4
  import "index.scss"
5
- <% end %>
5
+ <%- end -%>
6
6
 
7
7
  // Import all javascript files from src/_components
8
8
  const componentsContext = require.context("bridgetownComponents", true, /.js$/)
@@ -13,28 +13,28 @@
13
13
  "start": "node start.js"
14
14
  },
15
15
  "devDependencies": {
16
- "@babel/core": "^7.9.0",
17
- "@babel/plugin-proposal-class-properties": "^7.8.3",
18
- "@babel/plugin-proposal-decorators": "^7.10.1",
19
- "@babel/plugin-transform-runtime": "^7.9.0",
20
- "@babel/preset-env": "^7.9.0",
21
- "babel-loader": "^8.1.0",
22
16
  "browser-sync": "^2.26.7",
23
17
  "concurrently": "^5.2.0",
24
18
  "css-loader": "^4.3.0",
19
+ "esbuild": "^0.12.7",
20
+ "esbuild-loader": "^2.13.1",
25
21
  "file-loader": "^6.2.0",
26
22
  "mini-css-extract-plugin": "^1.3.1",
27
- <% if options["use-postcss"] %>
23
+ <%- if options["use-postcss"] -%>
28
24
  "postcss": "^8.3.0",
29
25
  "postcss-flexbugs-fixes": "^4.1.0",
30
26
  "postcss-loader": "^4.3.0",
31
27
  "postcss-preset-env": "^6.7.0",
32
- <% else %>
28
+ <%- else -%>
33
29
  "sass": "^1.32.8",
34
30
  "sass-loader": "^8.0.2",
35
- <% end %>
36
- "webpack": "^4.44.2",
37
- "webpack-cli": "^3.3.11",
38
- "webpack-manifest-plugin": "^2.1.0"
31
+ <%- end -%>
32
+ "webpack": "^5.39.1",
33
+ "webpack-cli": "^4.7.2",
34
+ "webpack-manifest-plugin": "^3.1.1",
35
+ "webpack-merge": "^5.8.0"
36
+ },
37
+ "resolutions": {
38
+ "postcss-focus-within": "^4.0.0"
39
39
  }
40
40
  }
@@ -7,5 +7,5 @@
7
7
  title: Your awesome title
8
8
  tagline: This site is totally awesome
9
9
  email: your-email@example.com
10
- description: >- # this means to ignore newlines until "baseurl:"
10
+ description: >-
11
11
  Write an awesome description for your new site here. It will appear in your document head meta (for Google search results) and in your feed.xml site description.
@@ -8,9 +8,9 @@ const port = 4001
8
8
  // Concurrently
9
9
  /////////////////
10
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"}
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
14
  ], {
15
15
  restartTries: 3,
16
16
  killOthers: ['failure', 'success'],
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0
4
+ version: 0.21.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-01 00:00:00.000000000 Z
11
+ date: 2021-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel