bridgetown-core 1.1.0.beta3 → 1.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bridgetown +1 -3
  3. data/bridgetown-core.gemspec +7 -6
  4. data/lib/bridgetown-core/collection.rb +5 -2
  5. data/lib/bridgetown-core/commands/base.rb +1 -1
  6. data/lib/bridgetown-core/commands/build.rb +18 -5
  7. data/lib/bridgetown-core/commands/clean.rb +1 -1
  8. data/lib/bridgetown-core/commands/concerns/actions.rb +2 -4
  9. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +7 -8
  10. data/lib/bridgetown-core/commands/console.rb +20 -1
  11. data/lib/bridgetown-core/commands/esbuild/esbuild.config.js +5 -0
  12. data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +8 -7
  13. data/lib/bridgetown-core/commands/esbuild/migrate-from-webpack.rb +1 -1
  14. data/lib/bridgetown-core/commands/plugins.rb +46 -32
  15. data/lib/bridgetown-core/commands/serve.rb +1 -2
  16. data/lib/bridgetown-core/commands/start.rb +0 -8
  17. data/lib/bridgetown-core/component.rb +50 -0
  18. data/lib/bridgetown-core/concerns/site/configurable.rb +22 -18
  19. data/lib/bridgetown-core/concerns/site/localizable.rb +2 -6
  20. data/lib/bridgetown-core/concerns/site/processable.rb +0 -1
  21. data/lib/bridgetown-core/concerns/site/ssr.rb +0 -1
  22. data/lib/bridgetown-core/concerns/transformable.rb +5 -2
  23. data/lib/bridgetown-core/configuration/configuration_dsl.rb +146 -0
  24. data/lib/bridgetown-core/configuration.rb +92 -16
  25. data/lib/bridgetown-core/configurations/gh-pages/gh-pages.yml +3 -1
  26. data/lib/bridgetown-core/configurations/lit/esbuild-plugins.js +5 -2
  27. data/lib/bridgetown-core/configurations/minitesting.rb +1 -1
  28. data/lib/bridgetown-core/configurations/purgecss.rb +37 -25
  29. data/lib/bridgetown-core/configurations/shoelace.rb +25 -3
  30. data/lib/bridgetown-core/configurations/tailwindcss.rb +6 -4
  31. data/lib/bridgetown-core/converter.rb +8 -0
  32. data/lib/bridgetown-core/converters/identity.rb +2 -0
  33. data/lib/bridgetown-core/converters/liquid_templates.rb +1 -0
  34. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  35. data/lib/bridgetown-core/converters/markdown.rb +2 -0
  36. data/lib/bridgetown-core/current.rb +19 -5
  37. data/lib/bridgetown-core/deprecator.rb +4 -37
  38. data/lib/bridgetown-core/filters.rb +1 -3
  39. data/lib/bridgetown-core/generated_page.rb +5 -0
  40. data/lib/bridgetown-core/helpers.rb +119 -8
  41. data/lib/bridgetown-core/hooks.rb +1 -0
  42. data/lib/bridgetown-core/kramdown/parser/gfm.rb +1 -1
  43. data/lib/bridgetown-core/layout.rb +1 -1
  44. data/lib/bridgetown-core/model/base.rb +11 -12
  45. data/lib/bridgetown-core/model/builder_origin.rb +1 -1
  46. data/lib/bridgetown-core/model/origin.rb +5 -1
  47. data/lib/bridgetown-core/model/plugin_origin.rb +1 -1
  48. data/lib/bridgetown-core/model/repo_origin.rb +7 -7
  49. data/lib/bridgetown-core/plugin.rb +2 -6
  50. data/lib/bridgetown-core/plugin_manager.rb +120 -41
  51. data/lib/bridgetown-core/rack/boot.rb +3 -7
  52. data/lib/bridgetown-core/rack/logger.rb +1 -0
  53. data/lib/bridgetown-core/rack/roda.rb +39 -45
  54. data/lib/bridgetown-core/rack/routes.rb +2 -6
  55. data/lib/bridgetown-core/rack/static_indexes.rb +1 -2
  56. data/lib/bridgetown-core/reader.rb +39 -50
  57. data/lib/bridgetown-core/readers/layout_reader.rb +1 -1
  58. data/lib/bridgetown-core/resource/base.rb +17 -1
  59. data/lib/bridgetown-core/ruby_template_view.rb +12 -8
  60. data/lib/bridgetown-core/site.rb +10 -3
  61. data/lib/bridgetown-core/slot.rb +41 -0
  62. data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +23 -9
  63. data/lib/bridgetown-core/utils/ansi.rb +1 -1
  64. data/lib/bridgetown-core/utils/aux.rb +7 -6
  65. data/lib/bridgetown-core/utils/initializers.rb +45 -0
  66. data/lib/bridgetown-core/utils/loaders_manager.rb +2 -2
  67. data/lib/bridgetown-core/utils/require_gems.rb +11 -35
  68. data/lib/bridgetown-core/utils/ruby_front_matter.rb +2 -3
  69. data/lib/bridgetown-core/{converters/smartypants.rb → utils/smarty_pants_converter.rb} +5 -24
  70. data/lib/bridgetown-core/utils.rb +1 -0
  71. data/lib/bridgetown-core/version.rb +2 -2
  72. data/lib/bridgetown-core/watcher.rb +1 -8
  73. data/lib/bridgetown-core.rb +89 -6
  74. data/lib/roda/plugins/bridgetown_boot.rb +25 -0
  75. data/lib/roda/plugins/bridgetown_ssr.rb +23 -0
  76. data/lib/roda/plugins/initializers.rb +17 -0
  77. data/lib/site_template/.gitignore +1 -0
  78. data/lib/site_template/Gemfile.erb +1 -1
  79. data/lib/site_template/TEMPLATES/erb/_layouts/default.erb +2 -2
  80. data/lib/site_template/TEMPLATES/erb/_layouts/page.erb +1 -1
  81. data/lib/site_template/TEMPLATES/erb/_layouts/post.erb +1 -1
  82. data/lib/site_template/TEMPLATES/liquid/_layouts/default.liquid +2 -2
  83. data/lib/site_template/TEMPLATES/liquid/_layouts/page.liquid +1 -1
  84. data/lib/site_template/TEMPLATES/liquid/_layouts/post.liquid +1 -1
  85. data/lib/site_template/TEMPLATES/serbea/_layouts/default.serb +2 -2
  86. data/lib/site_template/TEMPLATES/serbea/_layouts/page.serb +1 -1
  87. data/lib/site_template/TEMPLATES/serbea/_layouts/post.serb +1 -1
  88. data/lib/site_template/config/initializers.rb +43 -0
  89. data/lib/site_template/package.json.erb +1 -1
  90. data/lib/site_template/server/roda_app.rb +2 -8
  91. metadata +15 -7
@@ -6,12 +6,15 @@ module Bridgetown
6
6
  # (requires a `converter` method to be present on the including class)
7
7
  #
8
8
  # @param document [Bridgetown::GeneratedPage, Bridgetown::Resource::Base]
9
+ # @param alternate_content [String, nil] Pass in content if you don't want to use document's
9
10
  # @return String
10
11
  # @yieldparam converter [Bridgetown::Converter]
11
12
  # @yieldparam index [Integer] index of the conversion step
12
13
  # @yieldparam output [String]
13
- def transform_content(document)
14
- converters.each_with_index.inject(document.content.to_s) do |content, (converter, index)|
14
+ def transform_content(document, alternate_content: nil)
15
+ converters.each_with_index.inject(
16
+ (alternate_content || document.content).to_s
17
+ ) do |content, (converter, index)|
15
18
  output = if converter.method(:convert).arity == 1
16
19
  converter.convert content
17
20
  else
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Configuration
5
+ class ConfigurationDSL < Bridgetown::Utils::RubyFrontMatter
6
+ attr_reader :context
7
+
8
+ # @yieldself [ConfigurationDSL]
9
+ def init(name, require_gem: true, require_initializer: true, **kwargs, &block) # rubocop:todo Metrics
10
+ return if @scope.initializers.key?(name.to_sym) &&
11
+ @scope.initializers[name.to_sym].completed
12
+
13
+ initializer = _setup_initializer(
14
+ name: name, require_gem: require_gem, require_initializer: require_initializer
15
+ )
16
+
17
+ return unless initializer.nil? || initializer.completed == false
18
+
19
+ set :init_params do
20
+ block ? set(name, &block) : set(name, kwargs)
21
+ end
22
+
23
+ if initializer.nil?
24
+ Bridgetown.logger.warn("Initializing:",
25
+ "The `#{name}' initializer could not be found")
26
+ return
27
+ end
28
+
29
+ Bridgetown.logger.debug "Initializing:", name
30
+ @scope.initializers[name.to_sym].block.(self, **@scope.init_params[name].symbolize_keys)
31
+ initializer.completed = true
32
+ end
33
+
34
+ def only(*context, &block)
35
+ return unless context.any? { _1 == @context }
36
+
37
+ instance_exec(&block)
38
+ end
39
+
40
+ def except(*context, &block)
41
+ return if context.any? { _1 == @context }
42
+
43
+ instance_exec(&block)
44
+ end
45
+
46
+ def hook(
47
+ owner,
48
+ event,
49
+ priority: Bridgetown::Hooks::DEFAULT_PRIORITY,
50
+ &block
51
+ )
52
+ Bridgetown::Hooks.register_one(owner, event, priority: priority, &block)
53
+ end
54
+
55
+ def source_manifest(**kwargs)
56
+ @scope.source_manifests << SourceManifest.new(**kwargs)
57
+ end
58
+
59
+ def builder(klass = nil, &block)
60
+ return klass.register if klass.is_a?(Bridgetown::Builder)
61
+
62
+ unless klass.is_a?(Symbol)
63
+ raise "You must supply a constant symbol to register an inline builder"
64
+ end
65
+
66
+ Object.const_set(
67
+ klass, Class.new(Bridgetown::Builder, &block).tap(&:register)
68
+ )
69
+ end
70
+
71
+ def roda(&block)
72
+ @scope.roda_initializers << block
73
+ end
74
+
75
+ def method_missing(key, *value, &block) # rubocop:disable Style/MissingRespondToMissing
76
+ return get(key) if value.length.zero? && block.nil?
77
+
78
+ set(key, value[0], &block)
79
+ end
80
+
81
+ def get(key)
82
+ unless @data.key?(key)
83
+ Bridgetown.logger.debug("Initializing:", "Uh oh, missing key `#{key}' in configuration")
84
+ end
85
+
86
+ super
87
+ end
88
+
89
+ def set(key, value = nil, &block)
90
+ # Handle nested data within a block
91
+ if block
92
+ value = self.class.new(scope: @scope).tap do |fm|
93
+ fm.instance_exec(&block)
94
+ end.to_h
95
+ end
96
+
97
+ key = key.to_s.delete_suffix("=") if key.to_s.ends_with?("=")
98
+
99
+ @data[key] = if @data[key].is_a?(Hash) && value.is_a?(Hash)
100
+ Bridgetown::Utils.deep_merge_hashes(@data[key], value)
101
+ else
102
+ value
103
+ end
104
+ end
105
+
106
+ def reflect(name, require_gem: true, require_initializer: true)
107
+ initializer = _setup_initializer(
108
+ name: name, require_gem: require_gem, require_initializer: require_initializer
109
+ )
110
+
111
+ if initializer.nil?
112
+ Bridgetown.logger.info("Reflection:",
113
+ "The `#{name}' initializer could not be found")
114
+ return
115
+ end
116
+
117
+ Bridgetown.logger.info(
118
+ "Reflection:",
119
+ "The #{name.to_s.yellow} initializer accepts the following options:"
120
+ )
121
+ initializer.block.parameters.each do |param|
122
+ next if param[0] == :opt
123
+
124
+ Bridgetown.logger.info("",
125
+ "* #{param[1].to_s.cyan}#{" (required)" if param[0] == :keyreq}")
126
+ end
127
+ end
128
+
129
+ # @return [Bridgetown::Configuration::Initializer]
130
+ def _setup_initializer(name:, require_gem:, require_initializer:)
131
+ Bridgetown::PluginManager.require_gem(name) if require_gem && !_in_require_denylist?(name)
132
+
133
+ if require_initializer
134
+ init_file_name = File.join(@scope.root_dir, "config", "#{name}.rb")
135
+ require(init_file_name) if File.exist?(init_file_name)
136
+ end
137
+
138
+ @scope.initializers[name.to_sym]
139
+ end
140
+
141
+ def _in_require_denylist?(name)
142
+ REQUIRE_DENYLIST.include?(name.to_sym)
143
+ end
144
+ end
145
+ end
146
+ end
@@ -1,20 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- # Holds the processed configuration loaded from the YAML config file.
5
- #
6
- # @todo refactor this whole object! Already had to fix obscure
7
- # bugs just making minor changes, and all the indirection is
8
- # quite hard to decipher. -JW
4
+ # The primary configuration object for a Bridgetown project
9
5
  class Configuration < HashWithDotAccess::Hash
10
- # Default options. Overridden by values in bridgetown.config.yml.
6
+ REQUIRE_DENYLIST = %i(parse_routes ssr) # rubocop:disable Style/MutableConstant
7
+
8
+ Initializer = Struct.new(:name, :block, :completed, keyword_init: true) do
9
+ def to_s
10
+ "#{name} (Initializer)"
11
+ end
12
+ end
13
+
14
+ SourceManifest = Struct.new(:origin, :components, :content, :layouts, keyword_init: true)
15
+
16
+ Preflight = Struct.new(:source_manifests, :initializers, keyword_init: true) do
17
+ def initialize(*)
18
+ super
19
+ self.source_manifests ||= Set.new
20
+ end
21
+ end
22
+
23
+ require_relative "configuration/configuration_dsl"
24
+
25
+ # Default options. Overridden by values in bridgetown.config.yml or initializers.
11
26
  # Strings rather than symbols are used for compatibility with YAML.
12
27
  DEFAULTS = {
13
28
  # Where things are
14
29
  "root_dir" => Dir.pwd,
15
30
  "plugins_dir" => "plugins",
16
- "source" => File.join(Dir.pwd, "src"),
17
- "destination" => File.join(Dir.pwd, "output"),
31
+ "source" => "src",
32
+ "destination" => "output",
18
33
  "collections_dir" => "",
19
34
  "cache_dir" => ".bridgetown-cache",
20
35
  "layouts_dir" => "_layouts",
@@ -48,7 +63,6 @@ module Bridgetown
48
63
  "content_engine" => "resource",
49
64
  "markdown" => "kramdown",
50
65
  "highlighter" => "rouge",
51
- "excerpt_separator" => "\n\n",
52
66
 
53
67
  # Serving
54
68
  "port" => "4000",
@@ -88,12 +102,15 @@ module Bridgetown
88
102
  },
89
103
  }.each_with_object(Configuration.new) { |(k, v), hsh| hsh[k] = v.freeze }.freeze
90
104
 
91
- # The modern default config file name is bridgetown.config.EXT, but we also
92
- # need to check for _config.EXT as a backward-compatibility nod to our
93
- # progenitor
105
+ # TODO: Deprecated. Remove support for _config as well as toml in the next release.
94
106
  CONFIG_FILE_PREFIXES = %w(bridgetown.config _config).freeze
95
107
  CONFIG_FILE_EXTS = %w(yml yaml toml).freeze
96
108
 
109
+ # @return [Hash<Symbol, Initializer>]
110
+ attr_accessor :initializers
111
+
112
+ attr_writer :source_manifests, :roda_initializers
113
+
97
114
  class << self
98
115
  # Static: Produce a Configuration ready for use in a Site.
99
116
  # It takes the input, fills in the defaults where values do not exist.
@@ -102,7 +119,7 @@ module Bridgetown
102
119
  #
103
120
  # Returns a Configuration filled with defaults.
104
121
  def from(user_config, starting_defaults = DEFAULTS)
105
- Utils.deep_merge_hashes(starting_defaults.deep_dup, Configuration[user_config])
122
+ Utils.deep_merge_hashes(starting_defaults.deep_dup, Configuration.new(user_config))
106
123
  .merge_environment_specific_options!
107
124
  .setup_load_paths!
108
125
  .setup_locales
@@ -112,6 +129,43 @@ module Bridgetown
112
129
  end
113
130
  end
114
131
 
132
+ def run_initializers!(context:)
133
+ initializers_file = File.join(root_dir, "config", "initializers.rb")
134
+ return unless File.file?(initializers_file)
135
+
136
+ require initializers_file
137
+
138
+ return unless initializers # no initializers have been set up
139
+
140
+ init_init = initializers[:init]
141
+ return unless init_init && !init_init.completed
142
+
143
+ Bridgetown.logger.debug "Initializing:", "Running initializers with `#{context}' context in:"
144
+ Bridgetown.logger.debug "", initializers_file
145
+ self.init_params = {}
146
+ dsl = ConfigurationDSL.new(scope: self, data: self)
147
+ dsl.instance_variable_set(:@context, context)
148
+ dsl.instance_exec(dsl, &init_init.block)
149
+
150
+ self
151
+ end
152
+
153
+ # @return [Set<SourceManifest>]
154
+ def source_manifests
155
+ @source_manifests ||= Set.new
156
+ end
157
+
158
+ # @return [Array<Proc>]
159
+ def roda_initializers
160
+ @roda_initializers ||= []
161
+ end
162
+
163
+ def initialize_roda_app(app)
164
+ roda_initializers.each do |initializer|
165
+ initializer.(app)
166
+ end
167
+ end
168
+
115
169
  def get_config_value_with_override(config_key, override)
116
170
  override[config_key] || self[config_key] || DEFAULTS[config_key]
117
171
  end
@@ -144,17 +198,35 @@ module Bridgetown
144
198
  end
145
199
  alias_method :verbose?, :verbose
146
200
 
147
- def safe_load_file(filename)
201
+ def safe_load_file(filename) # rubocop:todo Metrics
148
202
  case File.extname(filename)
149
203
  when %r!\.toml!i
204
+ Deprecator.deprecation_message(
205
+ "TOML configurations will no longer be supported in the next version of Bridgetown." \
206
+ "Use initializers or a .yaml config instead."
207
+ )
150
208
  Bridgetown::Utils::RequireGems.require_with_graceful_fail("tomlrb") unless defined?(Tomlrb)
151
209
  Tomlrb.load_file(filename)
152
210
  when %r!\.ya?ml!i
211
+ if File.basename(filename, ".*") == "_config"
212
+ Deprecator.deprecation_message(
213
+ "YAML configurations named `_config.y(a)ml' will no longer be supported in the next " \
214
+ "version of Bridgetown. Rename to `bridgetown.config.yml' instead."
215
+ )
216
+ end
217
+ if File.extname(filename) == ".yaml"
218
+ Deprecator.deprecation_message(
219
+ "YAML configurations ending in `.yaml' will no longer be supported in the next " \
220
+ "version of Bridgetown. Rename to use `.yml' extension instead."
221
+ )
222
+ end
153
223
  YAMLParser.load_file(filename) || {}
154
224
  else
155
225
  raise ArgumentError,
156
- "No parser for '#{filename}' is available. Use a .y(a)ml or .toml file instead."
226
+ "No parser for '#{filename}' is available. Use a .y(a)ml file instead."
157
227
  end
228
+ rescue Psych::DisallowedClass => e
229
+ raise "Unable to parse `#{File.basename(filename)}'. #{e.message}"
158
230
  end
159
231
 
160
232
  # Public: Generate list of configuration files from the override
@@ -251,7 +323,11 @@ module Bridgetown
251
323
  self
252
324
  end
253
325
 
254
- def setup_load_paths!
326
+ def setup_load_paths! # rubocop:todo Metrics
327
+ self[:root_dir] = File.expand_path(self[:root_dir])
328
+ self[:source] = File.expand_path(self[:source], self[:root_dir])
329
+ self[:destination] = File.expand_path(self[:destination], self[:root_dir])
330
+
255
331
  if self[:plugins_use_zeitwerk]
256
332
  autoload_paths.unshift({
257
333
  path: self[:plugins_dir],
@@ -24,7 +24,9 @@ jobs:
24
24
  - run: yarn install
25
25
 
26
26
  - name: Build
27
- run: bin/bridgetown deploy
27
+ env:
28
+ BRIDGETOWN_ENV: production
29
+ run: bin/bridgetown deploy
28
30
 
29
31
  - name: Deploy
30
32
  uses: peaceiris/actions-gh-pages@v3
@@ -5,14 +5,17 @@
5
5
  // This plugin will let you import `.lit.css` files as sidecar stylesheets.
6
6
  // Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
7
7
  const { litCssPlugin } = require("esbuild-plugin-lit-css")
8
- const postCssConfig = require("postcss-load-config").sync()
9
- const postCssProcessor = require("postcss")([...postCssConfig.plugins])
8
+ const postcssrc = require("postcss-load-config")
9
+ const postcss = require("postcss")
10
10
 
11
11
  module.exports = {
12
12
  plugins: [
13
13
  litCssPlugin({
14
14
  filter: /\.lit\.css$/,
15
15
  transform: async (css, { filePath }) => {
16
+ const postCssConfig = await postcssrc()
17
+ const postCssProcessor = postcss([...postCssConfig.plugins])
18
+
16
19
  const results = await postCssProcessor.process(css, { ...postCssConfig.options, from: filePath })
17
20
  return results.css
18
21
  }
@@ -38,7 +38,7 @@ create_file "test/helper.rb" do
38
38
  include Rails::Dom::Testing::Assertions
39
39
 
40
40
  def site
41
- @site ||= Bridgetown.sites.first
41
+ @site ||= Bridgetown::Current.site
42
42
  end
43
43
 
44
44
  def nokogiri(input)
@@ -10,33 +10,45 @@ create_builder "purgecss.rb" do
10
10
  <<~RUBY
11
11
  class Builders::Purgecss < SiteBuilder
12
12
  def build
13
- unless config[:watch] # don't run in "watch mode"
14
- hook :site, :post_write do
15
- purgecss_file = site.in_root_dir("purgecss.config.js")
16
- unless File.exist?(purgecss_file)
17
- config_js = <<~PURGE
18
- module.exports = {
19
- content: ['frontend/javascript/*.js','./output/**/*.html'],
20
- output: "./output/_bridgetown/static/css"
21
- }
22
- PURGE
23
- File.write(purgecss_file, config_js.strip)
24
- end
25
- manifest_file = File.join(site.frontend_bundling_path, "manifest.json")
26
- if File.exist?(manifest_file)
27
- manifest = JSON.parse(File.read(manifest_file))
28
- # TODO: make this work with esbuild too
13
+ return if config[:watch] # don't run in "watch mode"
14
+
15
+ hook :site, :post_write do
16
+ purgecss_file = site.in_root_dir("purgecss.config.js")
17
+
18
+ unless File.exist?(purgecss_file)
19
+ config_js = <<~PURGE
20
+ module.exports = {
21
+ content: ['frontend/javascript/*.js','./output/**/*.html'],
22
+ output: "./output/_bridgetown/static"
23
+ }
24
+ PURGE
25
+ File.write(purgecss_file, config_js.strip)
26
+ end
27
+
28
+ manifest_file = File.join(site.frontend_bundling_path, "manifest.json")
29
+
30
+ if File.exist?(manifest_file)
31
+ manifest = JSON.parse(File.read(manifest_file))
32
+
33
+ if Bridgetown::Utils.frontend_bundler_type == :esbuild
34
+ css_file = manifest["styles/index.css"].split("/").last
35
+ css_path = ["output", "_bridgetown", "static", css_file].join("/")
36
+ else
29
37
  css_file = manifest["main.css"].split("/").last
30
38
  css_path = ["output", "_bridgetown", "static", "css", css_file].join("/")
31
- Bridgetown.logger.info "PurgeCSS", "Purging \#{css_file}"
32
- oldsize = File.stat(css_path).size / 1000
33
- system "./node_modules/.bin/purgecss -c purgecss.config.js -css \#{css_path}"
34
- newsize = File.stat(css_path).size / 1000
35
- if newsize < oldsize
36
- Bridgetown.logger.info "PurgeCSS", "Done! File size reduced from \#{oldsize}kB to \#{newsize}kB"
37
- else
38
- Bridgetown.logger.info "PurgeCSS", "Done. No apparent change in file size (\#{newsize}kB)."
39
- end
39
+ end
40
+
41
+ Bridgetown.logger.info "PurgeCSS", "Purging \#{css_file}"
42
+ oldsize = File.stat(css_path).size / 1000
43
+ system "./node_modules/.bin/purgecss -c purgecss.config.js -css \#{css_path}"
44
+ newsize = File.stat(css_path).size / 1000
45
+
46
+ if newsize < oldsize
47
+ Bridgetown.logger.info "PurgeCSS",
48
+ "Done! File size reduced from \#{oldsize}kB to \#{newsize}kB"
49
+ else
50
+ Bridgetown.logger.info "PurgeCSS",
51
+ "Done. No apparent change in file size (\#{newsize}kB)."
40
52
  end
41
53
  end
42
54
  end
@@ -4,14 +4,27 @@ say_status :shoelace, "Installing Shoelace..."
4
4
 
5
5
  run "yarn add @shoelace-style/shoelace"
6
6
 
7
+ stylesheet_import = <<~CSS
8
+ /* Import the base Shoelace stylesheet: */
9
+ @import "@shoelace-style/shoelace/dist/themes/light.css";
10
+
11
+ CSS
12
+
13
+ if File.exist?("frontend/styles/index.css")
14
+ prepend_to_file "frontend/styles/index.css", stylesheet_import
15
+ elsif File.exist?("frontend/styles/index.scss")
16
+ prepend_to_file "frontend/styles/index.scss", stylesheet_import
17
+ else
18
+ say "\nPlease add the following lines to your CSS index file:"
19
+ say stylesheet_import
20
+ end
21
+
7
22
  say 'Adding Shoelace to "frontend/javascript/index.js"...', :magenta
8
23
 
9
24
  javascript_import do
10
25
  <<~JS
11
- // Import the base Shoelace stylesheet:
12
- import "@shoelace-style/shoelace/dist/themes/light.css"
13
26
 
14
- // Example components, mix 'n' match however you like!
27
+ // Example Shoelace components. Mix 'n' match however you like!
15
28
  import "@shoelace-style/shoelace/dist/components/button/button.js"
16
29
  import "@shoelace-style/shoelace/dist/components/icon/icon.js"
17
30
  import "@shoelace-style/shoelace/dist/components/spinner/spinner.js"
@@ -45,6 +58,15 @@ else
45
58
  '"webpack-dev": "yarn shoelace:copy-assets && webpack'
46
59
  end
47
60
 
61
+ if File.exist?(".gitignore")
62
+ append_to_file ".gitignore" do
63
+ <<~FILES
64
+
65
+ src/shoelace-assets
66
+ FILES
67
+ end
68
+ end
69
+
48
70
  say_status :shoelace, "Shoelace is now configured!"
49
71
 
50
72
  say 'For further reading, check out "https://shoelace.style"', :blue
@@ -45,11 +45,13 @@ insert_into_file "Rakefile",
45
45
  JS
46
46
  end
47
47
 
48
- append_to_file ".gitignore" do
49
- <<~FILES
48
+ if File.exist?(".gitignore")
49
+ append_to_file ".gitignore" do
50
+ <<~FILES
50
51
 
51
- frontend/styles/jit-refresh.css
52
- FILES
52
+ frontend/styles/jit-refresh.css
53
+ FILES
54
+ end
53
55
  end
54
56
 
55
57
  create_builder "tailwind_jit.rb" do
@@ -14,6 +14,14 @@ module Bridgetown
14
14
  self.extname_list ||= []
15
15
  self.extname_list += extnames.map { |e| ".#{e.to_s.downcase}" }
16
16
  end
17
+
18
+ def supports_slots?
19
+ @support_slots == true
20
+ end
21
+
22
+ def support_slots(bool = true) # rubocop:disable Style/OptionalBooleanParameter
23
+ @support_slots = bool == true
24
+ end
17
25
  end
18
26
 
19
27
  # Initialize the converter.
@@ -7,6 +7,8 @@ module Bridgetown
7
7
  class Identity < Converter
8
8
  priority :lowest
9
9
 
10
+ support_slots
11
+
10
12
  # Public: Does the given extension match this converter's list of acceptable extensions?
11
13
  # Takes one argument: the file's extension (including the dot).
12
14
  #
@@ -89,6 +89,7 @@ module Bridgetown
89
89
  payload["paginator"] = document.respond_to?(:paginator) ? document.paginator.to_liquid : nil
90
90
  payload["layout"] = @layout ? @layout.to_liquid.merge({ data: @layout.data }) : {}
91
91
  payload["content"] = content
92
+ payload["data"] = payload["page"].data
92
93
  end
93
94
 
94
95
  def liquid_context
@@ -1,4 +1,4 @@
1
- # Frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Kramdown
4
4
  # A Kramdown::Document subclass meant to optimize memory usage from initializing
@@ -5,6 +5,8 @@ module Bridgetown
5
5
  # Markdown converter.
6
6
  # For more info on converters see https://bridgetownrb.com/docs/plugins/converters/
7
7
  class Markdown < Converter
8
+ support_slots
9
+
8
10
  def initialize(config = {})
9
11
  super
10
12
 
@@ -2,13 +2,27 @@
2
2
 
3
3
  module Bridgetown
4
4
  class Current < ActiveSupport::CurrentAttributes
5
- # @!method self.site
6
- # @return [Bridgetown::Site]
7
-
8
- attribute :site
9
-
10
5
  # @!method self.preloaded_configuration
11
6
  # @return [Bridgetown::Configuration]
12
7
  attribute :preloaded_configuration
8
+
9
+ # @return [Bridgetown::Site, nil]
10
+ def self.site
11
+ sites[:main]
12
+ end
13
+
14
+ def self.site=(new_site)
15
+ sites[:main] = new_site
16
+ end
17
+
18
+ # @!method self.sites
19
+ # @return [Hash<Symbol, Bridgetown::Site>]
20
+
21
+ attribute :sites
22
+
23
+ def initialize
24
+ super
25
+ @attributes[:sites] = {}
26
+ end
13
27
  end
14
28
  end
@@ -2,45 +2,12 @@
2
2
 
3
3
  module Bridgetown
4
4
  module Deprecator
5
- extend self
6
-
7
- def process(args)
8
- arg_is_present? args, "--server", "The --server command has been replaced by the \
9
- 'serve' subcommand."
10
- arg_is_present? args, "--serve", "The --serve command has been replaced by the \
11
- 'serve' subcommand."
12
- arg_is_present? args, "--no-server", "To build Bridgetown without launching a server, \
13
- use the 'build' subcommand."
14
- arg_is_present? args, "--auto", "The switch '--auto' has been replaced with \
15
- '--watch'."
16
- arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \
17
- the '--watch' switch."
18
- arg_is_present? args, "--url", "The 'url' setting can only be set in your \
19
- config files."
20
- no_subcommand(args)
21
- end
22
-
23
- def no_subcommand(args)
24
- unless args.empty? ||
25
- args.first !~ %r(!/^--/!) || %w(--help --version).include?(args.first)
26
- deprecation_message "Bridgetown now uses subcommands instead of just switches. \
27
- Run `bridgetown help` to find out more."
28
- abort
29
- end
30
- end
31
-
32
- def arg_is_present?(args, deprecated_argument, message)
33
- deprecation_message(message) if args.include?(deprecated_argument)
34
- end
35
-
36
- def deprecation_message(message)
5
+ def self.deprecation_message(message)
37
6
  Bridgetown.logger.warn "Deprecation:", message
38
- end
39
7
 
40
- def defaults_deprecate_type(old, current)
41
- Bridgetown.logger.warn "Defaults:", "The '#{old}' type has become '#{current}'."
42
- Bridgetown.logger.warn "Defaults:", "Please update your front-matter defaults to use \
43
- 'type: #{current}'."
8
+ caller_locations[0..1].each_with_index do |backtrace_line, index|
9
+ Bridgetown.logger.debug "#{index + 1}:", backtrace_line
10
+ end
44
11
  end
45
12
  end
46
13
  end
@@ -26,9 +26,7 @@ module Bridgetown
26
26
  #
27
27
  # Returns the smart-quotified String.
28
28
  def smartify(input)
29
- @context.registers[:site].find_converter_instance(
30
- Bridgetown::Converters::SmartyPants
31
- ).convert(input.to_s)
29
+ Utils::SmartyPantsConverter.new(@context.registers[:site].config).convert(input.to_s)
32
30
  end
33
31
 
34
32
  # Slugify a filename or title.