bridgetown-core 0.17.1 → 0.18.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/lib/bridgetown-core.rb +43 -28
  4. data/lib/bridgetown-core/collection.rb +5 -1
  5. data/lib/bridgetown-core/commands/apply.rb +2 -2
  6. data/lib/bridgetown-core/commands/new.rb +1 -1
  7. data/lib/bridgetown-core/concerns/layout_placeable.rb +1 -1
  8. data/lib/bridgetown-core/concerns/liquid_renderable.rb +10 -0
  9. data/lib/bridgetown-core/concerns/site/configurable.rb +21 -23
  10. data/lib/bridgetown-core/concerns/site/content.rb +44 -31
  11. data/lib/bridgetown-core/concerns/site/extensible.rb +14 -13
  12. data/lib/bridgetown-core/concerns/site/localizable.rb +6 -2
  13. data/lib/bridgetown-core/concerns/site/processable.rb +10 -9
  14. data/lib/bridgetown-core/concerns/site/renderable.rb +34 -26
  15. data/lib/bridgetown-core/concerns/site/writable.rb +7 -15
  16. data/lib/bridgetown-core/configuration.rb +5 -3
  17. data/lib/bridgetown-core/converter.rb +0 -42
  18. data/lib/bridgetown-core/converters/erb_templates.rb +75 -16
  19. data/lib/bridgetown-core/converters/liquid_templates.rb +96 -0
  20. data/lib/bridgetown-core/converters/markdown.rb +0 -3
  21. data/lib/bridgetown-core/document.rb +31 -18
  22. data/lib/bridgetown-core/drops/site_drop.rb +4 -0
  23. data/lib/bridgetown-core/drops/unified_payload_drop.rb +0 -1
  24. data/lib/bridgetown-core/drops/url_drop.rb +19 -3
  25. data/lib/bridgetown-core/excerpt.rb +1 -1
  26. data/lib/bridgetown-core/filters.rb +28 -7
  27. data/lib/bridgetown-core/generators/prototype_generator.rb +42 -25
  28. data/lib/bridgetown-core/helpers.rb +84 -0
  29. data/lib/bridgetown-core/liquid_renderer.rb +1 -1
  30. data/lib/bridgetown-core/log_writer.rb +2 -2
  31. data/lib/bridgetown-core/plugin_manager.rb +34 -1
  32. data/lib/bridgetown-core/reader.rb +1 -4
  33. data/lib/bridgetown-core/readers/post_reader.rb +28 -15
  34. data/lib/bridgetown-core/renderer.rb +42 -160
  35. data/lib/bridgetown-core/ruby_template_view.rb +22 -33
  36. data/lib/bridgetown-core/site.rb +12 -2
  37. data/lib/bridgetown-core/utils.rb +14 -0
  38. data/lib/bridgetown-core/version.rb +2 -2
  39. data/lib/bridgetown-core/watcher.rb +1 -0
  40. data/lib/site_template/src/images/.keep +1 -0
  41. metadata +7 -3
@@ -1,20 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Bridgetown
4
- module Site::Extensible
3
+ class Bridgetown::Site
4
+ module Extensible
5
5
  # Load necessary libraries, plugins, converters, and generators.
6
- # @see Bridgetown::Converter
7
- # @see Bridgetown::Generator
6
+ # @see Converter
7
+ # @see Generator
8
8
  # @see PluginManager
9
9
  # @return [void]
10
10
  def setup
11
11
  plugin_manager.require_plugin_files
12
+ plugin_manager.setup_component_loaders
12
13
  self.converters = instantiate_subclasses(Bridgetown::Converter)
13
14
  self.generators = instantiate_subclasses(Bridgetown::Generator)
14
15
  end
15
16
 
16
17
  # Run all Generators.
17
- # @see Bridgetown::Generator
18
+ # @see Generator
18
19
  # @return [void]
19
20
  def generate
20
21
  generators.each do |generator|
@@ -33,10 +34,10 @@ module Bridgetown
33
34
  end
34
35
  end
35
36
 
36
- # Get the implementation class for the given Converter.
37
- # @param klass [Object] The Class of the Converter to fetch.
38
- # @return [Bridgetown::Converter] Returns the {Bridgetown::Converter}
39
- # instance implementing the given +Converter+.
37
+ # Get the implementation for the given Converter class.
38
+ # @param klass [Class] The Class of the Converter to fetch.
39
+ # @return [Converter] Returns the {Converter}
40
+ # instance implementing the given `Converter` class.
40
41
  def find_converter_instance(klass)
41
42
  @find_converter_instance ||= {}
42
43
  @find_converter_instance[klass] ||= begin
@@ -45,11 +46,11 @@ module Bridgetown
45
46
  end
46
47
  end
47
48
 
48
- # Create an array of instances of the subclasses of the class or module
49
+ # Create an array of instances of the subclasses of the class
49
50
  # passed in as argument.
50
- # @param klass [Class, Module] - class or module containing the subclasses.
51
- # @return [Array<Object>] Returns an array of instances of subclasses of
52
- # +klass+.
51
+ # @param klass [Class] - class which is the parent of the subclasses.
52
+ # @return [Array<Converter, Generator>] Returns an array of instances of
53
+ # subclasses of `klass`.
53
54
  def instantiate_subclasses(klass)
54
55
  klass.descendants.sort.map do |c|
55
56
  c.new(config)
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Bridgetown
4
- module Site::Localizable
3
+ class Bridgetown::Site
4
+ module Localizable
5
+ # Returns the current and/or default configured locale
6
+ # @return String
5
7
  def locale
6
8
  if @locale
7
9
  @locale
@@ -13,6 +15,8 @@ module Bridgetown
13
15
  end
14
16
  end
15
17
 
18
+ # Sets the current locale for the site
19
+ # @param new_locale [String] for example: "en" for English, "es" for Spanish
16
20
  def locale=(new_locale)
17
21
  I18n.locale = @locale = new_locale.to_sym
18
22
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Bridgetown
4
- module Site::Processable
3
+ class Bridgetown::Site
4
+ module Processable
5
5
  # Reset, Read, Generate, Render, Cleanup, Process, and Write this Site to output.
6
6
  # @return [void]
7
7
  # @see #reset
@@ -22,14 +22,15 @@ module Bridgetown
22
22
 
23
23
  # rubocop:disable Metrics/AbcSize
24
24
 
25
- # Reset Site details.
25
+ # Reset all in-memory data and content.
26
26
  # @return [void]
27
27
  def reset
28
- self.time = if config["time"]
29
- Utils.parse_date(config["time"].to_s, "Invalid time in bridgetown.config.yml.")
30
- else
31
- Time.now
32
- end
28
+ self.time = Time.now
29
+ if config["time"]
30
+ self.time = Bridgetown::Utils.parse_date(
31
+ config["time"].to_s, "Invalid time in bridgetown.config.yml."
32
+ )
33
+ end
33
34
  self.layouts = HashWithDotAccess::Hash.new
34
35
  self.pages = []
35
36
  self.static_files = []
@@ -50,7 +51,7 @@ module Bridgetown
50
51
 
51
52
  # rubocop:enable Metrics/AbcSize
52
53
 
53
- # Read Site data from disk and load it into internal data structures.
54
+ # Read data from disk and load it into internal memory.
54
55
  # @return [void]
55
56
  def read
56
57
  Bridgetown::Hooks.trigger :site, :pre_read, self
@@ -1,20 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Bridgetown
4
- module Site::Renderable
5
- # Render the site to the destination.
3
+ class Bridgetown::Site
4
+ module Renderable
5
+ # Render all pages & documents so they're ready to be written out to disk.
6
6
  # @return [void]
7
+ # @see Page
8
+ # @see Document
7
9
  def render
8
- payload = site_payload
9
-
10
- Bridgetown::Hooks.trigger :site, :pre_render, self, payload
11
-
10
+ Bridgetown::Hooks.trigger :site, :pre_render, self
12
11
  execute_inline_ruby_for_layouts!
13
-
14
- render_docs(payload)
15
- render_pages(payload)
16
-
17
- Bridgetown::Hooks.trigger :site, :post_render, self, payload
12
+ render_docs
13
+ render_pages
14
+ Bridgetown::Hooks.trigger :site, :post_render, self
18
15
  end
19
16
 
20
17
  # Executes inline Ruby frontmatter
@@ -33,36 +30,47 @@ module Bridgetown
33
30
  end
34
31
 
35
32
  # Renders all documents
36
- # @param payload [Hash] A hash of site data.
37
33
  # @return [void]
38
- # @see Bridgetown::Site::Content#site_payload
39
- def render_docs(payload)
34
+ def render_docs
40
35
  collections.each_value do |collection|
41
36
  collection.docs.each do |document|
42
- render_regenerated(document, payload)
37
+ render_with_locale(document) do
38
+ render_regenerated document
39
+ end
43
40
  end
44
41
  end
45
42
  end
46
43
 
47
44
  # Renders all pages
48
- # @param payload [Hash] A hash of site data.
49
45
  # @return [void]
50
- # @see Bridgetown::Site::Content#site_payload
51
- def render_pages(payload)
46
+ def render_pages
52
47
  pages.each do |page|
53
- render_regenerated(page, payload)
48
+ render_regenerated page
49
+ end
50
+ end
51
+
52
+ # Renders a document while ensuring site locale is set if the data is available.
53
+ # @param document [Document] The document to render
54
+ # @yield Runs the block in between locale setting and resetting
55
+ # @return [void]
56
+ def render_with_locale(document)
57
+ if document.data["locale"]
58
+ previous_locale = locale
59
+ self.locale = document.data["locale"]
60
+ yield
61
+ self.locale = previous_locale
62
+ else
63
+ yield
54
64
  end
55
65
  end
56
66
 
57
- # Regenerates a site using {Bridgetown::Renderer}
58
- # @param document [Post] The document to regenerate.
59
- # @param payload [Hash] A hash of site data.
67
+ # Regenerates a site using {Renderer}
68
+ # @param document [Document] The document to regenerate.
60
69
  # @return [void]
61
- # @see Bridgetown::Renderer
62
- def render_regenerated(document, payload)
70
+ def render_regenerated(document)
63
71
  return unless regenerator.regenerate?(document)
64
72
 
65
- Bridgetown::Renderer.new(self, document, payload).run
73
+ Bridgetown::Renderer.new(self, document).run
66
74
  end
67
75
  end
68
76
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Bridgetown
4
- module Site::Writable
3
+ class Bridgetown::Site
4
+ module Writable
5
5
  # Remove orphaned files and empty directories in destination.
6
6
  #
7
7
  # @return [void]
@@ -9,7 +9,7 @@ module Bridgetown
9
9
  @cleaner.cleanup!
10
10
  end
11
11
 
12
- # Write static files, pages, and posts.
12
+ # Write static files, pages, and documents to the destination folder.
13
13
  #
14
14
  # @return [void]
15
15
  def write
@@ -20,22 +20,14 @@ module Bridgetown
20
20
  Bridgetown::Hooks.trigger :site, :post_write, self
21
21
  end
22
22
 
23
- # Yields the pages from {#pages}, {#static_files}, and {#docs_to_write}.
23
+ # Yields all content objects while looping through {#pages},
24
+ # {#static_files_to_write}, and {#docs_to_write}.
24
25
  #
25
- # @yieldparam item [Document, Page, StaticFile] Yields a
26
- # {#Bridgetown::Page}, {#Bridgetown::StaticFile}, or
27
- # {#Bridgetown::Document} object.
26
+ # @yieldparam item [Document, Page, StaticFile]
28
27
  #
29
28
  # @return [void]
30
- #
31
- # @see #pages
32
- # @see #static_files
33
- # @see #docs_to_write
34
- # @see Page
35
- # @see StaticFile
36
- # @see Document
37
29
  def each_site_file
38
- %w(pages static_files docs_to_write).each do |type|
30
+ %w(pages static_files_to_write docs_to_write).each do |type|
39
31
  send(type).each do |item|
40
32
  yield item
41
33
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- # TODO: refactor this whole object! Already had to fix obscure
5
- # bugs just making minor changes, and all the indirection is
6
- # quite hard to decipher. -JW
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
7
9
  class Configuration < HashWithDotAccess::Hash
8
10
  # Default options. Overridden by values in bridgetown.config.yml.
9
11
  # Strings rather than symbols are used for compatibility with YAML.
@@ -16,34 +16,6 @@ module Bridgetown
16
16
  end
17
17
  end
18
18
 
19
- # Public: Get or set the highlighter prefix. When an argument is specified,
20
- # the prefix will be set. If no argument is specified, the current prefix
21
- # will be returned.
22
- #
23
- # highlighter_prefix - The String prefix (default: nil).
24
- #
25
- # Returns the String prefix.
26
- def self.highlighter_prefix(highlighter_prefix = nil)
27
- unless defined?(@highlighter_prefix) && highlighter_prefix.nil?
28
- @highlighter_prefix = highlighter_prefix
29
- end
30
- @highlighter_prefix
31
- end
32
-
33
- # Public: Get or set the highlighter suffix. When an argument is specified,
34
- # the suffix will be set. If no argument is specified, the current suffix
35
- # will be returned.
36
- #
37
- # highlighter_suffix - The String suffix (default: nil).
38
- #
39
- # Returns the String suffix.
40
- def self.highlighter_suffix(highlighter_suffix = nil)
41
- unless defined?(@highlighter_suffix) && highlighter_suffix.nil?
42
- @highlighter_suffix = highlighter_suffix
43
- end
44
- @highlighter_suffix
45
- end
46
-
47
19
  # Initialize the converter.
48
20
  #
49
21
  # Returns an initialized Converter.
@@ -70,19 +42,5 @@ module Bridgetown
70
42
  def output_ext(_ext)
71
43
  ".html"
72
44
  end
73
-
74
- # Get the highlighter prefix.
75
- #
76
- # Returns the String prefix.
77
- def highlighter_prefix
78
- self.class.highlighter_prefix
79
- end
80
-
81
- # Get the highlighter suffix.
82
- #
83
- # Returns the String suffix.
84
- def highlighter_suffix
85
- self.class.highlighter_suffix
86
- end
87
45
  end
88
46
  end
@@ -1,9 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "tilt/erubi"
4
- require "erubi/capture_end"
5
4
 
6
5
  module Bridgetown
6
+ class ERBBuffer < String
7
+ def concat_to_s(input)
8
+ concat input.to_s
9
+ end
10
+
11
+ alias_method :safe_append=, :concat_to_s
12
+ alias_method :append=, :concat_to_s
13
+ alias_method :safe_expr_append=, :concat_to_s
14
+ end
15
+
16
+ class ERBEngine < Erubi::Engine
17
+ private
18
+
19
+ def add_code(code)
20
+ @src << code
21
+ @src << ";#{@bufvar};" if code.strip.split(".").first == "end"
22
+ @src << ";" unless code[Erubi::RANGE_LAST] == "\n"
23
+ end
24
+
25
+ # pulled from Rails' ActionView
26
+ BLOCK_EXPR = %r!\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z!.freeze
27
+
28
+ def add_expression(indicator, code)
29
+ if BLOCK_EXPR.match?(code)
30
+ src << "#{@bufvar}.append= " << code
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ # Don't allow == to output escaped strings, as that's the opposite of Rails
37
+ def add_expression_result_escaped(code)
38
+ add_expression_result(code)
39
+ end
40
+ end
41
+
7
42
  class ERBView < RubyTemplateView
8
43
  def h(input)
9
44
  Erubi.h(input)
@@ -11,6 +46,7 @@ module Bridgetown
11
46
 
12
47
  def partial(partial_name, options = {})
13
48
  options.merge!(options[:locals]) if options[:locals]
49
+ options[:content] = yield if block_given?
14
50
 
15
51
  partial_segments = partial_name.split("/")
16
52
  partial_segments.last.sub!(%r!^!, "_")
@@ -19,34 +55,42 @@ module Bridgetown
19
55
  Tilt::ErubiTemplate.new(
20
56
  site.in_source_dir(site.config[:partials_dir], "#{partial_name}.erb"),
21
57
  outvar: "@_erbout",
22
- engine_class: Erubi::CaptureEndEngine
58
+ bufval: "Bridgetown::ERBBuffer.new",
59
+ engine_class: ERBEngine
23
60
  ).render(self, options)
24
61
  end
25
62
 
26
- def markdownify
27
- previous_buffer_state = @_erbout
28
- @_erbout = +""
29
- result = yield
30
- @_erbout = previous_buffer_state
31
-
32
- content = Bridgetown::Utils.reindent_for_markdown(result)
63
+ def markdownify(input = nil, &block)
64
+ content = Bridgetown::Utils.reindent_for_markdown(
65
+ block.nil? ? input.to_s : capture(&block)
66
+ )
33
67
  converter = site.find_converter_instance(Bridgetown::Converters::Markdown)
34
- md_output = converter.convert(content).strip
35
- @_erbout << md_output
68
+ converter.convert(content).strip
36
69
  end
37
70
 
38
- def capture
71
+ def capture(obj = nil, &block)
39
72
  previous_buffer_state = @_erbout
40
- @_erbout = +""
41
- result = yield
73
+ @_erbout = ERBBuffer.new
74
+
75
+ # For compatibility with ActionView, not used by Bridgetown normally
76
+ previous_ob_state = @output_buffer
77
+ @output_buffer = ERBBuffer.new
78
+
79
+ result = instance_exec(obj, &block)
80
+ if @output_buffer != ""
81
+ # use Rails' ActionView buffer if present
82
+ result = @output_buffer
83
+ end
42
84
  @_erbout = previous_buffer_state
85
+ @output_buffer = previous_ob_state
43
86
 
44
- result
87
+ result.respond_to?(:html_safe) ? result.html_safe : result
45
88
  end
46
89
  end
47
90
 
48
91
  module Converters
49
92
  class ERBTemplates < Converter
93
+ priority :highest
50
94
  input :erb
51
95
 
52
96
  # Logic to do the ERB content conversion.
@@ -62,7 +106,8 @@ module Bridgetown
62
106
  erb_renderer = Tilt::ErubiTemplate.new(
63
107
  convertible.relative_path,
64
108
  outvar: "@_erbout",
65
- engine_class: Erubi::CaptureEndEngine
109
+ bufval: "Bridgetown::ERBBuffer.new",
110
+ engine_class: ERBEngine
66
111
  ) { content }
67
112
 
68
113
  if convertible.is_a?(Bridgetown::Layout)
@@ -73,6 +118,20 @@ module Bridgetown
73
118
  erb_renderer.render(erb_view)
74
119
  end
75
120
  end
121
+
122
+ def matches(ext, convertible)
123
+ if convertible.data[:template_engine] == "erb" ||
124
+ (convertible.data[:template_engine].nil? &&
125
+ @config[:template_engine] == "erb")
126
+ return true
127
+ end
128
+
129
+ super(ext)
130
+ end
131
+
132
+ def output_ext(ext)
133
+ ext == ".erb" ? ".html" : ext
134
+ end
76
135
  end
77
136
  end
78
137
  end