bridgetown-core 0.19.2 → 0.21.0.beta3

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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/bridgetown-core.gemspec +1 -2
  3. data/lib/bridgetown-core.rb +37 -29
  4. data/lib/bridgetown-core/cleaner.rb +9 -3
  5. data/lib/bridgetown-core/collection.rb +177 -78
  6. data/lib/bridgetown-core/commands/base.rb +9 -0
  7. data/lib/bridgetown-core/commands/build.rb +0 -11
  8. data/lib/bridgetown-core/commands/concerns/git_helpers.rb +20 -0
  9. data/lib/bridgetown-core/commands/configure.rb +8 -3
  10. data/lib/bridgetown-core/commands/console.rb +4 -0
  11. data/lib/bridgetown-core/commands/doctor.rb +1 -19
  12. data/lib/bridgetown-core/commands/new.rb +2 -2
  13. data/lib/bridgetown-core/commands/plugins.rb +14 -13
  14. data/lib/bridgetown-core/commands/serve.rb +0 -14
  15. data/lib/bridgetown-core/component.rb +178 -0
  16. data/lib/bridgetown-core/concerns/data_accessible.rb +1 -0
  17. data/lib/bridgetown-core/concerns/front_matter_importer.rb +52 -0
  18. data/lib/bridgetown-core/concerns/site/configurable.rb +10 -10
  19. data/lib/bridgetown-core/concerns/site/content.rb +56 -15
  20. data/lib/bridgetown-core/concerns/site/localizable.rb +3 -5
  21. data/lib/bridgetown-core/concerns/site/processable.rb +6 -4
  22. data/lib/bridgetown-core/concerns/site/renderable.rb +26 -0
  23. data/lib/bridgetown-core/concerns/site/writable.rb +12 -2
  24. data/lib/bridgetown-core/concerns/validatable.rb +2 -5
  25. data/lib/bridgetown-core/configuration.rb +51 -30
  26. data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -3
  27. data/lib/bridgetown-core/configurations/netlify.rb +1 -0
  28. data/lib/bridgetown-core/configurations/tailwindcss.rb +1 -3
  29. data/lib/bridgetown-core/converter.rb +23 -0
  30. data/lib/bridgetown-core/converters/erb_templates.rb +51 -35
  31. data/lib/bridgetown-core/converters/identity.rb +0 -9
  32. data/lib/bridgetown-core/converters/liquid_templates.rb +1 -1
  33. data/lib/bridgetown-core/converters/markdown.rb +14 -4
  34. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +5 -38
  35. data/lib/bridgetown-core/converters/ruby_templates.rb +17 -0
  36. data/lib/bridgetown-core/converters/smartypants.rb +3 -1
  37. data/lib/bridgetown-core/core_ext/psych.rb +19 -0
  38. data/lib/bridgetown-core/current.rb +10 -0
  39. data/lib/bridgetown-core/document.rb +9 -16
  40. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  41. data/lib/bridgetown-core/drops/page_drop.rb +4 -0
  42. data/lib/bridgetown-core/drops/relations_drop.rb +23 -0
  43. data/lib/bridgetown-core/drops/resource_drop.rb +83 -0
  44. data/lib/bridgetown-core/drops/site_drop.rb +33 -8
  45. data/lib/bridgetown-core/drops/unified_payload_drop.rb +5 -0
  46. data/lib/bridgetown-core/entry_filter.rb +17 -28
  47. data/lib/bridgetown-core/errors.rb +0 -2
  48. data/lib/bridgetown-core/filters.rb +3 -26
  49. data/lib/bridgetown-core/filters/from_liquid.rb +23 -0
  50. data/lib/bridgetown-core/filters/url_filters.rb +12 -0
  51. data/lib/bridgetown-core/frontmatter_defaults.rb +1 -1
  52. data/lib/bridgetown-core/generators/prototype_generator.rb +37 -19
  53. data/lib/bridgetown-core/helpers.rb +48 -9
  54. data/lib/bridgetown-core/layout.rb +28 -13
  55. data/lib/bridgetown-core/liquid_renderer/file.rb +1 -0
  56. data/lib/bridgetown-core/liquid_renderer/table.rb +1 -0
  57. data/lib/bridgetown-core/model/base.rb +138 -0
  58. data/lib/bridgetown-core/model/builder_origin.rb +40 -0
  59. data/lib/bridgetown-core/model/origin.rb +38 -0
  60. data/lib/bridgetown-core/model/repo_origin.rb +126 -0
  61. data/lib/bridgetown-core/page.rb +11 -2
  62. data/lib/bridgetown-core/plugin_manager.rb +1 -3
  63. data/lib/bridgetown-core/publisher.rb +8 -2
  64. data/lib/bridgetown-core/reader.rb +37 -22
  65. data/lib/bridgetown-core/readers/data_reader.rb +5 -5
  66. data/lib/bridgetown-core/readers/defaults_reader.rb +1 -1
  67. data/lib/bridgetown-core/readers/page_reader.rb +1 -0
  68. data/lib/bridgetown-core/readers/post_reader.rb +5 -4
  69. data/lib/bridgetown-core/regenerator.rb +9 -2
  70. data/lib/bridgetown-core/related_posts.rb +9 -6
  71. data/lib/bridgetown-core/renderer.rb +6 -13
  72. data/lib/bridgetown-core/resource/base.rb +313 -0
  73. data/lib/bridgetown-core/resource/destination.rb +49 -0
  74. data/lib/bridgetown-core/resource/permalink_processor.rb +179 -0
  75. data/lib/bridgetown-core/resource/relations.rb +132 -0
  76. data/lib/bridgetown-core/resource/taxonomy_term.rb +34 -0
  77. data/lib/bridgetown-core/resource/taxonomy_type.rb +56 -0
  78. data/lib/bridgetown-core/resource/transformer.rb +177 -0
  79. data/lib/bridgetown-core/ruby_template_view.rb +11 -11
  80. data/lib/bridgetown-core/site.rb +13 -6
  81. data/lib/bridgetown-core/static_file.rb +33 -10
  82. data/lib/bridgetown-core/tags/highlight.rb +2 -15
  83. data/lib/bridgetown-core/tags/include.rb +1 -1
  84. data/lib/bridgetown-core/tags/post_url.rb +2 -2
  85. data/lib/bridgetown-core/url.rb +1 -0
  86. data/lib/bridgetown-core/utils.rb +49 -43
  87. data/lib/bridgetown-core/utils/require_gems.rb +60 -0
  88. data/lib/bridgetown-core/utils/ruby_exec.rb +6 -9
  89. data/lib/bridgetown-core/utils/ruby_front_matter.rb +39 -0
  90. data/lib/bridgetown-core/version.rb +2 -2
  91. data/lib/bridgetown-core/watcher.rb +1 -1
  92. data/lib/bridgetown-core/yaml_parser.rb +22 -0
  93. data/lib/site_template/package.json.erb +2 -2
  94. data/lib/site_template/plugins/site_builder.rb +1 -1
  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 +39 -40
  98. data/lib/bridgetown-core/external.rb +0 -58
  99. data/lib/bridgetown-core/page_without_a_file.rb +0 -17
  100. data/lib/bridgetown-core/path_manager.rb +0 -31
  101. data/lib/bridgetown-core/readers/collection_reader.rb +0 -23
  102. data/lib/bridgetown-core/readers/static_file_reader.rb +0 -25
  103. data/lib/bridgetown-core/utils/exec.rb +0 -26
  104. data/lib/bridgetown-core/utils/internet.rb +0 -37
  105. data/lib/bridgetown-core/utils/platforms.rb +0 -80
  106. data/lib/bridgetown-core/utils/thread_event.rb +0 -31
  107. data/lib/bridgetown-core/utils/win_tz.rb +0 -75
@@ -8,7 +8,7 @@ module Bridgetown
8
8
  mutable false
9
9
 
10
10
  def_delegator :@obj, :write?, :output
11
- def_delegators :@obj, :label, :docs, :files, :relative_path
11
+ def_delegators :@obj, :label, :docs, :files, :relative_path, :resources, :static_files
12
12
 
13
13
  private def_delegator :@obj, :metadata, :fallback_data
14
14
 
@@ -9,6 +9,10 @@ module Bridgetown
9
9
 
10
10
  def_delegators :@obj, :content, :dir, :name, :path, :url, :pager
11
11
  private def_delegator :@obj, :data, :fallback_data
12
+
13
+ def relative_url
14
+ @obj.relative_url
15
+ end
12
16
  end
13
17
  end
14
18
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Drops
5
+ class RelationsDrop < Drop
6
+ mutable false
7
+
8
+ def [](type)
9
+ return nil unless type.to_s.in?(@obj.relation_types)
10
+
11
+ @obj.resources_for_type(type)
12
+ end
13
+
14
+ def key?(type)
15
+ type.to_s.in?(@obj.relation_types)
16
+ end
17
+
18
+ def fallback_data
19
+ {}
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Drops
5
+ class ResourceDrop < Drop
6
+ extend Forwardable
7
+
8
+ NESTED_OBJECT_FIELD_BLACKLIST = %w(
9
+ content output excerpt next previous
10
+ ).freeze
11
+
12
+ mutable false
13
+
14
+ def_delegator :@obj, :relative_path, :path
15
+ def_delegators :@obj,
16
+ :id,
17
+ :data,
18
+ :output,
19
+ :content,
20
+ :to_s,
21
+ :absolute_url,
22
+ :relative_path,
23
+ :relative_url,
24
+ :date,
25
+ :taxonomies,
26
+ :relations
27
+
28
+ private def_delegator :@obj, :data, :fallback_data
29
+
30
+ def collection
31
+ @collection ||= @obj.collection.to_liquid
32
+ end
33
+
34
+ def excerpt
35
+ fallback_data["excerpt"].to_s
36
+ end
37
+
38
+ def <=>(other)
39
+ return nil unless other.is_a? ResourceDrop
40
+
41
+ cmp = self["date"] <=> other["date"]
42
+ cmp = self["path"] <=> other["path"] if cmp.nil? || cmp.zero?
43
+ cmp
44
+ end
45
+
46
+ def previous
47
+ @previous ||= @obj.previous_resource.to_liquid
48
+ end
49
+
50
+ def next
51
+ @next ||= @obj.previous_resource.to_liquid
52
+ end
53
+
54
+ # Generate a Hash for use in generating JSON.
55
+ # This is useful if fields need to be cleared before the JSON can generate.
56
+ #
57
+ # state - the JSON::State object which determines the state of current processing.
58
+ #
59
+ # Returns a Hash ready for JSON generation.
60
+ def hash_for_json(state = nil)
61
+ to_h.tap do |hash|
62
+ # use collection label in the hash
63
+ hash["collection"] = hash["collection"]["label"] if hash["collection"]
64
+
65
+ if state && state.depth >= 2
66
+ hash["previous"] = collapse_document(hash["previous"]) if hash["previous"]
67
+ hash["next"] = collapse_document(hash["next"]) if hash["next"]
68
+ end
69
+ end
70
+ end
71
+
72
+ # Generate a Hash which breaks the recursive chain.
73
+ # Certain fields which are normally available are omitted.
74
+ #
75
+ # Returns a Hash with only non-recursive fields present.
76
+ def collapse_document(doc)
77
+ doc.keys.each_with_object({}) do |(key, _), result|
78
+ result[key] = doc[key] unless NESTED_OBJECT_FIELD_BLACKLIST.include?(key)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -7,35 +7,53 @@ module Bridgetown
7
7
 
8
8
  mutable false
9
9
 
10
- def_delegator :@obj, :data
11
- def_delegators :@obj, :locale, :time, :pages, :static_files, :tags, :categories
10
+ def_delegators :@obj,
11
+ :data,
12
+ :locale,
13
+ :time,
14
+ :pages,
15
+ :generated_pages,
16
+ :static_files,
17
+ :tags,
18
+ :categories,
19
+ :taxonomies,
20
+ :taxonomy_types
12
21
 
13
22
  private def_delegator :@obj, :config, :fallback_data
14
23
 
15
24
  attr_writer :current_document
16
25
 
17
26
  def [](key)
18
- if key != "posts" && @obj.collections.key?(key)
19
- @obj.collections[key].docs
20
- else
21
- super(key)
27
+ if !@obj.uses_resource? && !%w(posts data).freeze.include?(key) &&
28
+ @obj.collections.key?(key)
29
+ return @obj.collections[key].docs
22
30
  end
31
+
32
+ super(key)
23
33
  end
24
34
 
25
35
  def key?(key)
26
- (key != "posts" && @obj.collections.key?(key)) || super
36
+ (!@obj.uses_resource? && key != "posts" && @obj.collections.key?(key)) || super
37
+ end
38
+
39
+ def uses_resource
40
+ @obj.uses_resource?
27
41
  end
28
42
 
29
43
  def posts
30
- @site_posts ||= @obj.posts.docs.sort { |a, b| b <=> a }
44
+ unless @obj.uses_resource?
45
+ @site_posts ||= @obj.collections.posts.docs.sort { |a, b| b <=> a }
46
+ end
31
47
  end
32
48
 
49
+ # TODO: deprecate before v1.0
33
50
  def html_pages
34
51
  @site_html_pages ||= @obj.pages.select do |page|
35
52
  page.html? || page.url.end_with?("/")
36
53
  end
37
54
  end
38
55
 
56
+ # TODO: deprecate before v1.0
39
57
  def collections
40
58
  @site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
41
59
  end
@@ -50,6 +68,10 @@ module Bridgetown
50
68
  @documents ||= @obj.documents
51
69
  end
52
70
 
71
+ def resources
72
+ @resources ||= @obj.resources
73
+ end
74
+
53
75
  def contents
54
76
  @contents ||= @obj.contents
55
77
  end
@@ -58,6 +80,9 @@ module Bridgetown
58
80
  @site_metadata ||= @obj.data["site_metadata"]
59
81
  end
60
82
 
83
+ # TODO: change this so you *do* use site.config...aka site.config.timezone,
84
+ # not site.timezone
85
+ #
61
86
  # return nil for `{{ site.config }}` even if --config was passed via CLI
62
87
  def config; end
63
88
  end
@@ -6,6 +6,7 @@ module Bridgetown
6
6
  mutable true
7
7
 
8
8
  attr_accessor :page, :layout, :content, :paginator
9
+ alias_method :resource, :page
9
10
 
10
11
  def bridgetown
11
12
  BridgetownDrop.global
@@ -15,6 +16,10 @@ module Bridgetown
15
16
  @site_drop ||= SiteDrop.new(@obj)
16
17
  end
17
18
 
19
+ def collections
20
+ @obj.collections
21
+ end
22
+
18
23
  private
19
24
 
20
25
  def fallback_data
@@ -4,12 +4,14 @@ module Bridgetown
4
4
  class EntryFilter
5
5
  attr_reader :site
6
6
  SPECIAL_LEADING_CHAR_REGEX = %r!\A#{Regexp.union([".", "_", "#", "~"])}!o.freeze
7
+ SPECIAL_LEADING_CHAR_NO_UNDERSCORES_REGEX = %r!\A#{Regexp.union([".", "#", "~"])}!o.freeze
7
8
 
8
- def initialize(site, base_directory = nil)
9
+ def initialize(site, base_directory: nil, include_underscores: false)
9
10
  @site = site
10
11
  @base_directory = derive_base_directory(
11
12
  @site, base_directory.to_s.dup
12
13
  )
14
+ @include_underscores = include_underscores
13
15
  end
14
16
 
15
17
  def base_directory
@@ -32,8 +34,6 @@ module Bridgetown
32
34
  # Reject this entry if it is just a "dot" representation.
33
35
  # e.g.: '.', '..', '_movies/.', 'music/..', etc
34
36
  next true if e.end_with?(".")
35
- # Reject this entry if it is a symlink.
36
- next true if symlink?(e)
37
37
  # Do not reject this entry if it is included.
38
38
  next false if included?(e)
39
39
 
@@ -43,13 +43,18 @@ module Bridgetown
43
43
  end
44
44
 
45
45
  def included?(entry)
46
- glob_include?(site.include, entry) ||
47
- glob_include?(site.include, File.basename(entry))
46
+ glob_include?(site.config.include, entry) ||
47
+ glob_include?(site.config.include, File.basename(entry))
48
48
  end
49
49
 
50
50
  def special?(entry)
51
- SPECIAL_LEADING_CHAR_REGEX.match?(entry) ||
52
- SPECIAL_LEADING_CHAR_REGEX.match?(File.basename(entry))
51
+ use_regex = if @include_underscores
52
+ SPECIAL_LEADING_CHAR_NO_UNDERSCORES_REGEX
53
+ else
54
+ SPECIAL_LEADING_CHAR_REGEX
55
+ end
56
+
57
+ use_regex.match?(entry) || use_regex.match?(File.basename(entry))
53
58
  end
54
59
 
55
60
  def backup?(entry)
@@ -57,7 +62,9 @@ module Bridgetown
57
62
  end
58
63
 
59
64
  def excluded?(entry)
60
- glob_include?(site.exclude - site.include, relative_to_source(entry)).tap do |excluded|
65
+ glob_include?(
66
+ site.config.exclude - site.config.include, relative_to_source(entry)
67
+ ).tap do |excluded|
61
68
  if excluded
62
69
  Bridgetown.logger.debug(
63
70
  "EntryFilter:",
@@ -67,33 +74,15 @@ module Bridgetown
67
74
  end
68
75
  end
69
76
 
70
- # --
71
- # TODO: this is for old Safe mode and can be removed.
72
- # --
73
- def symlink?(_entry)
74
- false
75
- end
76
-
77
- # --
78
- # NOTE: Pathutil#in_path? gets the realpath.
79
- # @param [<Anything>] entry the entry you want to validate.
80
- # Check if a path is outside of our given root.
81
- # --
82
- def symlink_outside_site_source?(entry)
83
- !Pathutil.new(entry).in_path?(
84
- site.in_source_dir
85
- )
86
- end
87
-
88
77
  # Check if an entry matches a specific pattern.
89
78
  # Returns true if path matches against any glob pattern, else false.
90
79
  def glob_include?(enumerator, entry)
91
- entry_with_source = PathManager.join(site.source, entry)
80
+ entry_with_source = File.join(site.source, entry)
92
81
 
93
82
  enumerator.any? do |pattern|
94
83
  case pattern
95
84
  when String
96
- pattern_with_source = PathManager.join(site.source, pattern)
85
+ pattern_with_source = File.join(site.source, pattern)
97
86
 
98
87
  File.fnmatch?(pattern_with_source, entry_with_source) ||
99
88
  entry_with_source.start_with?(pattern_with_source)
@@ -4,8 +4,6 @@ module Bridgetown
4
4
  module Errors
5
5
  FatalException = Class.new(::RuntimeError)
6
6
 
7
- InvalidThemeName = Class.new(FatalException)
8
-
9
7
  DropMutationException = Class.new(FatalException)
10
8
  InvalidPermalinkError = Class.new(FatalException)
11
9
  InvalidYAMLFrontMatterError = Class.new(FatalException)
@@ -31,30 +31,6 @@ module Bridgetown
31
31
  ).convert(input.to_s)
32
32
  end
33
33
 
34
- # TODO: This should be removed, there is no Sass converter
35
- # Convert a Sass string into CSS output.
36
- #
37
- # input - The Sass String to convert.
38
- #
39
- # Returns the CSS formatted String.
40
- def sassify(input)
41
- @context.registers[:site].find_converter_instance(
42
- Bridgetown::Converters::Sass
43
- ).convert(input)
44
- end
45
-
46
- # TODO: This should be removed, there is no Scss converter
47
- # Convert a Scss string into CSS output.
48
- #
49
- # input - The Scss String to convert.
50
- #
51
- # Returns the CSS formatted String.
52
- def scssify(input)
53
- @context.registers[:site].find_converter_instance(
54
- Bridgetown::Converters::Scss
55
- ).convert(input)
56
- end
57
-
58
34
  # Slugify a filename or title.
59
35
  #
60
36
  # input - The filename or title to slugify.
@@ -63,6 +39,7 @@ module Bridgetown
63
39
  # Returns the given filename or title as a lowercase URL String.
64
40
  # See Utils.slugify for more detail.
65
41
  def slugify(input, mode = nil)
42
+ mode = @context.registers[:site].config.slugify_mode if mode.nil?
66
43
  Utils.slugify(input, mode: mode)
67
44
  end
68
45
 
@@ -102,7 +79,7 @@ module Bridgetown
102
79
  #
103
80
  # Returns the escaped String.
104
81
  def cgi_escape(input)
105
- CGI.escape(input)
82
+ CGI.escape(input.to_s)
106
83
  end
107
84
 
108
85
  # URI escape a string.
@@ -131,7 +108,7 @@ module Bridgetown
131
108
  script += "function(c){{var j=c.charCodeAt(0);if((j>=33)&&(j<=126)){"
132
109
  script += "return String.fromCharCode(33+((j+ 14)%94));}"
133
110
  script += "else{return String.fromCharCode(j);}}}));</script>"
134
- script
111
+ script.html_safe
135
112
  end
136
113
 
137
114
  # Replace any whitespace in the input string with a single space
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Filters
5
+ module FromLiquid
6
+ extend Liquid::StandardFilters
7
+
8
+ def strip_html(input)
9
+ FromLiquid.strip_html(input)
10
+ end
11
+
12
+ def strip_newlines(input)
13
+ FromLiquid.strip_newlines(input)
14
+ end
15
+
16
+ def newline_to_br(input)
17
+ FromLiquid.newline_to_br(input)
18
+ end
19
+
20
+ # FYI, truncate and truncate words are already provided by ActiveSupport! =)
21
+ end
22
+ end
23
+ end
@@ -3,6 +3,8 @@
3
3
  module Bridgetown
4
4
  module Filters
5
5
  module URLFilters
6
+ extend self
7
+
6
8
  # Produces an absolute URL based on site.url and site.baseurl.
7
9
  #
8
10
  # input - the URL to make absolute.
@@ -35,6 +37,16 @@ module Bridgetown
35
37
  input.sub(%r!/index\.html?$!, "/")
36
38
  end
37
39
 
40
+ # Strips the extension (if present) off a path/URL
41
+ #
42
+ # @param input [Object] value which responds to `to_s`
43
+ # @return [String]
44
+ def strip_extname(input)
45
+ Pathname.new(input.to_s).yield_self do |path|
46
+ path.dirname + path.basename(".*")
47
+ end.to_s
48
+ end
49
+
38
50
  private
39
51
 
40
52
  def compute_absolute_url(input)
@@ -13,7 +13,7 @@ module Bridgetown
13
13
  end
14
14
 
15
15
  def reset
16
- @glob_cache = {} if @glob_cache
16
+ @glob_cache = {}
17
17
  end
18
18
 
19
19
  def update_deprecated_types(set)