bridgetown-core 0.19.0 → 0.21.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bridgetown +6 -0
  3. data/bridgetown-core.gemspec +3 -4
  4. data/lib/bridgetown-core.rb +34 -12
  5. data/lib/bridgetown-core/cleaner.rb +7 -1
  6. data/lib/bridgetown-core/collection.rb +176 -77
  7. data/lib/bridgetown-core/commands/apply.rb +4 -3
  8. data/lib/bridgetown-core/commands/base.rb +9 -0
  9. data/lib/bridgetown-core/commands/concerns/actions.rb +0 -5
  10. data/lib/bridgetown-core/commands/configure.rb +66 -0
  11. data/lib/bridgetown-core/commands/console.rb +4 -0
  12. data/lib/bridgetown-core/commands/new.rb +8 -0
  13. data/lib/bridgetown-core/commands/plugins.rb +1 -0
  14. data/lib/bridgetown-core/component.rb +178 -0
  15. data/lib/bridgetown-core/concerns/data_accessible.rb +1 -0
  16. data/lib/bridgetown-core/concerns/front_matter_importer.rb +52 -0
  17. data/lib/bridgetown-core/concerns/site/configurable.rb +7 -3
  18. data/lib/bridgetown-core/concerns/site/content.rb +56 -15
  19. data/lib/bridgetown-core/concerns/site/processable.rb +1 -0
  20. data/lib/bridgetown-core/concerns/site/renderable.rb +26 -0
  21. data/lib/bridgetown-core/concerns/site/writable.rb +12 -2
  22. data/lib/bridgetown-core/concerns/validatable.rb +1 -4
  23. data/lib/bridgetown-core/configuration.rb +49 -28
  24. data/lib/bridgetown-core/configurations/.keep +0 -0
  25. data/lib/bridgetown-core/configurations/bt-postcss.rb +26 -0
  26. data/lib/bridgetown-core/configurations/bt-postcss/postcss.config.js +21 -0
  27. data/lib/bridgetown-core/configurations/minitesting.rb +95 -0
  28. data/lib/bridgetown-core/configurations/netlify.rb +6 -0
  29. data/lib/bridgetown-core/configurations/netlify/netlify.sh +14 -0
  30. data/lib/bridgetown-core/configurations/netlify/netlify.toml +44 -0
  31. data/lib/bridgetown-core/configurations/purgecss.rb +49 -0
  32. data/lib/bridgetown-core/configurations/stimulus.rb +49 -0
  33. data/lib/bridgetown-core/configurations/swup.rb +37 -0
  34. data/lib/bridgetown-core/configurations/tailwindcss.rb +29 -0
  35. data/lib/bridgetown-core/configurations/tailwindcss/css_imports.css +4 -0
  36. data/lib/bridgetown-core/configurations/tailwindcss/postcss.config.js +12 -0
  37. data/lib/bridgetown-core/configurations/turbo.rb +16 -0
  38. data/lib/bridgetown-core/converter.rb +23 -0
  39. data/lib/bridgetown-core/converters/erb_templates.rb +50 -41
  40. data/lib/bridgetown-core/converters/identity.rb +0 -9
  41. data/lib/bridgetown-core/converters/markdown.rb +14 -4
  42. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +3 -0
  43. data/lib/bridgetown-core/converters/ruby_templates.rb +17 -0
  44. data/lib/bridgetown-core/current.rb +10 -0
  45. data/lib/bridgetown-core/document.rb +6 -14
  46. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  47. data/lib/bridgetown-core/drops/page_drop.rb +4 -0
  48. data/lib/bridgetown-core/drops/relations_drop.rb +23 -0
  49. data/lib/bridgetown-core/drops/resource_drop.rb +83 -0
  50. data/lib/bridgetown-core/drops/site_drop.rb +33 -8
  51. data/lib/bridgetown-core/drops/unified_payload_drop.rb +5 -0
  52. data/lib/bridgetown-core/entry_filter.rb +10 -23
  53. data/lib/bridgetown-core/errors.rb +0 -2
  54. data/lib/bridgetown-core/filters.rb +3 -2
  55. data/lib/bridgetown-core/filters/from_liquid.rb +23 -0
  56. data/lib/bridgetown-core/generator.rb +2 -1
  57. data/lib/bridgetown-core/generators/prototype_generator.rb +37 -19
  58. data/lib/bridgetown-core/helpers.rb +48 -9
  59. data/lib/bridgetown-core/layout.rb +28 -13
  60. data/lib/bridgetown-core/liquid_renderer/file.rb +1 -0
  61. data/lib/bridgetown-core/liquid_renderer/table.rb +1 -0
  62. data/lib/bridgetown-core/model/base.rb +138 -0
  63. data/lib/bridgetown-core/model/builder_origin.rb +40 -0
  64. data/lib/bridgetown-core/model/origin.rb +38 -0
  65. data/lib/bridgetown-core/model/repo_origin.rb +126 -0
  66. data/lib/bridgetown-core/page.rb +9 -1
  67. data/lib/bridgetown-core/plugin.rb +2 -26
  68. data/lib/bridgetown-core/plugin_manager.rb +0 -2
  69. data/lib/bridgetown-core/publisher.rb +7 -1
  70. data/lib/bridgetown-core/reader.rb +26 -13
  71. data/lib/bridgetown-core/readers/data_reader.rb +3 -4
  72. data/lib/bridgetown-core/readers/post_reader.rb +1 -1
  73. data/lib/bridgetown-core/regenerator.rb +8 -1
  74. data/lib/bridgetown-core/related_posts.rb +1 -1
  75. data/lib/bridgetown-core/renderer.rb +6 -13
  76. data/lib/bridgetown-core/resource/base.rb +317 -0
  77. data/lib/bridgetown-core/resource/destination.rb +49 -0
  78. data/lib/bridgetown-core/resource/permalink_processor.rb +179 -0
  79. data/lib/bridgetown-core/resource/relations.rb +132 -0
  80. data/lib/bridgetown-core/resource/taxonomy_term.rb +34 -0
  81. data/lib/bridgetown-core/resource/taxonomy_type.rb +56 -0
  82. data/lib/bridgetown-core/resource/transformer.rb +175 -0
  83. data/lib/bridgetown-core/ruby_template_view.rb +12 -4
  84. data/lib/bridgetown-core/site.rb +9 -1
  85. data/lib/bridgetown-core/static_file.rb +33 -10
  86. data/lib/bridgetown-core/url.rb +1 -0
  87. data/lib/bridgetown-core/utils.rb +48 -41
  88. data/lib/bridgetown-core/utils/platforms.rb +1 -0
  89. data/lib/bridgetown-core/utils/ruby_exec.rb +6 -9
  90. data/lib/bridgetown-core/utils/ruby_front_matter.rb +39 -0
  91. data/lib/bridgetown-core/version.rb +2 -2
  92. data/lib/bridgetown-core/watcher.rb +1 -1
  93. data/lib/site_template/README.md +70 -0
  94. data/lib/site_template/package.json.erb +2 -2
  95. data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
  96. data/lib/site_template/webpack.config.js.erb +26 -6
  97. metadata +55 -39
  98. data/lib/bridgetown-core/page_without_a_file.rb +0 -17
  99. data/lib/bridgetown-core/readers/collection_reader.rb +0 -23
  100. data/lib/bridgetown-core/utils/exec.rb +0 -26
  101. data/lib/bridgetown-core/utils/internet.rb +0 -37
  102. data/lib/bridgetown-core/utils/win_tz.rb +0 -75
@@ -26,6 +26,10 @@ module Bridgetown
26
26
  # @return [Array<Page>]
27
27
  attr_accessor :pages
28
28
 
29
+ # NOTE: Eventually pages will be deprecated once the Resource content engine
30
+ # is default
31
+ alias_method :generated_pages, :pages
32
+
29
33
  attr_accessor :exclude, :include, :lsi, :highlighter, :permalink_style,
30
34
  :time, :future, :unpublished, :limit_posts,
31
35
  :keep_files, :baseurl, :data, :file_read_opts,
@@ -46,7 +50,7 @@ module Bridgetown
46
50
 
47
51
  ensure_not_in_dest
48
52
 
49
- Bridgetown.sites << self
53
+ Bridgetown::Current.site = self
50
54
  Bridgetown::Hooks.trigger :site, :after_init, self
51
55
 
52
56
  reset # Processable
@@ -64,5 +68,9 @@ module Bridgetown
64
68
  end
65
69
  end
66
70
  end
71
+
72
+ def inspect
73
+ "#<Bridgetown::Site #{metadata.inspect.delete_prefix("{").delete_suffix("}")}>"
74
+ end
67
75
  end
68
76
  end
@@ -4,7 +4,7 @@ module Bridgetown
4
4
  class StaticFile
5
5
  extend Forwardable
6
6
 
7
- attr_reader :relative_path, :extname, :name, :data
7
+ attr_reader :relative_path, :extname, :name, :data, :site, :collection
8
8
 
9
9
  def_delegator :to_liquid, :to_json, :to_json
10
10
 
@@ -25,8 +25,7 @@ module Bridgetown
25
25
  # base - The String path to the <source>.
26
26
  # dir - The String path between <source> and the file.
27
27
  # name - The String filename of the file.
28
- # rubocop: disable Metrics/ParameterLists
29
- def initialize(site, base, dir, name, collection = nil)
28
+ def initialize(site, base, dir, name, collection = nil) # rubocop:disable Metrics/ParameterLists
30
29
  @site = site
31
30
  @base = base
32
31
  @dir = dir
@@ -34,9 +33,15 @@ module Bridgetown
34
33
  @collection = collection
35
34
  @relative_path = File.join(*[@dir, @name].compact)
36
35
  @extname = File.extname(@name)
37
- @data = @site.frontmatter_defaults.all(relative_path, type)
36
+ @data = @site.frontmatter_defaults.all(relative_path, type).with_dot_access
37
+ if site.uses_resource? && !data.permalink
38
+ data.permalink = if collection && !collection.builtin?
39
+ "/:collection/:path.*"
40
+ else
41
+ "/:path.*"
42
+ end
43
+ end
38
44
  end
39
- # rubocop: enable Metrics/ParameterLists
40
45
 
41
46
  # Returns source file path.
42
47
  def path
@@ -51,8 +56,11 @@ module Bridgetown
51
56
  #
52
57
  # Returns destination file path.
53
58
  def destination(dest)
54
- dest = @site.in_dest_dir(dest)
55
- @site.in_dest_dir(dest, Bridgetown::URL.unescape_path(url))
59
+ dest = site.in_dest_dir(dest)
60
+ dest_url = url
61
+ dest_url = dest_url.delete_prefix(site.baseurl) if site.uses_resource? &&
62
+ site.baseurl.present? && collection
63
+ site.in_dest_dir(dest, Bridgetown::URL.unescape_path(dest_url))
56
64
  end
57
65
 
58
66
  def destination_rel_dir
@@ -118,6 +126,15 @@ module Bridgetown
118
126
  @basename ||= File.basename(name, extname).gsub(%r!\.*\z!, "")
119
127
  end
120
128
 
129
+ def relative_path_basename_without_prefix
130
+ return_path = Pathname.new("")
131
+ Pathname.new(cleaned_relative_path).each_filename do |filename|
132
+ return_path += filename unless filename.starts_with?("_")
133
+ end
134
+
135
+ (return_path.dirname + return_path.basename(".*")).to_s
136
+ end
137
+
121
138
  def placeholders
122
139
  {
123
140
  collection: @collection.label,
@@ -154,15 +171,21 @@ module Bridgetown
154
171
  # be overriden in the collection's configuration in bridgetown.config.yml.
155
172
  def url
156
173
  @url ||= begin
157
- base = if @collection.nil? || @collection.label == "posts"
174
+ newly_processed = false
175
+ special_posts_case = @collection&.label == "posts" &&
176
+ site.config.content_engine != "resource"
177
+ base = if @collection.nil? || special_posts_case
158
178
  cleaned_relative_path
179
+ elsif site.uses_resource?
180
+ newly_processed = true
181
+ Bridgetown::Resource::PermalinkProcessor.new(self).transform
159
182
  else
160
183
  Bridgetown::URL.new(
161
184
  template: @collection.url_template,
162
185
  placeholders: placeholders
163
186
  )
164
187
  end.to_s.chomp("/")
165
- base << extname
188
+ newly_processed ? base : "#{base}#{extname}"
166
189
  end
167
190
  end
168
191
 
@@ -174,7 +197,7 @@ module Bridgetown
174
197
  # Returns the front matter defaults defined for the file's URL and/or type
175
198
  # as defined in bridgetown.config.yml.
176
199
  def defaults
177
- @defaults ||= @site.frontmatter_defaults.all url, type
200
+ @defaults ||= site.frontmatter_defaults.all url, type
178
201
  end
179
202
 
180
203
  # Returns a debug string on inspecting the static file.
@@ -129,6 +129,7 @@ module Bridgetown
129
129
  #
130
130
  # Returns the escaped path.
131
131
  def self.escape_path(path)
132
+ path = path.to_s
132
133
  return path if path.empty? || %r!^[a-zA-Z0-9./-]+$!.match?(path)
133
134
 
134
135
  # Because URI.escape doesn't escape "?", "[" and "]" by default,
@@ -4,12 +4,10 @@ module Bridgetown
4
4
  module Utils
5
5
  extend self
6
6
  autoload :Ansi, "bridgetown-core/utils/ansi"
7
- autoload :Exec, "bridgetown-core/utils/exec"
8
- autoload :Internet, "bridgetown-core/utils/internet"
9
7
  autoload :RubyExec, "bridgetown-core/utils/ruby_exec"
8
+ autoload :RubyFrontMatterDSL, "bridgetown-core/utils/ruby_front_matter"
10
9
  autoload :Platforms, "bridgetown-core/utils/platforms"
11
10
  autoload :ThreadEvent, "bridgetown-core/utils/thread_event"
12
- autoload :WinTZ, "bridgetown-core/utils/win_tz"
13
11
 
14
12
  # Constants for use in #slugify
15
13
  SLUGIFY_MODES = %w(raw default pretty simple ascii latin).freeze
@@ -74,38 +72,32 @@ module Bridgetown
74
72
  end
75
73
  end
76
74
 
77
- # Read array from the supplied hash favouring the singular key
78
- # and then the plural key, and handling any nil entries.
75
+ # Read array from the supplied hash, merging the singular key with the
76
+ # plural key as needing, and handling any nil or duplicate entries.
79
77
  #
80
- # hash - the hash to read from
81
- # singular_key - the singular key
82
- # plural_key - the plural key
83
- #
84
- # Returns an array
85
- def pluralized_array_from_hash(hash, singular_key, plural_key)
86
- array = []
87
- value = value_from_singular_key(hash, singular_key)
88
- value ||= value_from_plural_key(hash, plural_key)
78
+ # @param hsh [Hash] the hash to read from
79
+ # @param singular_key [Symbol] the singular key
80
+ # @param plural_key [Symbol] the plural key
81
+ # @return [Array]
82
+ def pluralized_array_from_hash(hsh, singular_key, plural_key)
83
+ array = [
84
+ hsh[singular_key],
85
+ value_from_plural_key(hsh, plural_key),
86
+ ]
89
87
 
90
- array << value
91
88
  array.flatten!
92
89
  array.compact!
90
+ array.uniq!
93
91
  array
94
92
  end
95
93
 
96
- def value_from_singular_key(hash, key)
97
- hash[key] if hash.key?(key) || (hash.default_proc && hash[key])
98
- end
99
-
100
- def value_from_plural_key(hash, key)
101
- if hash.key?(key) || (hash.default_proc && hash[key])
102
- val = hash[key]
103
- case val
104
- when String
105
- val.split
106
- when Array
107
- val.compact
108
- end
94
+ def value_from_plural_key(hsh, key)
95
+ val = hsh[key]
96
+ case val
97
+ when String
98
+ val.split
99
+ when Array
100
+ val.compact
109
101
  end
110
102
  end
111
103
 
@@ -124,17 +116,23 @@ module Bridgetown
124
116
 
125
117
  # Determines whether a given file has
126
118
  #
127
- # Returns true if the YAML front matter is present.
119
+ # @return [Boolean] if the YAML front matter is present.
128
120
  # rubocop: disable Naming/PredicateName
129
121
  def has_yaml_header?(file)
130
- File.open(file, "rb", &:readline).match? %r!\A---\s*\r?\n!
122
+ File.open(file, "rb", &:readline).match? Bridgetown::FrontMatterImporter::YAML_HEADER
123
+ rescue EOFError
124
+ false
125
+ end
126
+
127
+ def has_rbfm_header?(file)
128
+ File.open(file, "rb", &:readline).match? Bridgetown::FrontMatterImporter::RUBY_HEADER
131
129
  rescue EOFError
132
130
  false
133
131
  end
134
132
 
135
133
  # Determine whether the given content string contains Liquid Tags or Vaiables
136
134
  #
137
- # Returns true is the string contains sequences of `{%` or `{{`
135
+ # @return [Boolean] if the string contains sequences of `{%` or `{{`
138
136
  def has_liquid_construct?(content)
139
137
  return false if content.nil? || content.empty?
140
138
 
@@ -207,7 +205,7 @@ module Bridgetown
207
205
  slug.gsub!(%r!^\-|\-$!i, "")
208
206
 
209
207
  slug.downcase! unless cased
210
- Bridgetown.logger.warn("Warning:", "Empty `slug` generated for '#{string}'.") if slug.empty?
208
+
211
209
  slug
212
210
  end
213
211
 
@@ -347,7 +345,7 @@ module Bridgetown
347
345
 
348
346
  # Return an asset path based on the Webpack manifest file
349
347
  # @param site [Bridgetown::Site] The current site object
350
- # @param asset_type [String] js or css
348
+ # @param asset_type [String] js or css, or filename in manifest
351
349
  #
352
350
  # @return [String] Returns "MISSING_WEBPACK_MANIFEST" if the manifest
353
351
  # file isnt found
@@ -363,21 +361,30 @@ module Bridgetown
363
361
  manifest = JSON.parse(File.read(manifest_file))
364
362
 
365
363
  known_assets = %w(js css)
364
+ asset_path = nil
366
365
  if known_assets.include?(asset_type)
367
366
  asset_path = manifest["main.#{asset_type}"]
368
-
369
367
  log_webpack_asset_error(asset_type) && return if asset_path.nil?
370
-
371
- asset_path = asset_path.split("/").last
372
- return [static_frontend_path(site), asset_type, asset_path].join("/")
368
+ else
369
+ asset_path = manifest.find do |item, _|
370
+ item.sub(%r{^../(frontend/|src/)?}, "") == asset_type
371
+ end&.last
373
372
  end
374
373
 
375
- Bridgetown.logger.error("Unknown Webpack asset type", asset_type)
376
- nil
374
+ if asset_path
375
+ static_frontend_path(site, ["js", asset_path])
376
+ else
377
+ Bridgetown.logger.error("Unknown Webpack asset type", asset_type)
378
+ nil
379
+ end
377
380
  end
378
381
 
379
- def static_frontend_path(site)
380
- path_parts = [site.config["baseurl"].to_s.chomp("/"), "_bridgetown/static"]
382
+ def static_frontend_path(site, additional_parts = [])
383
+ path_parts = [
384
+ site.config["baseurl"].to_s.gsub(%r(^/|/$), ""),
385
+ "_bridgetown/static",
386
+ *additional_parts,
387
+ ]
381
388
  path_parts[0] = "/#{path_parts[0]}" unless path_parts[0].empty?
382
389
  Addressable::URI.parse(path_parts.join("/")).normalize.to_s
383
390
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Bridgetown
4
4
  module Utils
5
+ # TODO: deprecate, we should try not to have any platform-specific code
5
6
  module Platforms
6
7
  extend self
7
8
 
@@ -5,8 +5,8 @@ module Bridgetown
5
5
  module RubyExec
6
6
  extend self
7
7
 
8
- # rubocop:disable Metrics/AbcSize
9
- def search_data_for_ruby_code(convertible, renderer)
8
+ # TODO: Deprecate storing Ruby code in YAML, Rb, etc. and just use native Ruby Front Matter
9
+ def search_data_for_ruby_code(convertible, renderer) # rubocop:todo Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
10
10
  return if convertible.data.empty?
11
11
 
12
12
  # Iterate using `keys` here so inline Ruby script can add new data keys
@@ -14,24 +14,21 @@ module Bridgetown
14
14
  data_keys = convertible.data.keys
15
15
  data_keys.each do |k|
16
16
  v = convertible.data[k]
17
- next unless v.is_a?(Rb) || v.is_a?(Hash)
17
+ next unless v.is_a?(Rb) || v.is_a?(Hash) || v.is_a?(Proc)
18
18
 
19
- if v.is_a?(Hash)
19
+ if v.is_a?(Proc)
20
+ convertible.data[k] = convertible.instance_exec(&v)
21
+ elsif v.is_a?(Hash)
20
22
  v.each do |nested_k, nested_v|
21
23
  next unless nested_v.is_a?(Rb)
22
24
 
23
- Bridgetown.logger.debug("Executing inline Ruby…", convertible.relative_path)
24
25
  convertible.data[k][nested_k] = run(nested_v, convertible, renderer)
25
- Bridgetown.logger.debug("Inline Ruby completed!", convertible.relative_path)
26
26
  end
27
27
  else
28
- Bridgetown.logger.debug("Executing inline Ruby…", convertible.relative_path)
29
28
  convertible.data[k] = run(v, convertible, renderer)
30
- Bridgetown.logger.debug("Inline Ruby completed!", convertible.relative_path)
31
29
  end
32
30
  end
33
31
  end
34
- # rubocop:enable Metrics/AbcSize
35
32
 
36
33
  # Sets up a new context in which to eval Ruby coming from front matter.
37
34
  #
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Utils
5
+ module RubyFrontMatterDSL
6
+ def front_matter(&block)
7
+ RubyFrontMatter.new.tap { |fm| fm.instance_exec(&block) }
8
+ end
9
+ end
10
+
11
+ class RubyFrontMatter
12
+ def initialize
13
+ @data = {}
14
+ end
15
+
16
+ def method_missing(key, value) # rubocop:disable Style/MissingRespondToMissing
17
+ return super if respond_to?(key)
18
+
19
+ set(key, value)
20
+ end
21
+
22
+ def each(&block)
23
+ @data.each(&block)
24
+ end
25
+
26
+ def get(key)
27
+ @data[key]
28
+ end
29
+
30
+ def set(key, value)
31
+ @data[key] = value
32
+ end
33
+
34
+ def to_h
35
+ @data
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "0.19.0"
5
- CODE_NAME = "Arbor Lodge"
4
+ VERSION = "0.21.0.beta1"
5
+ CODE_NAME = "Broughton Beach"
6
6
  end
@@ -140,7 +140,7 @@ module Bridgetown
140
140
  if options[:trace]
141
141
  Bridgetown.logger.info e.backtrace.join("\n")
142
142
  else
143
- Bridgetown.logger.warn "Error:", "Use the --trace option for more information."
143
+ Bridgetown.logger.warn "Backtrace:", "Use the --trace option for more information."
144
144
  end
145
145
  end
146
146
  Bridgetown.logger.info ""
@@ -0,0 +1,70 @@
1
+ # Bridgetown Website README
2
+
3
+ Welcome to your new Bridgetown website! You can update this README file to provide additional context and setup information for yourself or other contributors.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Prerequisites](#prerequisites)
8
+ - [Install](#install)
9
+ - [Development](#development)
10
+ - [Commands](#commands)
11
+ - [Deployment](#deployment)
12
+ - [Contributing](#contributing)
13
+
14
+ ## Prerequisites
15
+
16
+ - [GCC](https://gcc.gnu.org/install/)
17
+ - [Make](https://www.gnu.org/software/make/)
18
+ - [Ruby](https://www.ruby-lang.org/en/downloads/)
19
+ - `>= 2.5`
20
+ - [Bridgetown Gem](https://rubygems.org/gems/bridgetown)
21
+ - `gem install bundler bridgetown -N`
22
+ - [Node](https://nodejs.org)
23
+ - `>= 10.13`
24
+ - [Yarn](https://yarnpkg.com)
25
+
26
+ ## Install
27
+
28
+ ```sh
29
+ cd bridgetown-site-folder
30
+ bundle install && yarn install
31
+ ```
32
+ > Learn more: [Bridgetown Getting Started Documentation](https://www.bridgetownrb.com/docs/).
33
+
34
+ ## Development
35
+
36
+ To start your site in development mode, run `yarn start` and navigate to [localhost:4000](https://localhost:4000/)!
37
+
38
+ Use a [theme](https://github.com/topics/bridgetown-theme), add some [plugins](https://www.bridgetownrb.com/plugins/), and/or run some [automations](https://github.com/topics/bridgetown-automation) to get started quickly.
39
+
40
+ ### Commands
41
+
42
+ ```sh
43
+ # running locally
44
+ yarn start
45
+
46
+ # build & deploy to production
47
+ yarn deploy
48
+
49
+ # load the site up within a Ruby console (IRB)
50
+ bundle exec bridgetown console
51
+ ```
52
+
53
+ > Learn more: [Bridgetown CLI Documentation](https://www.bridgetownrb.com/docs/command-line-usage)
54
+
55
+ ## Deployment
56
+
57
+ You can deploy Bridgetown sites on "Jamstack" hosts (Netlify, Vercel, Render, etc.) or virtually any tranditional web server by simply building and copying the output folder to your HTML root.
58
+
59
+ > Read the [Bridgetown Deployment Documentation](https://www.bridgetownrb.com/docs/deployment) for more information.
60
+
61
+ ## Contributing
62
+
63
+ If repo is on GitHub:
64
+
65
+ 1. Fork it
66
+ 2. Clone the fork using `git clone` to your local development machine.
67
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
68
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
69
+ 5. Push to the branch (`git push origin my-new-feature`)
70
+ 6. Create a new Pull Request