bridgetown-core 0.15.0.beta3 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +14 -0
  3. data/bridgetown-core.gemspec +3 -0
  4. data/lib/bridgetown-core.rb +6 -1
  5. data/lib/bridgetown-core/commands/concerns/actions.rb +29 -23
  6. data/lib/bridgetown-core/commands/console.rb +12 -2
  7. data/lib/bridgetown-core/commands/serve.rb +5 -0
  8. data/lib/bridgetown-core/concerns/data_accessible.rb +19 -0
  9. data/lib/bridgetown-core/concerns/layout_placeable.rb +17 -0
  10. data/lib/bridgetown-core/concerns/liquid_renderable.rb +20 -0
  11. data/lib/bridgetown-core/concerns/publishable.rb +10 -0
  12. data/lib/bridgetown-core/concerns/site/configurable.rb +62 -31
  13. data/lib/bridgetown-core/concerns/site/content.rb +88 -29
  14. data/lib/bridgetown-core/concerns/site/extensible.rb +15 -12
  15. data/lib/bridgetown-core/concerns/site/processable.rb +12 -10
  16. data/lib/bridgetown-core/concerns/site/renderable.rb +22 -2
  17. data/lib/bridgetown-core/concerns/site/writable.rb +16 -2
  18. data/lib/bridgetown-core/concerns/validatable.rb +59 -0
  19. data/lib/bridgetown-core/configuration.rb +1 -0
  20. data/lib/bridgetown-core/converter.rb +34 -0
  21. data/lib/bridgetown-core/converters/erb_templates.rb +78 -0
  22. data/lib/bridgetown-core/converters/markdown.rb +6 -23
  23. data/lib/bridgetown-core/converters/smartypants.rb +0 -10
  24. data/lib/bridgetown-core/document.rb +8 -52
  25. data/lib/bridgetown-core/drops/document_drop.rb +9 -1
  26. data/lib/bridgetown-core/errors.rb +2 -0
  27. data/lib/bridgetown-core/excerpt.rb +1 -6
  28. data/lib/bridgetown-core/filters.rb +2 -0
  29. data/lib/bridgetown-core/layout.rb +24 -1
  30. data/lib/bridgetown-core/liquid_renderer/file_system.rb +1 -1
  31. data/lib/bridgetown-core/page.rb +34 -25
  32. data/lib/bridgetown-core/plugin_manager.rb +14 -5
  33. data/lib/bridgetown-core/regenerator.rb +1 -1
  34. data/lib/bridgetown-core/renderer.rb +38 -12
  35. data/lib/bridgetown-core/ruby_template_view.rb +98 -0
  36. data/lib/bridgetown-core/tags/class_map.rb +90 -0
  37. data/lib/bridgetown-core/tags/include.rb +2 -0
  38. data/lib/bridgetown-core/tags/render_content.rb +11 -1
  39. data/lib/bridgetown-core/tags/webpack_path.rb +19 -22
  40. data/lib/bridgetown-core/utils.rb +53 -0
  41. data/lib/bridgetown-core/version.rb +2 -2
  42. data/lib/site_template/bridgetown.config.yml +5 -3
  43. data/lib/site_template/src/_components/{footer.html → footer.liquid} +0 -0
  44. data/lib/site_template/src/_components/{head.html → head.liquid} +0 -0
  45. data/lib/site_template/src/_components/{navbar.html → navbar.liquid} +0 -0
  46. data/lib/site_template/src/_layouts/{default.html → default.liquid} +1 -1
  47. data/lib/site_template/src/_layouts/{home.html → home.liquid} +0 -0
  48. data/lib/site_template/src/_layouts/{page.html → page.liquid} +0 -0
  49. data/lib/site_template/src/_layouts/{post.html → post.liquid} +0 -0
  50. metadata +59 -10
  51. data/lib/bridgetown-core/concerns/convertible.rb +0 -235
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+ require "active_support/core_ext/hash/keys"
5
+
6
+ module Bridgetown
7
+ class RubyTemplateView
8
+ class Helpers
9
+ include Bridgetown::Filters
10
+
11
+ Context = Struct.new(:registers)
12
+
13
+ def initialize(site)
14
+ @site = site
15
+
16
+ # duck typing for Liquid context
17
+ @context = Context.new({ site: @site })
18
+ end
19
+
20
+ def webpack_path(asset_type)
21
+ Bridgetown::Utils.parse_webpack_manifest_file(@site, asset_type.to_s)
22
+ end
23
+ end
24
+
25
+ attr_reader :layout, :page, :site, :content
26
+
27
+ def initialize(convertible)
28
+ if convertible.is_a?(Layout)
29
+ @layout = convertible
30
+ @page = layout.current_document
31
+ @content = layout.current_document_output
32
+ else
33
+ @page = convertible
34
+ end
35
+ @site = page.site
36
+ end
37
+
38
+ def partial(_partial_name, _options = {})
39
+ raise "Must be implemented in a subclass"
40
+ end
41
+
42
+ def site_drop
43
+ site.site_payload.site
44
+ end
45
+
46
+ def liquid_render(component, options = {})
47
+ render_statement = _render_statement(component, options)
48
+
49
+ template = site.liquid_renderer.file(
50
+ "#{page.path}.#{Digest::SHA2.hexdigest(render_statement)}"
51
+ ).parse(render_statement)
52
+ template.warnings.each do |e|
53
+ Bridgetown.logger.warn "Liquid Warning:",
54
+ LiquidRenderer.format_error(e, path || document.relative_path)
55
+ end
56
+ template.render!(options.deep_stringify_keys, _liquid_context)
57
+ end
58
+
59
+ def helpers
60
+ @helpers ||= Helpers.new(@site)
61
+ end
62
+
63
+ def method_missing(method, *args, &block)
64
+ if helpers.respond_to?(method.to_sym)
65
+ helpers.send method.to_sym, *args, &block
66
+ else
67
+ super
68
+ end
69
+ end
70
+
71
+ def respond_to_missing?(method, include_private = false)
72
+ helpers.respond_to?(method.to_sym, include_private) || super
73
+ end
74
+
75
+ private
76
+
77
+ def _render_statement(component, options)
78
+ render_statement = ["{% render \"#{component}\""]
79
+ unless options.empty?
80
+ render_statement << ", " + options.keys.map { |k| "#{k}: #{k}" }.join(", ")
81
+ end
82
+ render_statement << " %}"
83
+ render_statement.join
84
+ end
85
+
86
+ def _liquid_context
87
+ {
88
+ registers: {
89
+ site: site,
90
+ page: page,
91
+ cached_partials: Bridgetown::Renderer.cached_partials,
92
+ },
93
+ strict_filters: site.config["liquid"]["strict_filters"],
94
+ strict_variables: site.config["liquid"]["strict_variables"],
95
+ }
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module Bridgetown
6
+ module Tags
7
+ # A ClassMap class is meant to take a hash and append styles based on if the
8
+ # value is truthy or falsy
9
+ #
10
+ # @example
11
+ # center-var = true
12
+ # small-var = nil
13
+ #
14
+ # # input
15
+ # <div class="{% class_map has-centered-text: center-var, is-small: small-var %}">
16
+ # Text
17
+ # </div>
18
+ #
19
+ # # output
20
+ # <div class="has-centered-text">
21
+ # Text
22
+ # </div>
23
+ class ClassMap < Liquid::Tag
24
+ # @see https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
25
+ FALSE_VALUES = [
26
+ nil, "nil", "NIL", false, 0, "0", :"0", "f", :f, "F", :F, "false",
27
+ false, "FALSE", :FALSE,
28
+ ].to_set.freeze
29
+
30
+ # @param tag_name [String] The name to use for the tag
31
+ # @param input [String] The input to the tag
32
+ # @param tokens [Hash] A hash of config tokens for Liquid.
33
+ #
34
+ #
35
+ # @return [ClassMap] Returns a ClassMap object
36
+ def initialize(tag_name, input, tokens)
37
+ super
38
+ @input = input
39
+ end
40
+
41
+ def render(context)
42
+ class_map(@input, context)
43
+ end
44
+
45
+ private
46
+
47
+ def class_map(string, context)
48
+ ary = []
49
+
50
+ string.split(%r!,\s+!).each do |item|
51
+ kv_pair = item.split(%r!:\s+!)
52
+ klass = kv_pair[0]
53
+ variable = kv_pair[1]
54
+
55
+ # Check if a user wants the opposite of the variable
56
+ if variable[0] == "!"
57
+ check_opposite = true
58
+ variable.slice!(1..-1)
59
+ end
60
+
61
+ variable = find_variable(context, variable)
62
+
63
+ if check_opposite
64
+ ary.push(klass) if FALSE_VALUES.include?(variable)
65
+ else
66
+ ary.push(klass) unless FALSE_VALUES.include?(variable)
67
+ end
68
+ end
69
+
70
+ ary.join(" ")
71
+
72
+ # Gracefully handle if syntax is improper
73
+ rescue NoMethodError
74
+ "invalid-class-map"
75
+ end
76
+
77
+ def find_variable(context, variable)
78
+ lookup = context
79
+
80
+ variable.split(".").each do |value|
81
+ lookup = lookup[value.strip]
82
+ end
83
+
84
+ lookup || nil
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ Liquid::Template.register_tag("class_map", Bridgetown::Tags::ClassMap)
@@ -212,7 +212,9 @@ module Bridgetown
212
212
  else
213
213
  File.join(site.config["collections_dir"], page_payload["path"])
214
214
  end
215
+ # rubocop:disable Performance/DeleteSuffix
215
216
  resource_path.sub!(%r!/#excerpt\z!, "")
217
+ # rubocop:enable Performance/DeleteSuffix
216
218
  site.in_source_dir File.dirname(resource_path)
217
219
  end
218
220
  end
@@ -3,6 +3,7 @@
3
3
  module Bridgetown
4
4
  module Tags
5
5
  class BlockRenderTag < Liquid::Block
6
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
6
7
  def render(context)
7
8
  context.stack({}) do
8
9
  # unindent the incoming text
@@ -19,7 +20,15 @@ module Bridgetown
19
20
  unless regions.empty?
20
21
  regions.each do |region_name, region_content|
21
22
  region_name = region_name.sub("content_with_region_", "")
22
- context[region_name] = converter.convert(region_content.strip_heredoc)
23
+
24
+ if region_name.end_with? ":markdown"
25
+ region_name.sub!(%r!:markdown$!, "")
26
+ context[region_name] = converter.convert(
27
+ Bridgetown::Utils.reindent_for_markdown(region_content)
28
+ )
29
+ else
30
+ context[region_name] = region_content
31
+ end
23
32
  render_params.push "#{region_name}: #{region_name}"
24
33
  end
25
34
  end
@@ -28,6 +37,7 @@ module Bridgetown
28
37
  .render_tag(context, +"")
29
38
  end
30
39
  end
40
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
31
41
 
32
42
  private
33
43
 
@@ -2,38 +2,35 @@
2
2
 
3
3
  module Bridgetown
4
4
  module Tags
5
+ # A helper class to help find the path to webpack asset inside of a webpack
6
+ # manifest file.
5
7
  class WebpackPath < Liquid::Tag
6
- include Bridgetown::Filters::URLFilters
7
-
8
- def initialize(tag_name, asset_type, tokens)
8
+ # @param tag_name [String] Name of the tag
9
+ # @param asset_type [String] The type of asset to parse (js, css)
10
+ # @param options [Hash] An options hash
11
+ # @return [void]
12
+ # @see {https://www.rdoc.info/github/Shopify/liquid/Liquid/Tag#initialize-instance_method}
13
+ def initialize(tag_name, asset_type, options)
9
14
  super
10
15
 
11
16
  # js or css
12
17
  @asset_type = asset_type.strip
13
18
  end
14
19
 
20
+ # Render an asset path based on the Webpack manifest file
21
+ # @param context [Liquid::Context] Context passed to the tag
22
+ #
23
+ # @return [String] Returns "MISSING_WEBPACK_MANIFEST" if the manifest
24
+ # file isn't found
25
+ # @return [String] Returns a blank string if the asset isn't found
26
+ # @return [String] Returns the path to the asset if no issues parsing
27
+ #
28
+ # @raise [WebpackAssetError] if unable to find css or js in the manifest
29
+ # file
15
30
  def render(context)
16
31
  @context = context
17
32
  site = context.registers[:site]
18
-
19
- frontend_path = relative_url("_bridgetown/static")
20
-
21
- manifest_file = site.in_root_dir(".bridgetown-webpack", "manifest.json")
22
- if File.exist?(manifest_file)
23
- manifest = JSON.parse(File.read(manifest_file))
24
- if @asset_type == "js"
25
- js_path = manifest["main.js"].split("/").last
26
- [frontend_path, "js", js_path].join("/")
27
- elsif @asset_type == "css"
28
- css_path = manifest["main.css"].split("/").last
29
- [frontend_path, "css", css_path].join("/")
30
- else
31
- Bridgetown.logger.error("Unknown Webpack asset type", @asset_type)
32
- nil
33
- end
34
- else
35
- "MISSING_WEBPACK_MANIFEST"
36
- end
33
+ Bridgetown::Utils.parse_webpack_manifest_file(site, @asset_type) || ""
37
34
  end
38
35
  end
39
36
  end
@@ -331,6 +331,59 @@ module Bridgetown
331
331
  end
332
332
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
333
333
 
334
+ # Return an asset path based on the Webpack manifest file
335
+ # @param site [Bridgetown::Site] The current site object
336
+ # @param asset_type [String] js or css
337
+ #
338
+ # @return [String] Returns "MISSING_WEBPACK_MANIFEST" if the manifest
339
+ # file isnt found
340
+ # @return [nil] Returns nil if the asset isnt found
341
+ # @return [String] Returns the path to the asset if no issues parsing
342
+ #
343
+ # @raise [WebpackAssetError] if unable to find css or js in the manifest
344
+ # file
345
+ def parse_webpack_manifest_file(site, asset_type)
346
+ manifest_file = site.in_root_dir(".bridgetown-webpack", "manifest.json")
347
+ return "MISSING_WEBPACK_MANIFEST" unless File.exist?(manifest_file)
348
+
349
+ manifest = JSON.parse(File.read(manifest_file))
350
+
351
+ known_assets = %w(js css)
352
+ if known_assets.include?(asset_type)
353
+ asset_path = manifest["main.#{asset_type}"]
354
+
355
+ log_webpack_asset_error(asset_type) && return if asset_path.nil?
356
+
357
+ asset_path = asset_path.split("/").last
358
+ return [static_frontend_path(site), asset_type, asset_path].join("/")
359
+ end
360
+
361
+ Bridgetown.logger.error("Unknown Webpack asset type", asset_type)
362
+ nil
363
+ end
364
+
365
+ def static_frontend_path(site)
366
+ path_parts = [site.config["baseurl"].to_s.chomp("/"), "_bridgetown/static"]
367
+ path_parts[0] = "/#{path_parts[0]}" unless path_parts[0].empty?
368
+ Addressable::URI.parse(path_parts.join("/")).normalize.to_s
369
+ end
370
+
371
+ def log_webpack_asset_error(asset_type)
372
+ error_message = "There was an error parsing your #{asset_type} files. \
373
+ Please check your #{asset_type} for any errors."
374
+
375
+ Bridgetown.logger.warn(Errors::WebpackAssetError, error_message)
376
+ end
377
+
378
+ def default_github_branch_name(repo_url)
379
+ repo_match = Bridgetown::Commands::Actions::GITHUB_REPO_REGEX.match(repo_url)
380
+ api_endpoint = "https://api.github.com/repos/#{repo_match[1]}"
381
+ JSON.parse(Faraday.get(api_endpoint).body)["default_branch"] || "master"
382
+ rescue StandardError => e
383
+ Bridgetown.logger.warn("Unable to connect to GitHub API: #{e.message}")
384
+ "master"
385
+ end
386
+
334
387
  private
335
388
 
336
389
  def merge_values(target, overwrite)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "0.15.0.beta3"
5
- CODE_NAME = "Overlook"
4
+ VERSION = "0.16.0"
5
+ CODE_NAME = "Crystal Springs"
6
6
  end
@@ -10,12 +10,14 @@
10
10
  # For reloadable site metadata like title, SEO description, social media
11
11
  # handles, etc., take a look at src/_data/site_metadata.yml
12
12
  #
13
- # If you need help with YAML syntax, here are some quick references for you:
13
+ # If you need help with YAML syntax, here are some quick references for you:
14
14
  # https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
15
15
  # https://learnxinyminutes.com/docs/yaml/
16
16
  #
17
17
 
18
18
  baseurl: "" # OPTIONAL: the subpath of your site, e.g. /blog
19
- url: "" # the base hostname & protocol for your site, e.g. http://example.com
19
+ url: "" # the base hostname & protocol for your site, e.g. https://example.com
20
20
 
21
- # Additional build settings go here
21
+ permalink: pretty
22
+
23
+ # timezone: America/Los_Angeles
@@ -4,7 +4,7 @@
4
4
  {% render "head", metadata: site.metadata, title: page.title %}
5
5
  </head>
6
6
  <body class="{{ page.layout }} {{ page.page_class }}">
7
- {% render "navbar" %}
7
+ {% render "navbar", metadata: site.metadata, page: page %}
8
8
 
9
9
  <main>
10
10
  {{ content }}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0.beta3
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-05 00:00:00.000000000 Z
11
+ date: 2020-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: awesome_print
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.8'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: colorator
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
68
  version: '1.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: erubi
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.9'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.9'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: faraday
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -248,6 +276,20 @@ dependencies:
248
276
  - - "~>"
249
277
  - !ruby/object:Gem::Version
250
278
  version: '1.0'
279
+ - !ruby/object:Gem::Dependency
280
+ name: tilt
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - "~>"
284
+ - !ruby/object:Gem::Version
285
+ version: '2.0'
286
+ type: :runtime
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - "~>"
291
+ - !ruby/object:Gem::Version
292
+ version: '2.0'
251
293
  description: Bridgetown is a Webpack-aware, Ruby-powered static site generator for
252
294
  the modern Jamstack era
253
295
  email: maintainers@bridgetownrb.com
@@ -278,15 +320,20 @@ files:
278
320
  - lib/bridgetown-core/commands/registrations.rb
279
321
  - lib/bridgetown-core/commands/serve.rb
280
322
  - lib/bridgetown-core/commands/serve/servlet.rb
281
- - lib/bridgetown-core/concerns/convertible.rb
323
+ - lib/bridgetown-core/concerns/data_accessible.rb
324
+ - lib/bridgetown-core/concerns/layout_placeable.rb
325
+ - lib/bridgetown-core/concerns/liquid_renderable.rb
326
+ - lib/bridgetown-core/concerns/publishable.rb
282
327
  - lib/bridgetown-core/concerns/site/configurable.rb
283
328
  - lib/bridgetown-core/concerns/site/content.rb
284
329
  - lib/bridgetown-core/concerns/site/extensible.rb
285
330
  - lib/bridgetown-core/concerns/site/processable.rb
286
331
  - lib/bridgetown-core/concerns/site/renderable.rb
287
332
  - lib/bridgetown-core/concerns/site/writable.rb
333
+ - lib/bridgetown-core/concerns/validatable.rb
288
334
  - lib/bridgetown-core/configuration.rb
289
335
  - lib/bridgetown-core/converter.rb
336
+ - lib/bridgetown-core/converters/erb_templates.rb
290
337
  - lib/bridgetown-core/converters/identity.rb
291
338
  - lib/bridgetown-core/converters/markdown.rb
292
339
  - lib/bridgetown-core/converters/markdown/kramdown_parser.rb
@@ -341,8 +388,10 @@ files:
341
388
  - lib/bridgetown-core/regenerator.rb
342
389
  - lib/bridgetown-core/related_posts.rb
343
390
  - lib/bridgetown-core/renderer.rb
391
+ - lib/bridgetown-core/ruby_template_view.rb
344
392
  - lib/bridgetown-core/site.rb
345
393
  - lib/bridgetown-core/static_file.rb
394
+ - lib/bridgetown-core/tags/class_map.rb
346
395
  - lib/bridgetown-core/tags/highlight.rb
347
396
  - lib/bridgetown-core/tags/include.rb
348
397
  - lib/bridgetown-core/tags/link.rb
@@ -370,14 +419,14 @@ files:
370
419
  - lib/site_template/plugins/builders/.keep
371
420
  - lib/site_template/plugins/site_builder.rb
372
421
  - lib/site_template/src/404.html
373
- - lib/site_template/src/_components/footer.html
374
- - lib/site_template/src/_components/head.html
375
- - lib/site_template/src/_components/navbar.html
422
+ - lib/site_template/src/_components/footer.liquid
423
+ - lib/site_template/src/_components/head.liquid
424
+ - lib/site_template/src/_components/navbar.liquid
376
425
  - lib/site_template/src/_data/site_metadata.yml
377
- - lib/site_template/src/_layouts/default.html
378
- - lib/site_template/src/_layouts/home.html
379
- - lib/site_template/src/_layouts/page.html
380
- - lib/site_template/src/_layouts/post.html
426
+ - lib/site_template/src/_layouts/default.liquid
427
+ - lib/site_template/src/_layouts/home.liquid
428
+ - lib/site_template/src/_layouts/page.liquid
429
+ - lib/site_template/src/_layouts/post.liquid
381
430
  - lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb
382
431
  - lib/site_template/src/about.md
383
432
  - lib/site_template/src/favicon.ico