Skip to content

Commit

Permalink
Default locale prefixing config option, in_locale template filter/h…
Browse files Browse the repository at this point in the history
…elper (bridgetownrb#540)

* Allow finding and linking to alternate locale pages

* Rename to all_locales

* Allow ability to prefix URLs for even the default locale

* Add `in_locale` filter/helper, fix pagination output folders with base paths

* fix spacing

* add warning when index not found
  • Loading branch information
jaredcwhite authored May 16, 2022
1 parent 1909ec7 commit 03ab947
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 11 deletions.
28 changes: 28 additions & 0 deletions bridgetown-core/lib/bridgetown-core/concerns/site/writable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def cleanup
# @return [void]
def write
each_site_file { |item| item.write(dest) }
write_redirecting_index if config.prefix_default_locale

Bridgetown::Hooks.trigger :site, :post_write, self
end

Expand All @@ -40,5 +42,31 @@ def resources_cache_manifest
}
end
end

def write_redirecting_index
resource = resources.find do |item|
item.data.slug == "index" && item.data.locale == config.default_locale
end

unless resource
Bridgetown.logger.warn(
"Index file not found in the source folder, cannot generate top-level redirect file"
)
return
end

index_html = <<~HTML
<!DOCTYPE html>
<html>
<head>
<title>Redirecting…</title>
<meta http-equiv="refresh" content="0; url=#{resource.relative_url}" />
</head>
<body></body>
</html>
HTML

File.write(in_dest_dir("index.html"), index_html, mode: "wb")
end
end
end
1 change: 1 addition & 0 deletions bridgetown-core/lib/bridgetown-core/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class Configuration < HashWithDotAccess::Hash
# Output Configuration
"available_locales" => [:en],
"default_locale" => :en,
"prefix_default_locale" => false,
"permalink" => nil, # default is set according to content engine
"timezone" => nil, # use the local timezone

Expand Down
36 changes: 27 additions & 9 deletions bridgetown-core/lib/bridgetown-core/filters/url_filters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ module URLFilters

# Produces an absolute URL based on site.url and site.base_path.
#
# input - the URL to make absolute.
#
# Returns the absolute URL as a String.
# @param input [String] the URL to make absolute.
# @return [String] the absolute URL as a String.
def absolute_url(input)
cache = (@context.registers[:cached_absolute_urls] ||= {})
cache[input] ||= compute_absolute_url(input)
Expand All @@ -18,19 +17,38 @@ def absolute_url(input)
# Produces a URL relative to the domain root based on site.base_path
# unless it is already an absolute url with an authority (host).
#
# input - the URL to make relative to the domain root
#
# Returns a URL relative to the domain root as a String.
# @param input [String] the URL to make relative to the domain root
# @return [String] a URL relative to the domain root as a String.
def relative_url(input)
cache = (@context.registers[:cached_relative_urls] ||= {})
cache[input] ||= compute_relative_url(input)
end

# Strips trailing `/index.html` from URLs to create pretty permalinks
# Adds a prefix of the current site locale to a relative URL, unless it's
# a default locale and prefix_current_locale config is false.
#
# input - the URL with a possible `/index.html`
# @param input [String] the relative URL
# @param use_locale [String] another locale to use beside the current one (must if in site's
# available_configs)
# @return [String] the prefixed relative URL
def in_locale(input, use_locale = nil)
site = @context.registers[:site]
use_locale ||= site.locale

if !site.config.prefix_default_locale &&
use_locale&.to_sym == site.config.default_locale
return input
end

return input unless site.config.available_locales.include?(use_locale.to_sym)

"#{use_locale}/#{input.to_s.delete_prefix("/")}"
end

# Strips trailing `/index.html` from URLs to create pretty permalinks
#
# Returns a URL with the trailing `/index.html` removed
# @param input [String] the URL with a possible `/index.html`
# @return [String] a URL with the trailing `/index.html` removed
def strip_index(input)
return if input.nil? || input.to_s.empty?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ def ensure_base_path(permalink)

# @param resource [Bridgetown::Resource::Base]
register_placeholder :locale, ->(resource) do
next nil if resource.data.locale&.to_sym == resource.site.config.default_locale
if !resource.site.config.prefix_default_locale &&
resource.data.locale&.to_sym == resource.site.config.default_locale
next nil
end

locale_data = resource.data.locale&.to_sym
resource.site.config.available_locales.include?(locale_data) ? locale_data.to_s : nil
Expand Down
32 changes: 32 additions & 0 deletions bridgetown-core/test/test_locales.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,36 @@ class TestLocales < BridgetownUnitTest
HTML
end
end

context "locales, prefix_default_locale, and base_path combined" do
setup do
@site = resources_site(base_path: "/basefolder", prefix_default_locale: true)
@site.process
# @type [Bridgetown::Resource::Base]
@resources = @site.collections.pages.resources.select do |page|
page.relative_path.to_s == "_pages/multi-page.md"
end
@english_resource = @resources.find { |page| page.data.locale == :en }
@french_resource = @resources.find { |page| page.data.locale == :fr }
end

should "have the correct permalink and locale in English" do
assert_equal "/basefolder/en/multi-page/", @english_resource.relative_url
assert_includes @english_resource.output, 'lang="en"'
assert_includes @english_resource.output, "<title>Multi-locale page</title>"
assert_includes @english_resource.output, "<p>English: Multi-locale page</p>"
end

should "have the correct permalink and locale in French" do
assert_equal "/basefolder/fr/multi-page/", @french_resource.relative_url
assert_includes @french_resource.output, 'lang="fr"'
assert_includes @french_resource.output, "<title>Sur mesure</title>"
assert_includes @french_resource.output, "<p>French: Sur mesure</p>"

assert_includes @french_resource.output, <<-HTML
<li>Multi-locale page: /basefolder/en/multi-page/</li>
<li>Sur mesure: /basefolder/fr/multi-page/</li>
HTML
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def self.index_documents_by(all_documents, index_key) # rubocop:todo Metrics/Abc
document_data = document.data[index_key]
document_data = document_data.split(%r!;|,!) if document_data.is_a?(String)

document_data.each do |key|
Array(document_data).each do |key|
key = key.to_s.downcase.strip
# If the key is a delimetered list of values
# (meaning the user didn't use an array but a string with commas)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ def set_url(url_value)
@url = url_value
end
# rubocop:enable Naming/AccessorMethodName

def destination(dest)
path = site.in_dest_dir(
dest, URL.unescape_path(url).delete_prefix(site.base_path(strip_slash_only: true))
)
path = File.join(path, "index") if url.end_with?("/")
path << output_ext unless path.end_with? output_ext
path
end
end
end
end

0 comments on commit 03ab947

Please sign in to comment.