bridgetown-core 0.21.0 → 0.21.4

Sign up to get free protection for your applications and to get access to all the features.
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