bridgetown-core 0.20.0 → 0.21.0

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/bridgetown-core.gemspec +0 -1
  3. data/lib/bridgetown-core.rb +11 -22
  4. data/lib/bridgetown-core/cleaner.rb +2 -2
  5. data/lib/bridgetown-core/collection.rb +14 -11
  6. data/lib/bridgetown-core/commands/build.rb +0 -11
  7. data/lib/bridgetown-core/commands/concerns/git_helpers.rb +20 -0
  8. data/lib/bridgetown-core/commands/configure.rb +4 -3
  9. data/lib/bridgetown-core/commands/doctor.rb +1 -19
  10. data/lib/bridgetown-core/commands/new.rb +6 -6
  11. data/lib/bridgetown-core/commands/plugins.rb +14 -13
  12. data/lib/bridgetown-core/commands/serve.rb +0 -14
  13. data/lib/bridgetown-core/commands/webpack.rb +75 -0
  14. data/lib/bridgetown-core/commands/webpack/enable-postcss.rb +12 -0
  15. data/lib/bridgetown-core/commands/webpack/setup.rb +4 -0
  16. data/lib/bridgetown-core/commands/webpack/update.rb +3 -0
  17. data/lib/bridgetown-core/commands/webpack/webpack.config.js +18 -0
  18. data/lib/{site_template/webpack.config.js.erb → bridgetown-core/commands/webpack/webpack.defaults.js.erb} +25 -11
  19. data/lib/bridgetown-core/component.rb +183 -0
  20. data/lib/bridgetown-core/concerns/front_matter_importer.rb +52 -0
  21. data/lib/bridgetown-core/concerns/layout_placeable.rb +1 -1
  22. data/lib/bridgetown-core/concerns/site/configurable.rb +3 -7
  23. data/lib/bridgetown-core/concerns/site/content.rb +2 -3
  24. data/lib/bridgetown-core/concerns/site/localizable.rb +3 -5
  25. data/lib/bridgetown-core/concerns/site/processable.rb +5 -4
  26. data/lib/bridgetown-core/concerns/site/writable.rb +1 -1
  27. data/lib/bridgetown-core/concerns/validatable.rb +1 -5
  28. data/lib/bridgetown-core/configuration.rb +22 -14
  29. data/lib/bridgetown-core/configurations/bt-postcss.rb +6 -6
  30. data/lib/bridgetown-core/configurations/netlify.rb +1 -0
  31. data/lib/bridgetown-core/configurations/tailwindcss.rb +6 -6
  32. data/lib/bridgetown-core/converter.rb +9 -0
  33. data/lib/bridgetown-core/converters/erb_templates.rb +51 -35
  34. data/lib/bridgetown-core/converters/liquid_templates.rb +1 -1
  35. data/lib/bridgetown-core/converters/markdown.rb +1 -1
  36. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +2 -38
  37. data/lib/bridgetown-core/converters/ruby_templates.rb +17 -0
  38. data/lib/bridgetown-core/converters/smartypants.rb +3 -1
  39. data/lib/bridgetown-core/core_ext/psych.rb +19 -0
  40. data/lib/bridgetown-core/document.rb +3 -2
  41. data/lib/bridgetown-core/drops/relations_drop.rb +23 -0
  42. data/lib/bridgetown-core/drops/resource_drop.rb +3 -1
  43. data/lib/bridgetown-core/drops/unified_payload_drop.rb +1 -0
  44. data/lib/bridgetown-core/entry_filter.rb +7 -5
  45. data/lib/bridgetown-core/filters.rb +1 -25
  46. data/lib/bridgetown-core/filters/from_liquid.rb +23 -0
  47. data/lib/bridgetown-core/filters/url_filters.rb +12 -0
  48. data/lib/bridgetown-core/frontmatter_defaults.rb +1 -1
  49. data/lib/bridgetown-core/generators/prototype_generator.rb +25 -4
  50. data/lib/bridgetown-core/helpers.rb +48 -9
  51. data/lib/bridgetown-core/layout.rb +52 -20
  52. data/lib/bridgetown-core/model/origin.rb +1 -1
  53. data/lib/bridgetown-core/model/{file_origin.rb → repo_origin.rb} +33 -26
  54. data/lib/bridgetown-core/page.rb +2 -1
  55. data/lib/bridgetown-core/plugin_manager.rb +1 -1
  56. data/lib/bridgetown-core/publisher.rb +2 -2
  57. data/lib/bridgetown-core/reader.rb +13 -11
  58. data/lib/bridgetown-core/readers/data_reader.rb +2 -1
  59. data/lib/bridgetown-core/readers/defaults_reader.rb +1 -1
  60. data/lib/bridgetown-core/readers/layout_reader.rb +1 -1
  61. data/lib/bridgetown-core/readers/page_reader.rb +1 -0
  62. data/lib/bridgetown-core/readers/post_reader.rb +5 -4
  63. data/lib/bridgetown-core/regenerator.rb +1 -1
  64. data/lib/bridgetown-core/related_posts.rb +8 -5
  65. data/lib/bridgetown-core/renderer.rb +1 -1
  66. data/lib/bridgetown-core/resource/base.rb +80 -26
  67. data/lib/bridgetown-core/resource/permalink_processor.rb +1 -1
  68. data/lib/bridgetown-core/resource/relations.rb +132 -0
  69. data/lib/bridgetown-core/resource/taxonomy_term.rb +10 -1
  70. data/lib/bridgetown-core/resource/taxonomy_type.rb +9 -0
  71. data/lib/bridgetown-core/resource/transformer.rb +18 -14
  72. data/lib/bridgetown-core/ruby_template_view.rb +7 -11
  73. data/lib/bridgetown-core/site.rb +4 -5
  74. data/lib/bridgetown-core/tags/highlight.rb +2 -15
  75. data/lib/bridgetown-core/tags/include.rb +1 -1
  76. data/lib/bridgetown-core/tags/post_url.rb +2 -2
  77. data/lib/bridgetown-core/utils.rb +9 -3
  78. data/lib/bridgetown-core/utils/require_gems.rb +60 -0
  79. data/lib/bridgetown-core/utils/ruby_exec.rb +6 -9
  80. data/lib/bridgetown-core/utils/ruby_front_matter.rb +39 -0
  81. data/lib/bridgetown-core/version.rb +2 -2
  82. data/lib/bridgetown-core/watcher.rb +2 -1
  83. data/lib/bridgetown-core/yaml_parser.rb +22 -0
  84. data/lib/site_template/config/.keep +0 -0
  85. data/lib/site_template/package.json.erb +4 -4
  86. data/lib/site_template/plugins/site_builder.rb +1 -1
  87. data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
  88. metadata +21 -23
  89. data/lib/bridgetown-core/external.rb +0 -58
  90. data/lib/bridgetown-core/path_manager.rb +0 -31
  91. data/lib/bridgetown-core/readers/static_file_reader.rb +0 -25
  92. data/lib/bridgetown-core/utils/platforms.rb +0 -81
  93. data/lib/bridgetown-core/utils/thread_event.rb +0 -31
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Commands
5
+ class Webpack < Thor::Group
6
+ include Thor::Actions
7
+ extend Summarizable
8
+
9
+ Registrations.register do
10
+ register(Webpack, "webpack", "webpack ACTION", Webpack.summary)
11
+ end
12
+
13
+ def self.banner
14
+ "bridgetown webpack ACTION"
15
+ end
16
+ summary "Perform actions on the bridgetown webpack configuration"
17
+
18
+ def self.exit_on_failure?
19
+ true
20
+ end
21
+
22
+ def webpack
23
+ @logger = Bridgetown.logger
24
+ return show_actions if args.empty?
25
+
26
+ action = args.first
27
+ if supported_actions.include?(action)
28
+ perform action
29
+ else
30
+ @logger.error "Error:".red, "🚨 Please enter a valid action."
31
+ say "\n"
32
+ show_actions
33
+ end
34
+ end
35
+
36
+ def self.source_root
37
+ File.expand_path("./webpack", __dir__)
38
+ end
39
+
40
+ def self.destination_root
41
+ config.root_dir
42
+ end
43
+
44
+ def config
45
+ @config ||= Bridgetown.configuration({ root_dir: Dir.pwd })
46
+ end
47
+
48
+ protected
49
+
50
+ def perform(action)
51
+ automation = find_in_source_paths("#{action}.rb")
52
+ inside(New.created_site_dir || Dir.pwd) do
53
+ apply automation, verbose: false
54
+ end
55
+ end
56
+
57
+ def show_actions
58
+ say "Available actions:\n".bold
59
+
60
+ longest_action = supported_actions.keys.max_by(&:size).size
61
+ supported_actions.each do |action, description|
62
+ say action.ljust(longest_action).to_s.bold.blue + "\t" + "# #{description}"
63
+ end
64
+ end
65
+
66
+ def supported_actions
67
+ {
68
+ setup: "Sets up a webpack integration with Bridgetown in your project",
69
+ update: "Updates the Bridgetown webpack defaults to the latest available version",
70
+ "enable-postcss": "Configures PostCSS in your project",
71
+ }.with_indifferent_access
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ default_postcss_config = File.expand_path("../../../site_template/postcss.config.js.erb", __dir__)
4
+
5
+ template default_postcss_config, "postcss.config.js"
6
+ template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
7
+
8
+ unless Bridgetown.environment.test?
9
+ packages = %w(postcss@8.3.0 postcss-loader@4.3.0 postcss-flexbugs-fixes postcss-preset-env)
10
+ run "yarn add -D #{packages.join(" ")}"
11
+ run "yarn remove sass sass-loader"
12
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ template "webpack.defaults.js.erb", "config/webpack.defaults.js"
4
+ copy_file "webpack.config.js", force: true
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
@@ -0,0 +1,18 @@
1
+ const config = require("./config/webpack.defaults.js")
2
+
3
+ // Add any overrides to the default webpack config here:
4
+
5
+ // Eg:
6
+ //
7
+ // ```
8
+ // const path = require("path")
9
+ // config.resolve.modules.push(path.resolve(__dirname, 'frontend', 'components'))
10
+ // config.resolve.alias.frontendComponents = path.resolve(__dirname, 'frontend', 'components')
11
+ // ```
12
+
13
+
14
+
15
+
16
+ ////////////////////////////////////////////////////////
17
+
18
+ module.exports = config
@@ -1,10 +1,21 @@
1
+ // This file is created and managed by Bridgetown.
2
+ // Instead of editing this file, add your overrides to `webpack.config.js`
3
+ //
4
+ // To update this file to the latest version provided by Bridgetown,
5
+ // run `bridgetown webpack update`. Any changes to this file will be overwritten
6
+ // when an update is applied hence we strongly recommend adding overrides to
7
+ // `webpack.config.js` instead of editing this file.
8
+ //
9
+ // Shipped with Bridgetown v<%= Bridgetown::VERSION %>
10
+
1
11
  const path = require("path");
12
+ const rootDir = path.resolve(__dirname, "..")
2
13
  const MiniCssExtractPlugin = require("mini-css-extract-plugin");
3
14
  const ManifestPlugin = require("webpack-manifest-plugin");
4
15
 
5
16
  module.exports = {
6
17
  entry: {
7
- main: "./frontend/javascript/index.js"
18
+ main: path.resolve(rootDir, "frontend", "javascript", "index.js")
8
19
  },
9
20
  devtool: "source-map",
10
21
  // Set some or all of these to true if you want more verbose logging:
@@ -15,18 +26,18 @@ module.exports = {
15
26
  children: false,
16
27
  },
17
28
  output: {
18
- path: path.resolve(__dirname, "output", "_bridgetown", "static", "js"),
29
+ path: path.resolve(rootDir, "output", "_bridgetown", "static", "js"),
19
30
  filename: "[name].[contenthash].js",
20
31
  },
21
32
  resolve: {
22
33
  extensions: [".js", ".jsx"],
23
34
  modules: [
24
- path.resolve(__dirname, 'frontend', 'javascript'),
25
- path.resolve(__dirname, 'frontend', 'styles'),
26
- path.resolve('./node_modules')
35
+ path.resolve(rootDir, 'frontend', 'javascript'),
36
+ path.resolve(rootDir, 'frontend', 'styles'),
37
+ path.resolve(rootDir, 'node_modules')
27
38
  ],
28
39
  alias: {
29
- bridgetownComponents: path.resolve(__dirname, "src", "_components")
40
+ bridgetownComponents: path.resolve(rootDir, "src", "_components")
30
41
  }
31
42
  },
32
43
  plugins: [
@@ -34,7 +45,7 @@ module.exports = {
34
45
  filename: "../css/[name].[contenthash].css",
35
46
  }),
36
47
  new ManifestPlugin({
37
- fileName: path.resolve(__dirname, ".bridgetown-webpack", "manifest.json"),
48
+ fileName: path.resolve(rootDir, ".bridgetown-webpack", "manifest.json"),
38
49
  }),
39
50
  ],
40
51
  module: {
@@ -54,11 +65,12 @@ module.exports = {
54
65
  helpers: false,
55
66
  },
56
67
  ],
68
+ ["@babel/plugin-proposal-private-methods", { "loose": true }],
57
69
  ],
58
70
  },
59
71
  },
60
72
  },
61
- <% if options["use-postcss"] %>
73
+ <% if self.config.uses_postcss? %>
62
74
  {
63
75
  test: /\.(s[ac]|c)ss$/,
64
76
  use: [
@@ -72,7 +84,7 @@ module.exports = {
72
84
  },
73
85
  "postcss-loader"
74
86
  ],
75
- },
87
+ },
76
88
  <% else %>
77
89
  {
78
90
  test: /\.(s[ac]|c)ss$/,
@@ -87,9 +99,11 @@ module.exports = {
87
99
  {
88
100
  loader: "sass-loader",
89
101
  options: {
102
+ implementation: require("sass"),
90
103
  sassOptions: {
104
+ fiber: false,
91
105
  includePaths: [
92
- path.resolve(__dirname, "src/_components")
106
+ path.resolve(rootDir, "src/_components")
93
107
  ],
94
108
  },
95
109
  },
@@ -117,4 +131,4 @@ module.exports = {
117
131
  },
118
132
  ],
119
133
  },
120
- };
134
+ };
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Component
5
+ extend Forwardable
6
+
7
+ def_delegators :@view_context, :helpers, :liquid_render, :partial
8
+
9
+ # @return [Bridgetown::Site]
10
+ attr_reader :site # will be nil unless you explicitly set a `@site` ivar
11
+
12
+ # @return [Bridgetown::RubyTemplateView, Bridgetown::Component]
13
+ attr_reader :view_context
14
+
15
+ class << self
16
+ attr_accessor :source_location
17
+
18
+ def inherited(child)
19
+ # Code cribbed from ViewComponent by GitHub:
20
+ # Derive the source location of the component Ruby file from the call stack
21
+ child.source_location = caller_locations(1, 10).reject do |l|
22
+ l.label == "inherited"
23
+ end[0].absolute_path
24
+
25
+ super
26
+ end
27
+
28
+ # Return the appropriate template renderer for a given extension.
29
+ # TODO: make this extensible
30
+ #
31
+ # @param ext [String] erb, slim, etc.
32
+ def renderer_for_ext(ext, &block)
33
+ @_tmpl ||= case ext
34
+ when "erb"
35
+ include ERBCapture
36
+ Tilt::ErubiTemplate.new(component_template_path,
37
+ outvar: "@_erbout",
38
+ bufval: "Bridgetown::OutputBuffer.new",
39
+ engine_class: Bridgetown::ERBEngine,
40
+ &block)
41
+ when "serb" # requires serbea
42
+ include Serbea::Helpers
43
+ Tilt::SerbeaTemplate.new(component_template_path, &block)
44
+ when "slim" # requires bridgetown-slim
45
+ Slim::Template.new(component_template_path, &block)
46
+ when "haml" # requires bridgetown-haml
47
+ Tilt::HamlTemplate.new(component_template_path, &block)
48
+ else
49
+ raise NameError
50
+ end
51
+ rescue NameError, LoadError
52
+ raise "No component rendering engine could be found for .#{ext} templates"
53
+ end
54
+
55
+ # Find the first matching template path based on source location and extension.
56
+ #
57
+ # @return [String]
58
+ def component_template_path
59
+ @_tmpl_path ||= begin
60
+ stripped_path = File.join(
61
+ File.dirname(source_location),
62
+ File.basename(source_location, ".*")
63
+ )
64
+ supported_template_extensions.each do |ext|
65
+ test_path = "#{stripped_path}.#{ext}"
66
+ break test_path if File.exist?(test_path)
67
+
68
+ test_path = "#{stripped_path}.html.#{ext}"
69
+ break test_path if File.exist?(test_path)
70
+ end
71
+ end
72
+
73
+ unless @_tmpl_path.is_a?(String)
74
+ raise "#{name}: no matching template could be found in #{File.dirname(source_location)}"
75
+ end
76
+
77
+ @_tmpl_path
78
+ end
79
+
80
+ # Read the template file.
81
+ #
82
+ # @return [String]
83
+ def component_template_content
84
+ @_tmpl_content ||= File.read(component_template_path)
85
+ end
86
+
87
+ # A list of extensions supported by the renderer
88
+ # TODO: make this extensible
89
+ #
90
+ # @return [Array<String>]
91
+ def supported_template_extensions
92
+ %w(erb serb slim haml)
93
+ end
94
+ end
95
+
96
+ # If a content block was originally passed into via `render`, capture its output.
97
+ #
98
+ # @return [String] or nil
99
+ def content
100
+ @_content ||= begin
101
+ view_context.capture(self, &@_content_block) if @_content_block
102
+ end
103
+ end
104
+
105
+ # Provide a render helper for evaluation within the component context.
106
+ #
107
+ # @param item [Object] a component supporting `render_in` or a partial name
108
+ # @param options [Hash] passed to the `partial` helper if needed
109
+ # @return [String]
110
+ def render(item, options = {}, &block)
111
+ if item.respond_to?(:render_in)
112
+ result = ""
113
+ capture do # this ensures no leaky interactions between BT<=>VC blocks
114
+ result = item.render_in(self, &block)
115
+ end
116
+ result&.html_safe
117
+ else
118
+ partial(item, options, &block)&.html_safe
119
+ end
120
+ end
121
+
122
+ # This is where the magic happens. Render the component within a view context.
123
+ #
124
+ # @param view_context [Bridgetown::RubyTemplateView]
125
+ def render_in(view_context, &block)
126
+ @view_context = view_context
127
+ @_content_block = block
128
+
129
+ if render?
130
+ before_render
131
+ template
132
+ else
133
+ ""
134
+ end
135
+ rescue StandardError => e
136
+ Bridgetown.logger.error "Component error:",
137
+ "#{self.class} encountered an error while "\
138
+ "rendering `#{self.class.component_template_path}'"
139
+ raise e
140
+ end
141
+
142
+ # Subclasses can override this method to return a string from their own
143
+ # template handling.
144
+ def template
145
+ call || _renderer.render(self)
146
+ end
147
+
148
+ # Typically not used but here as a compatibility nod toward ViewComponent.
149
+ def call
150
+ nil
151
+ end
152
+
153
+ # Subclasses can override this method to perform tasks before a render.
154
+ def before_render; end
155
+
156
+ # Subclasses can override this method to determine if the component should
157
+ # be rendered based on initialized data or other logic.
158
+ def render?
159
+ true
160
+ end
161
+
162
+ def _renderer
163
+ @_renderer ||= begin
164
+ ext = File.extname(self.class.component_template_path).delete_prefix(".")
165
+ self.class.renderer_for_ext(ext) { self.class.component_template_content }
166
+ end
167
+ end
168
+
169
+ # rubocop:disable Style/MissingRespondToMissing
170
+ ruby2_keywords def method_missing(method, *args, &block)
171
+ if helpers.respond_to?(method.to_sym)
172
+ helpers.send method.to_sym, *args, &block
173
+ else
174
+ super
175
+ end
176
+ end
177
+
178
+ def respond_to_missing?(method, include_private = false)
179
+ helpers.respond_to?(method.to_sym, include_private) || super
180
+ end
181
+ # rubocop:enable Style/MissingRespondToMissing
182
+ end
183
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module FrontMatterImporter
5
+ # Requires klass#content and klass#front_matter_line_count accessors
6
+ def self.included(klass)
7
+ klass.include Bridgetown::Utils::RubyFrontMatterDSL
8
+ end
9
+
10
+ YAML_HEADER = %r!\A---\s*\n!.freeze
11
+ YAML_BLOCK = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
12
+ RUBY_HEADER = %r!\A[~`#\-]{3,}(?:ruby|<%|{%)\s*\n!.freeze
13
+ RUBY_BLOCK =
14
+ %r!#{RUBY_HEADER.source}(.*?\n?)^((?:%>|%})?[~`#\-]{3,}\s*$\n?)!m.freeze
15
+
16
+ def read_front_matter(file_path) # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
17
+ file_contents = File.read(
18
+ file_path, **Bridgetown::Utils.merged_file_read_opts(Bridgetown::Current.site, {})
19
+ )
20
+ yaml_content = file_contents.match(YAML_BLOCK)
21
+ if !yaml_content && Bridgetown::Current.site.config.should_execute_inline_ruby?
22
+ ruby_content = file_contents.match(RUBY_BLOCK)
23
+ end
24
+
25
+ if yaml_content
26
+ self.content = yaml_content.post_match
27
+ self.front_matter_line_count = yaml_content[1].lines.size - 1
28
+ YAMLParser.load(yaml_content[1])
29
+ elsif ruby_content
30
+ # rbfm header + content underneath
31
+ self.content = ruby_content.post_match
32
+ self.front_matter_line_count = ruby_content[1].lines.size
33
+ process_ruby_data(ruby_content[1], file_path, 2)
34
+ elsif Bridgetown::Utils.has_rbfm_header?(file_path)
35
+ process_ruby_data(File.read(file_path).lines[1..-1].join("\n"), file_path, 2)
36
+ elsif is_a?(Layout)
37
+ self.content = file_contents
38
+ {}
39
+ else
40
+ yaml_data = YAMLParser.load_file(file_path)
41
+ yaml_data.is_a?(Array) ? { rows: yaml_data } : yaml_data
42
+ end
43
+ end
44
+
45
+ def process_ruby_data(rubycode, file_path, starting_line)
46
+ ruby_data = instance_eval(rubycode, file_path.to_s, starting_line)
47
+ ruby_data.is_a?(Array) ? { rows: ruby_data } : ruby_data.to_h
48
+ rescue StandardError => e
49
+ raise "Ruby code isn't returning an array, or object which responds to `to_h' (#{e.message})"
50
+ end
51
+ end
52
+ end