bridgetown-core 1.0.0 → 1.1.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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -1
  3. data/bridgetown-core.gemspec +0 -1
  4. data/lib/bridgetown-core/collection.rb +39 -22
  5. data/lib/bridgetown-core/commands/apply.rb +3 -3
  6. data/lib/bridgetown-core/commands/build.rb +6 -6
  7. data/lib/bridgetown-core/commands/concerns/actions.rb +3 -2
  8. data/lib/bridgetown-core/commands/concerns/build_options.rb +2 -2
  9. data/lib/bridgetown-core/commands/configure.rb +1 -1
  10. data/lib/bridgetown-core/commands/console.rb +5 -5
  11. data/lib/bridgetown-core/commands/doctor.rb +7 -7
  12. data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +95 -12
  13. data/lib/bridgetown-core/commands/esbuild/migrate-from-webpack.rb +1 -6
  14. data/lib/bridgetown-core/commands/new.rb +20 -19
  15. data/lib/bridgetown-core/commands/plugins.rb +47 -9
  16. data/lib/bridgetown-core/commands/registrations.rb +2 -3
  17. data/lib/bridgetown-core/commands/serve.rb +2 -2
  18. data/lib/bridgetown-core/commands/start.rb +3 -0
  19. data/lib/bridgetown-core/commands/webpack/update.rb +3 -3
  20. data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +19 -14
  21. data/lib/bridgetown-core/component.rb +14 -8
  22. data/lib/bridgetown-core/concerns/localizable.rb +20 -0
  23. data/lib/bridgetown-core/concerns/prioritizable.rb +44 -0
  24. data/lib/bridgetown-core/concerns/publishable.rb +11 -1
  25. data/lib/bridgetown-core/concerns/site/configurable.rb +2 -10
  26. data/lib/bridgetown-core/concerns/site/localizable.rb +5 -1
  27. data/lib/bridgetown-core/concerns/site/ssr.rb +3 -3
  28. data/lib/bridgetown-core/concerns/site/writable.rb +28 -0
  29. data/lib/bridgetown-core/concerns/transformable.rb +2 -2
  30. data/lib/bridgetown-core/configuration.rb +4 -2
  31. data/lib/bridgetown-core/configurations/bt-postcss/postcss.config.js +5 -3
  32. data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -1
  33. data/lib/bridgetown-core/configurations/lit/esbuild-plugins.js +21 -0
  34. data/lib/bridgetown-core/configurations/lit/happy-days.lit.js +26 -0
  35. data/lib/bridgetown-core/configurations/lit/lit-components-entry.js +1 -0
  36. data/lib/bridgetown-core/configurations/lit/lit-ssr.config.js +6 -0
  37. data/lib/bridgetown-core/configurations/lit.rb +95 -0
  38. data/lib/bridgetown-core/configurations/open-props/variables.css.erb +11 -0
  39. data/lib/bridgetown-core/configurations/open-props.rb +21 -0
  40. data/lib/bridgetown-core/configurations/ruby2js/hello_world.js.rb +9 -0
  41. data/lib/bridgetown-core/configurations/ruby2js.rb +67 -0
  42. data/lib/bridgetown-core/configurations/shoelace.rb +50 -0
  43. data/lib/bridgetown-core/configurations/tailwindcss.rb +16 -2
  44. data/lib/bridgetown-core/configurations/turbo/turbo_transitions.js +1 -1
  45. data/lib/bridgetown-core/converters/erb_templates.rb +7 -2
  46. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  47. data/lib/bridgetown-core/converters/serbea_templates.rb +1 -4
  48. data/lib/bridgetown-core/drops/generated_page_drop.rb +2 -1
  49. data/lib/bridgetown-core/drops/resource_drop.rb +2 -1
  50. data/lib/bridgetown-core/errors.rb +5 -5
  51. data/lib/bridgetown-core/filters/translation_filters.rb +11 -0
  52. data/lib/bridgetown-core/filters/url_filters.rb +37 -10
  53. data/lib/bridgetown-core/filters.rb +3 -0
  54. data/lib/bridgetown-core/frontmatter_defaults.rb +14 -8
  55. data/lib/bridgetown-core/generated_page.rb +1 -0
  56. data/lib/bridgetown-core/kramdown/parser/gfm.rb +36 -0
  57. data/lib/bridgetown-core/model/base.rb +3 -4
  58. data/lib/bridgetown-core/plugin.rb +6 -37
  59. data/lib/bridgetown-core/plugin_manager.rb +3 -2
  60. data/lib/bridgetown-core/rack/boot.rb +7 -2
  61. data/lib/bridgetown-core/rack/logger.rb +14 -4
  62. data/lib/bridgetown-core/rack/roda.rb +106 -9
  63. data/lib/bridgetown-core/rack/routes.rb +67 -2
  64. data/lib/bridgetown-core/resource/base.rb +9 -6
  65. data/lib/bridgetown-core/resource/destination.rb +18 -0
  66. data/lib/bridgetown-core/resource/permalink_processor.rb +6 -4
  67. data/lib/bridgetown-core/resource/relations.rb +1 -1
  68. data/lib/bridgetown-core/ruby_template_view.rb +3 -3
  69. data/lib/bridgetown-core/static_file.rb +1 -1
  70. data/lib/bridgetown-core/tags/highlight.rb +1 -1
  71. data/lib/bridgetown-core/tags/post_url.rb +1 -1
  72. data/lib/bridgetown-core/url.rb +1 -1
  73. data/lib/bridgetown-core/utils/aux.rb +2 -1
  74. data/lib/bridgetown-core/utils/require_gems.rb +3 -6
  75. data/lib/bridgetown-core/utils.rb +24 -11
  76. data/lib/bridgetown-core/version.rb +2 -2
  77. data/lib/bridgetown-core/watcher.rb +21 -8
  78. data/lib/bridgetown-core.rb +8 -2
  79. data/lib/site_template/Gemfile.erb +4 -0
  80. data/lib/site_template/README.md +2 -2
  81. data/lib/site_template/bridgetown.config.yml +3 -0
  82. data/lib/site_template/frontend/javascript/index.js.erb +1 -0
  83. data/lib/site_template/frontend/styles/syntax-highlighting.css +77 -0
  84. data/lib/site_template/package.json.erb +18 -18
  85. data/lib/site_template/server/roda_app.rb +3 -6
  86. data/lib/site_template/src/404.html +2 -1
  87. data/lib/site_template/src/500.html +10 -0
  88. metadata +20 -19
  89. data/lib/bridgetown-core/publisher.rb +0 -29
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ unless Bridgetown::Utils.frontend_bundler_type == :esbuild
4
+ error_message = "#{"esbuild.config.js".bold} not found. (This configuration doesn't currently " \
5
+ "support Webpack.)"
6
+
7
+ @logger.error "\nError:".red, "🚨 #{error_message}"
8
+
9
+ return
10
+ end
11
+
12
+ say_status :lit, "Installing Lit + SSR Plugin..."
13
+
14
+ add_bridgetown_plugin "bridgetown-lit-renderer", version: "2.0.0.beta3"
15
+
16
+ run "yarn add lit esbuild-plugin-lit-css bridgetown-lit-renderer@2.0.0-beta3"
17
+
18
+ copy_file in_templates_dir("lit-ssr.config.js"), "config/lit-ssr.config.js"
19
+ copy_file in_templates_dir("lit-components-entry.js"), "config/lit-components-entry.js"
20
+ copy_file in_templates_dir("esbuild-plugins.js"), "config/esbuild-plugins.js"
21
+
22
+ insert_into_file "esbuild.config.js",
23
+ after: 'const build = require("./config/esbuild.defaults.js")' do
24
+ <<~JS
25
+
26
+ const { plugins } = require("./config/esbuild-plugins.js")
27
+ JS
28
+ end
29
+
30
+ found_match = false
31
+ gsub_file "esbuild.config.js", %r{const esbuildOptions = {}\n} do |_match|
32
+ found_match = true
33
+
34
+ <<~JS
35
+ const esbuildOptions = {
36
+ plugins: [...plugins],
37
+ // Uncomment the following to opt into `.global.css` & `.lit.css` nomenclature.
38
+ // Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
39
+ /*
40
+ postCssPluginConfig: {
41
+ filter: /(?:index|\.global)\.css$/,
42
+ },
43
+ */
44
+ }
45
+ JS
46
+ end
47
+
48
+ unless found_match
49
+ insert_into_file "esbuild.config.js",
50
+ after: 'const { plugins } = require("./config/esbuild-plugins.js")' do
51
+ <<~JS
52
+
53
+ // TODO: You will manually need to move any plugins below you wish to share with
54
+ // Lit SSR into the `config/esbuild-plugins.js` file.
55
+ // Then add `...plugins` as an item in your plugins array.
56
+ //
57
+ // You might also want to include the following in your esbuild config to opt into
58
+ // `.global.css` & `.lit.css` nomenclature.
59
+ // Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
60
+ /*
61
+ postCssPluginConfig: {
62
+ filter: /(?:index|\.global)\.css$/,
63
+ },
64
+ */
65
+ JS
66
+ end
67
+ end
68
+
69
+ copy_file in_templates_dir("happy-days.lit.js"), "src/_components/happy-days.lit.js"
70
+
71
+ javascript_import do
72
+ <<~JS
73
+ import "bridgetown-lit-renderer"
74
+ JS
75
+ end
76
+
77
+ insert_into_file "frontend/javascript/index.js",
78
+ before: 'import components from "bridgetownComponents/**/*.{js,jsx,js.rb,css}"' do
79
+ <<~JS
80
+ // To opt into `.global.css` & `.lit.css` nomenclature, change the `css` extension below to `global.css`.
81
+ // Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
82
+ JS
83
+ end
84
+
85
+ if found_match
86
+ say_status :lit, "Lit is now configured!"
87
+ say_status :lit,
88
+ "The `config/esbuild-plugins.js` file will let you add full-stack plugins in future."
89
+ else
90
+ say_status :lit, "Lit is just about configured!"
91
+ say_status :lit, "You will need to edit `esbuild.config.js` to finish setting up the plugin."
92
+ end
93
+
94
+ say "Check out the example `happy-days.lit.js` file in `src/_components`", :blue
95
+ say 'For further reading, check out "https://edge.bridgetownrb.com/docs/components/lit"', :blue
@@ -0,0 +1,11 @@
1
+ @import "open-props/<% if Bridgetown::Utils.frontend_bundler_type == :esbuild %>open-props.min.css<% else %>style<% end %>";
2
+
3
+ /* Uncomment this if you want addiitonal "default" styles applied: */
4
+ /* @import "open-props/normalize<% if Bridgetown::Utils.frontend_bundler_type == :esbuild %>.min.css<% end %>"; */
5
+
6
+ :root {
7
+ /* Define additional variables here. */
8
+
9
+ /* You can use variables from Open Props in your own custom properties. */
10
+ --color-medium-gray: var(--gray-7);
11
+ }
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ run "yarn add open-props"
4
+
5
+ variables_import = <<~CSS
6
+ @import "variables.css";
7
+
8
+ CSS
9
+
10
+ if File.exist?("frontend/styles/index.css")
11
+ prepend_to_file "frontend/styles/index.css", variables_import
12
+ elsif File.exist?("frontend/styles/index.scss")
13
+ prepend_to_file "frontend/styles/index.scss", variables_import
14
+ else
15
+ say "\nPlease add the following lines to your CSS index file:"
16
+ say variables_import
17
+ end
18
+
19
+ template in_templates_dir("variables.css.erb"), "frontend/styles/variables.css"
20
+
21
+ say_status :open_props, "Open Props is now configured."
@@ -0,0 +1,9 @@
1
+ class HelloWorld < HTMLElement
2
+ def connected_callback()
3
+ self.inner_html = "<p><strong>Hello World!</strong></p>"
4
+ end
5
+ end
6
+
7
+ # Try adding `<hello-world></hello-world>` somewhere on your site to see this
8
+ # example web component in action!
9
+ custom_elements.define "hello-world", HelloWorld
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ unless Bridgetown::Utils.frontend_bundler_type == :esbuild
4
+ error_message = "#{"esbuild.config.js".bold} not found. (This configuration doesn't currently " \
5
+ "support Webpack.)"
6
+
7
+ @logger.error "\nError:".red, "🚨 #{error_message}"
8
+
9
+ return
10
+ end
11
+
12
+ say_status :ruby2js, "Installing Ruby2JS..."
13
+
14
+ run "yarn add -D @ruby2js/esbuild-plugin"
15
+
16
+ found_match = false
17
+ gsub_file "esbuild.config.js", %r{const esbuildOptions = {}\n} do |_match|
18
+ found_match = true
19
+
20
+ <<~JS
21
+ const ruby2js = require("@ruby2js/esbuild-plugin")
22
+
23
+ const esbuildOptions = {
24
+ plugins: [
25
+ // See docs on Ruby2JS options here: https://www.ruby2js.com/docs/options
26
+ ruby2js({
27
+ eslevel: 2022,
28
+ autoexports: "default",
29
+ filters: ["camelCase", "functions", "lit", "esm", "return"]
30
+ })
31
+ ]
32
+ }
33
+ JS
34
+ end
35
+
36
+ unless found_match
37
+ insert_into_file "esbuild.config.js",
38
+ after: 'const build = require("./config/esbuild.defaults.js")' do
39
+ <<~JS
40
+
41
+ const ruby2js = require("@ruby2js/esbuild-plugin")
42
+
43
+ // TODO: Uncomment and move the following into your plugins array:
44
+ //
45
+ // ruby2js({
46
+ // eslevel: 2022,
47
+ // autoexports: "default",
48
+ // filters: ["camelCase", "functions", "lit", "esm", "return"]
49
+ // })
50
+ //
51
+ // See docs on Ruby2JS options here: https://www.ruby2js.com/docs/options
52
+
53
+ JS
54
+ end
55
+ end
56
+
57
+ copy_file in_templates_dir("hello_world.js.rb"), "src/_components/hello_world.js.rb"
58
+
59
+ if found_match
60
+ say_status :ruby2js, "Ruby2JS is now configured!"
61
+ else
62
+ say_status :ruby2js, "Ruby2JS is just about configured!"
63
+ say_status :ruby2js, "You will need to edit `esbuild.config.js` to finish setting up the plugin."
64
+ end
65
+
66
+ say "Check out the example `hello_world.js.rb` file in `src/_components`", :blue
67
+ say 'For further reading, check out "https://www.ruby2js.com"', :blue
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ say_status :shoelace, "Installing Shoelace..."
4
+
5
+ run "yarn add @shoelace-style/shoelace"
6
+
7
+ say 'Adding Shoelace to "frontend/javascript/index.js"...', :magenta
8
+
9
+ javascript_import do
10
+ <<~JS
11
+ // Import the base Shoelace stylesheet:
12
+ import "@shoelace-style/shoelace/dist/themes/light.css"
13
+
14
+ // Example components, mix 'n' match however you like!
15
+ import "@shoelace-style/shoelace/dist/components/button/button.js"
16
+ import "@shoelace-style/shoelace/dist/components/icon/icon.js"
17
+ import "@shoelace-style/shoelace/dist/components/spinner/spinner.js"
18
+
19
+ // Use the public icons folder:
20
+ import { setBasePath } from "@shoelace-style/shoelace/dist/utilities/base-path.js"
21
+ setBasePath("/shoelace-assets")
22
+ JS
23
+ end
24
+
25
+ say "Updating frontend build commands...", :magenta
26
+
27
+ if Bridgetown::Utils.frontend_bundler_type == :esbuild
28
+ insert_into_file "package.json", before: ' "esbuild": "node' do
29
+ <<-JS
30
+ "shoelace:copy-assets": "mkdir -p src/shoelace-assets && cp -r node_modules/@shoelace-style/shoelace/dist/assets src/shoelace-assets",
31
+ JS
32
+ end
33
+ gsub_file "package.json", %r{"esbuild": "node}, '"esbuild": "yarn shoelace:copy-assets && node'
34
+ gsub_file "package.json", %r{"esbuild-dev": "node},
35
+ '"esbuild-dev": "yarn shoelace:copy-assets && node'
36
+ else
37
+ insert_into_file "package.json", before: ' "webpack-build": "webpack' do
38
+ <<-JS
39
+ "shoelace:copy-assets": "mkdir -p src/shoelace-assets && cp -r node_modules/@shoelace-style/shoelace/dist/assets src/shoelace-assets",
40
+ JS
41
+ end
42
+ gsub_file "package.json", %r{"webpack-build": "webpack},
43
+ '"webpack-build": "yarn shoelace:copy-assets && webpack'
44
+ gsub_file "package.json", %r{"webpack-dev": "webpack},
45
+ '"webpack-dev": "yarn shoelace:copy-assets && webpack'
46
+ end
47
+
48
+ say_status :shoelace, "Shoelace is now configured!"
49
+
50
+ say 'For further reading, check out "https://shoelace.style"', :blue
@@ -21,7 +21,7 @@ run "npx tailwindcss init"
21
21
 
22
22
  gsub_file "tailwind.config.js", "content: [],", <<~JS.strip
23
23
  content: [
24
- './src/**/*.{html,md,liquid,erb,serb}',
24
+ './src/**/*.{html,md,liquid,erb,serb,rb}',
25
25
  './frontend/javascript/**/*.js',
26
26
  ],
27
27
  JS
@@ -38,6 +38,20 @@ end
38
38
 
39
39
  create_file "frontend/styles/jit-refresh.css", "/* #{Time.now.to_i} */"
40
40
 
41
+ insert_into_file "Rakefile",
42
+ after: %r{ task :(build|dev) do\n} do
43
+ <<-JS
44
+ sh "touch frontend/styles/jit-refresh.css"
45
+ JS
46
+ end
47
+
48
+ append_to_file ".gitignore" do
49
+ <<~FILES
50
+
51
+ frontend/styles/jit-refresh.css
52
+ FILES
53
+ end
54
+
41
55
  create_builder "tailwind_jit.rb" do
42
56
  <<~RUBY
43
57
  class Builders::TailwindJit < SiteBuilder
@@ -45,7 +59,7 @@ create_builder "tailwind_jit.rb" do
45
59
  hook :site, :pre_reload do |_, paths|
46
60
  # Don't trigger refresh if it's a frontend-only change
47
61
  next if paths.length == 1 && paths.first.ends_with?("manifest.json")
48
-
62
+
49
63
  # Save out a comment file to trigger Tailwind's JIT
50
64
  refresh_file = site.in_root_dir("frontend", "styles", "jit-refresh.css")
51
65
  File.write refresh_file, "/* \#{Time.now.to_i} */"
@@ -16,7 +16,7 @@ document.addEventListener("turbo:visit", () => {
16
16
  { opacity: 1, transform: "translateY(0px) scale(1)" },
17
17
  { opacity: 0, transform: `translateY(${movement}) scale(${scale})` }
18
18
  ],
19
- { duration: 300, easing: "cubic-bezier(0.45, 0, 0.55, 1)" }
19
+ { duration: 300, easing: "cubic-bezier(0.45, 0, 0.55, 1)", fill: "forwards" }
20
20
  );
21
21
 
22
22
  Promise.all(main.getAnimations().map(animation => animation.finished)).then(() => {
@@ -79,10 +79,15 @@ module Bridgetown
79
79
  Erubi.h(input)
80
80
  end
81
81
 
82
- def partial(partial_name, options = {})
82
+ def partial(partial_name = nil, **options, &block)
83
+ partial_name = options[:template] if partial_name.nil? && options[:template]
83
84
  options.merge!(options[:locals]) if options[:locals]
84
- options[:content] = yield if block_given?
85
+ options[:content] = capture(&block) if block
85
86
 
87
+ _render_partial partial_name, options
88
+ end
89
+
90
+ def _render_partial(partial_name, options)
86
91
  partial_path = _partial_path(partial_name, "erb")
87
92
  tmpl = site.tmp_cache["partial-tmpl:#{partial_path}"] ||= Tilt::ErubiTemplate.new(
88
93
  partial_path,
@@ -76,7 +76,7 @@ module Bridgetown
76
76
  @config["syntax_highlighter"] ||= config["highlighter"] || "rouge"
77
77
  @config["syntax_highlighter_opts"] ||= {}
78
78
  @config["syntax_highlighter_opts"]["guess_lang"] = @config["guess_lang"]
79
- require "kramdown-parser-gfm" if @config["input"] == "GFM"
79
+ require_relative "../../kramdown/parser/gfm" if @config["input"] == "GFM"
80
80
  end
81
81
 
82
82
  def convert(content)
@@ -7,10 +7,7 @@ module Bridgetown
7
7
  class SerbeaView < ERBView
8
8
  include Serbea::Helpers
9
9
 
10
- def partial(partial_name, options = {}, &block)
11
- options.merge!(options[:locals]) if options[:locals]
12
- options[:content] = capture(&block) if block
13
-
10
+ def _render_partial(partial_name, options)
14
11
  partial_path = _partial_path(partial_name, "serb")
15
12
  tmpl = site.tmp_cache["partial-tmpl:#{partial_path}"] ||=
16
13
  Tilt::SerbeaTemplate.new(partial_path)
@@ -15,7 +15,8 @@ module Bridgetown
15
15
  :path,
16
16
  :url,
17
17
  :relative_url,
18
- :relative_path
18
+ :relative_path,
19
+ :all_locales
19
20
 
20
21
  private def_delegator :@obj, :data, :fallback_data
21
22
  end
@@ -24,7 +24,8 @@ module Bridgetown
24
24
  :relative_url,
25
25
  :date,
26
26
  :taxonomies,
27
- :relations
27
+ :relations,
28
+ :all_locales
28
29
 
29
30
  private def_delegator :@obj, :data, :fallback_data
30
31
 
@@ -15,9 +15,9 @@ module Bridgetown
15
15
  InvalidURLError = Class.new(FatalException)
16
16
  InvalidConfigurationError = Class.new(FatalException)
17
17
 
18
- def self.print_build_error(exc, trace: false)
19
- Bridgetown.logger.error "Exception raised:", exc.class.to_s.bold
20
- Bridgetown.logger.error exc.message.reset_ansi
18
+ def self.print_build_error(exc, trace: false, logger: Bridgetown.logger)
19
+ logger.error "Exception raised:", exc.class.to_s.bold
20
+ logger.error exc.message.reset_ansi
21
21
 
22
22
  trace_args = ["-t", "--trace"]
23
23
  print_trace_msg = true
@@ -28,12 +28,12 @@ module Bridgetown
28
28
  exc.backtrace[0..4]
29
29
  end
30
30
  traces.each_with_index do |backtrace_line, index|
31
- Bridgetown.logger.error "#{index + 1}:", backtrace_line.reset_ansi
31
+ logger.error "#{index + 1}:", backtrace_line.reset_ansi
32
32
  end
33
33
 
34
34
  return unless print_trace_msg
35
35
 
36
- Bridgetown.logger.warn "Backtrace:", "Use the --trace option for complete information."
36
+ logger.warn "Backtrace:", "Use the --trace option for complete information."
37
37
  end
38
38
  end
39
39
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Filters
5
+ module TranslationFilters
6
+ def t(input)
7
+ I18n.t(input.to_s)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -7,9 +7,8 @@ module Bridgetown
7
7
 
8
8
  # Produces an absolute URL based on site.url and site.base_path.
9
9
  #
10
- # input - the URL to make absolute.
11
- #
12
- # Returns the absolute URL as a String.
10
+ # @param input [String] the URL to make absolute.
11
+ # @return [String] the absolute URL as a String.
13
12
  def absolute_url(input)
14
13
  cache = (@context.registers[:cached_absolute_urls] ||= {})
15
14
  cache[input] ||= compute_absolute_url(input)
@@ -18,19 +17,47 @@ module Bridgetown
18
17
  # Produces a URL relative to the domain root based on site.base_path
19
18
  # unless it is already an absolute url with an authority (host).
20
19
  #
21
- # input - the URL to make relative to the domain root
22
- #
23
- # Returns a URL relative to the domain root as a String.
20
+ # @param input [String] the URL to make relative to the domain root
21
+ # @return [String] a URL relative to the domain root as a String.
24
22
  def relative_url(input)
25
23
  cache = (@context.registers[:cached_relative_urls] ||= {})
26
24
  cache[input] ||= compute_relative_url(input)
27
25
  end
28
26
 
29
- # Strips trailing `/index.html` from URLs to create pretty permalinks
27
+ # For string input, adds a prefix of the current site locale to a relative
28
+ # URL, unless it's a default locale and prefix_current_locale config is
29
+ # false. For a resources array input, return a filtered resources array
30
+ # based on the locale.
30
31
  #
31
- # input - the URL with a possible `/index.html`
32
+ # @param input [String, Array] the relative URL, or an array of resources
33
+ # @param use_locale [String] another locale to use beside the current one
34
+ # (must be in site's `available_locales` config)
35
+ # @return [String, Array] the prefixed relative URL, or filtered resources
36
+ def in_locale(input, use_locale = nil)
37
+ site = @context.registers[:site]
38
+ use_locale ||= site.locale
39
+
40
+ # If we're given a collection, filter down and return
41
+ if input.is_a?(Array)
42
+ return input.select do |res|
43
+ res.data[:locale].to_sym == use_locale.to_sym
44
+ end
45
+ end
46
+
47
+ if !site.config.prefix_default_locale &&
48
+ use_locale.to_sym == site.config.default_locale
49
+ return input
50
+ end
51
+
52
+ return input unless site.config.available_locales.include?(use_locale.to_sym)
53
+
54
+ "#{use_locale}/#{input.to_s.delete_prefix("/")}"
55
+ end
56
+
57
+ # Strips trailing `/index.html` from URLs to create pretty permalinks
32
58
  #
33
- # Returns a URL with the trailing `/index.html` removed
59
+ # @param input [String] the URL with a possible `/index.html`
60
+ # @return [String] a URL with the trailing `/index.html` removed
34
61
  def strip_index(input)
35
62
  return if input.nil? || input.to_s.empty?
36
63
 
@@ -42,7 +69,7 @@ module Bridgetown
42
69
  # @param input [Object] value which responds to `to_s`
43
70
  # @return [String]
44
71
  def strip_extname(input)
45
- Pathname.new(input.to_s).yield_self do |path|
72
+ Pathname.new(input.to_s).then do |path|
46
73
  path.dirname + path.basename(".*")
47
74
  end.to_s
48
75
  end
@@ -435,3 +435,6 @@ end
435
435
  Liquid::Template.register_filter(
436
436
  Bridgetown::Filters
437
437
  )
438
+ Liquid::Template.register_filter(
439
+ Bridgetown::Filters::TranslationFilters
440
+ )
@@ -9,10 +9,12 @@ module Bridgetown
9
9
 
10
10
  def initialize(site)
11
11
  @site = site
12
+ @defaults_cache = {}
12
13
  end
13
14
 
14
15
  def reset
15
16
  @glob_cache = {}
17
+ @defaults_cache = {}
16
18
  end
17
19
 
18
20
  def ensure_time!(set)
@@ -29,16 +31,19 @@ module Bridgetown
29
31
  # Collects a hash with all default values for a resource
30
32
  #
31
33
  # @param path [String] the relative path of the resource
32
- # @param collection [Symbol] :posts, :pages, etc.
34
+ # @param collection_name [Symbol] :posts, :pages, etc.
33
35
  #
34
- # @returns [Hash] all default values (an empty hash if there are none)
35
- def all(path, collection)
36
- defaults = {}
36
+ # @return [Hash] all default values (an empty hash if there are none)
37
+ def all(path, collection_name)
38
+ if @defaults_cache.key?([path, collection_name])
39
+ return @defaults_cache[[path, collection_name]]
40
+ end
37
41
 
42
+ defaults = {}
38
43
  merge_data_cascade_for_path(path, defaults)
39
44
 
40
45
  old_scope = nil
41
- matching_sets(path, collection).each do |set|
46
+ matching_sets(path, collection_name).each do |set|
42
47
  if has_precedence?(old_scope, set["scope"])
43
48
  defaults = Utils.deep_merge_hashes(defaults, set["values"])
44
49
  old_scope = set["scope"]
@@ -46,7 +51,8 @@ module Bridgetown
46
51
  defaults = Utils.deep_merge_hashes(set["values"], defaults)
47
52
  end
48
53
  end
49
- defaults
54
+
55
+ @defaults_cache[[path, collection_name]] = defaults
50
56
  end
51
57
 
52
58
  private
@@ -123,7 +129,7 @@ module Bridgetown
123
129
  # @param scope [Hash] the defaults set being asked about
124
130
  # @param collection [Symbol] the collection of the resource being processed
125
131
  #
126
- # @returns [Boolean] whether either of the above conditions are satisfied
132
+ # @return [Boolean] whether either of the above conditions are satisfied
127
133
  def applies_collection?(scope, collection)
128
134
  !scope.key?("collection") || scope["collection"].eql?(collection.to_s)
129
135
  end
@@ -132,7 +138,7 @@ module Bridgetown
132
138
  #
133
139
  # @param set [Hash] the default value hash as defined in bridgetown.config.yml
134
140
  #
135
- # @returns [Boolean] if the set is valid and can be used
141
+ # @return [Boolean] if the set is valid and can be used
136
142
  def valid?(set)
137
143
  set.is_a?(Hash) && set["values"].is_a?(Hash)
138
144
  end
@@ -4,6 +4,7 @@ module Bridgetown
4
4
  class GeneratedPage
5
5
  include LayoutPlaceable
6
6
  include LiquidRenderable
7
+ include Localizable
7
8
  include Publishable
8
9
  include Transformable
9
10
 
@@ -0,0 +1,36 @@
1
+ # Frozen-string-literal: true
2
+
3
+ require "kramdown-parser-gfm"
4
+
5
+ module Kramdown
6
+ module Parser
7
+ class GFM
8
+ MARK_DELIMITER = %r{(==|::)+}.freeze
9
+ MARK_MATCH = %r{#{MARK_DELIMITER}(?!\s|=|:).*?[^\s=:]#{MARK_DELIMITER}}m.freeze
10
+
11
+ # Monkey-patch GFM initializer to add our new mark parser
12
+ alias_method :_old_initialize, :initialize
13
+ def initialize(source, options)
14
+ _old_initialize(source, options)
15
+ @span_parsers << :mark if @options[:mark_highlighting]
16
+ end
17
+
18
+ def parse_mark
19
+ line_number = @src.current_line_number
20
+
21
+ @src.pos += @src.matched_size
22
+ el = Element.new(:html_element, "mark", {}, category: :span, line: line_number)
23
+ @tree.children << el
24
+
25
+ env = save_env
26
+ reset_env(src: Kramdown::Utils::StringScanner.new(@src.matched[2..-3], line_number),
27
+ text_type: :text)
28
+ parse_spans(el)
29
+ restore_env(env)
30
+
31
+ el
32
+ end
33
+ define_parser(:mark, MARK_MATCH)
34
+ end
35
+ end
36
+ end
@@ -95,8 +95,7 @@ module Bridgetown
95
95
 
96
96
  # @return [Bridgetown::Resource::Base]
97
97
  def as_resource_in_collection
98
- collection.resources << to_resource.read!
99
- collection.resources.last
98
+ collection.add_resource_from_model(self)
100
99
  end
101
100
 
102
101
  # @return [Bridgetown::Resource::Base]
@@ -153,8 +152,8 @@ module Bridgetown
153
152
  return attributes[key]
154
153
  end
155
154
 
156
- Bridgetown.logger.warn "key `#{method_name}' not found in attributes for" \
157
- " #{attributes[:id].presence || "new #{self.class}"}"
155
+ Bridgetown.logger.warn "key `#{method_name}' not found in attributes for " \
156
+ "#{attributes[:id].presence || "new #{self.class}"}"
158
157
  nil
159
158
  end
160
159