bridgetown-core 1.0.0 → 1.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -1
  3. data/lib/bridgetown-core/collection.rb +37 -20
  4. data/lib/bridgetown-core/commands/concerns/actions.rb +3 -2
  5. data/lib/bridgetown-core/commands/configure.rb +1 -1
  6. data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +95 -12
  7. data/lib/bridgetown-core/commands/new.rb +10 -9
  8. data/lib/bridgetown-core/commands/plugins.rb +2 -0
  9. data/lib/bridgetown-core/commands/start.rb +3 -0
  10. data/lib/bridgetown-core/commands/webpack/update.rb +2 -2
  11. data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +11 -2
  12. data/lib/bridgetown-core/component.rb +13 -7
  13. data/lib/bridgetown-core/concerns/localizable.rb +20 -0
  14. data/lib/bridgetown-core/concerns/prioritizable.rb +44 -0
  15. data/lib/bridgetown-core/concerns/publishable.rb +11 -1
  16. data/lib/bridgetown-core/concerns/site/configurable.rb +2 -10
  17. data/lib/bridgetown-core/concerns/site/localizable.rb +5 -1
  18. data/lib/bridgetown-core/concerns/site/ssr.rb +3 -3
  19. data/lib/bridgetown-core/concerns/site/writable.rb +28 -0
  20. data/lib/bridgetown-core/configuration.rb +2 -0
  21. data/lib/bridgetown-core/configurations/bt-postcss/postcss.config.js +5 -3
  22. data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -1
  23. data/lib/bridgetown-core/configurations/lit/esbuild-plugins.js +21 -0
  24. data/lib/bridgetown-core/configurations/lit/happy-days.lit.js +26 -0
  25. data/lib/bridgetown-core/configurations/lit/lit-components-entry.js +1 -0
  26. data/lib/bridgetown-core/configurations/lit/lit-ssr.config.js +6 -0
  27. data/lib/bridgetown-core/configurations/lit.rb +95 -0
  28. data/lib/bridgetown-core/configurations/open-props/variables.css.erb +11 -0
  29. data/lib/bridgetown-core/configurations/open-props.rb +21 -0
  30. data/lib/bridgetown-core/configurations/ruby2js/hello_world.js.rb +9 -0
  31. data/lib/bridgetown-core/configurations/ruby2js.rb +67 -0
  32. data/lib/bridgetown-core/configurations/shoelace.rb +50 -0
  33. data/lib/bridgetown-core/configurations/tailwindcss.rb +16 -2
  34. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  35. data/lib/bridgetown-core/drops/generated_page_drop.rb +2 -1
  36. data/lib/bridgetown-core/drops/resource_drop.rb +2 -1
  37. data/lib/bridgetown-core/errors.rb +5 -5
  38. data/lib/bridgetown-core/filters/translation_filters.rb +11 -0
  39. data/lib/bridgetown-core/filters/url_filters.rb +37 -10
  40. data/lib/bridgetown-core/filters.rb +3 -0
  41. data/lib/bridgetown-core/frontmatter_defaults.rb +14 -8
  42. data/lib/bridgetown-core/generated_page.rb +1 -0
  43. data/lib/bridgetown-core/kramdown/parser/gfm.rb +36 -0
  44. data/lib/bridgetown-core/model/base.rb +1 -2
  45. data/lib/bridgetown-core/plugin.rb +6 -37
  46. data/lib/bridgetown-core/plugin_manager.rb +3 -2
  47. data/lib/bridgetown-core/rack/boot.rb +5 -0
  48. data/lib/bridgetown-core/rack/logger.rb +14 -4
  49. data/lib/bridgetown-core/rack/roda.rb +102 -8
  50. data/lib/bridgetown-core/rack/routes.rb +67 -2
  51. data/lib/bridgetown-core/resource/base.rb +4 -6
  52. data/lib/bridgetown-core/resource/destination.rb +18 -0
  53. data/lib/bridgetown-core/resource/permalink_processor.rb +6 -4
  54. data/lib/bridgetown-core/resource/relations.rb +1 -1
  55. data/lib/bridgetown-core/utils/aux.rb +2 -1
  56. data/lib/bridgetown-core/utils/require_gems.rb +3 -6
  57. data/lib/bridgetown-core/utils.rb +24 -11
  58. data/lib/bridgetown-core/version.rb +2 -2
  59. data/lib/bridgetown-core/watcher.rb +19 -6
  60. data/lib/bridgetown-core.rb +8 -2
  61. data/lib/site_template/README.md +2 -2
  62. data/lib/site_template/bridgetown.config.yml +3 -0
  63. data/lib/site_template/frontend/javascript/index.js.erb +1 -0
  64. data/lib/site_template/frontend/styles/syntax-highlighting.css +77 -0
  65. data/lib/site_template/package.json.erb +18 -17
  66. data/lib/site_template/server/roda_app.rb +3 -6
  67. data/lib/site_template/src/404.html +2 -1
  68. data/lib/site_template/src/500.html +10 -0
  69. metadata +20 -5
  70. data/lib/bridgetown-core/publisher.rb +0 -29
@@ -32,7 +32,7 @@ class Bridgetown::Site
32
32
  @ssr_enabled = true
33
33
  end
34
34
 
35
- def ssr_setup
35
+ def ssr_setup(&block)
36
36
  config.serving = true
37
37
  Bridgetown::Hooks.trigger :site, :pre_read, self
38
38
  defaults_reader.tap do |d|
@@ -46,10 +46,10 @@ class Bridgetown::Site
46
46
  end
47
47
  Bridgetown::Hooks.trigger :site, :post_read, self
48
48
 
49
- yield self if block_given? # provide additional setup hook
49
+ block&.call(self) # provide additional setup hook
50
50
  return if Bridgetown.env.production?
51
51
 
52
- Bridgetown::Watcher.watch(self, config)
52
+ Bridgetown::Watcher.watch(self, config, &block)
53
53
  end
54
54
 
55
55
  def disable_ssr
@@ -14,6 +14,8 @@ class Bridgetown::Site
14
14
  # @return [void]
15
15
  def write
16
16
  each_site_file { |item| item.write(dest) }
17
+ write_redirecting_index if config.prefix_default_locale
18
+
17
19
  Bridgetown::Hooks.trigger :site, :post_write, self
18
20
  end
19
21
 
@@ -40,5 +42,31 @@ class Bridgetown::Site
40
42
  }
41
43
  end
42
44
  end
45
+
46
+ def write_redirecting_index
47
+ resource = resources.find do |item|
48
+ item.data.slug == "index" && item.data.locale == config.default_locale
49
+ end
50
+
51
+ unless resource
52
+ Bridgetown.logger.warn(
53
+ "Index file not found in the source folder, cannot generate top-level redirect file"
54
+ )
55
+ return
56
+ end
57
+
58
+ index_html = <<~HTML
59
+ <!DOCTYPE html>
60
+ <html>
61
+ <head>
62
+ <title>Redirecting…</title>
63
+ <meta http-equiv="refresh" content="0; url=#{resource.relative_url}" />
64
+ </head>
65
+ <body></body>
66
+ </html>
67
+ HTML
68
+
69
+ File.write(in_dest_dir("index.html"), index_html, mode: "wb")
70
+ end
43
71
  end
44
72
  end
@@ -59,6 +59,7 @@ module Bridgetown
59
59
  # Output Configuration
60
60
  "available_locales" => [:en],
61
61
  "default_locale" => :en,
62
+ "prefix_default_locale" => false,
62
63
  "permalink" => nil, # default is set according to content engine
63
64
  "timezone" => nil, # use the local timezone
64
65
 
@@ -83,6 +84,7 @@ module Bridgetown
83
84
  "footnote_nr" => 1,
84
85
  "show_warnings" => false,
85
86
  "include_extraction_tags" => false,
87
+ "mark_highlighting" => true,
86
88
  },
87
89
  }.each_with_object(Configuration.new) { |(k, v), hsh| hsh[k] = v.freeze }.freeze
88
90
 
@@ -1,8 +1,10 @@
1
1
  module.exports = {
2
2
  plugins: {
3
- 'postcss-easy-import': {},
4
3
  'postcss-mixins': {},
5
- 'postcss-color-function': {},
4
+ 'postcss-color-mod-function': {
5
+ // Uncomment the following to import CSS variables for use in `color-mod`:
6
+ // importFrom: "frontend/styles/variables.css"
7
+ },
6
8
  'postcss-flexbugs-fixes': {},
7
9
  'postcss-preset-env': {
8
10
  autoprefixer: {
@@ -14,7 +16,7 @@ module.exports = {
14
16
  'custom-media-queries': true
15
17
  },
16
18
  },
17
- 'cssnano' : {
19
+ 'cssnano': {
18
20
  preset: 'default'
19
21
  }
20
22
  }
@@ -14,7 +14,7 @@ end
14
14
  confirm = ask "This configuration will ovewrite your existing #{"postcss.config.js".bold.white}. Would you like to continue? [Yn]"
15
15
  return unless confirm.casecmp?("Y")
16
16
 
17
- plugins = %w(postcss-easy-import postcss-mixins postcss-color-function cssnano)
17
+ plugins = %w(postcss-mixins postcss-color-mod-function cssnano)
18
18
 
19
19
  say "Adding the following PostCSS plugins: #{plugins.join(' | ')}", :green
20
20
  run "yarn add -D #{plugins.join(' ')}"
@@ -0,0 +1,21 @@
1
+ // You can add "full-stack" esbuild plugins here that you wish to share between
2
+ // the frontend bundles and Lit SSR. Just import your plugins and add them and
3
+ // any additional configuration to the `plugins` array below.
4
+
5
+ // This plugin will let you import `.lit.css` files as sidecar stylesheets.
6
+ // Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
7
+ const { litCssPlugin } = require("esbuild-plugin-lit-css")
8
+ const postCssConfig = require("postcss-load-config").sync()
9
+ const postCssProcessor = require("postcss")([...postCssConfig.plugins])
10
+
11
+ module.exports = {
12
+ plugins: [
13
+ litCssPlugin({
14
+ filter: /\.lit\.css$/,
15
+ transform: async (css, { filePath }) => {
16
+ const results = await postCssProcessor.process(css, { ...postCssConfig.options, from: filePath })
17
+ return results.css
18
+ }
19
+ }),
20
+ ]
21
+ }
@@ -0,0 +1,26 @@
1
+ import { LitElement, html, css } from "lit"
2
+
3
+ export class HappyDaysElement extends LitElement {
4
+ static styles = css`
5
+ :host {
6
+ display: block;
7
+ border: 2px dashed gray;
8
+ padding: 20px;
9
+ max-width: 300px;
10
+ }
11
+ `
12
+
13
+ static properties = {
14
+ hello: { type: String }
15
+ }
16
+
17
+ render() {
18
+ return html`
19
+ <p>Hello ${this.hello}! ${Date.now()}</p>
20
+ `;
21
+ }
22
+ }
23
+
24
+ // Try adding `<%= lit :happy_days, hello: "there" %>` somewhere in an ERB template
25
+ // on your site to see this example Lit component in action!
26
+ customElements.define("happy-days", HappyDaysElement)
@@ -0,0 +1 @@
1
+ import components from "bridgetownComponents/**/*.{lit.js,lit.js.rb}"
@@ -0,0 +1,6 @@
1
+ const build = require("bridgetown-lit-renderer/build")
2
+ const { plugins } = require("./esbuild-plugins.js")
3
+
4
+ const esbuildOptions = { plugins }
5
+
6
+ build(esbuildOptions)
@@ -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} */"
@@ -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)
@@ -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
+ )