diff --git a/_config.yml b/_config.yml
index e0e054caf..8bd472c94 100644
--- a/_config.yml
+++ b/_config.yml
@@ -73,17 +73,14 @@ defaults:
path: 'content/_en'
values:
lang: en
- base_path: ''
- scope:
path: 'content/_es'
values:
lang: es
- base_path: /es
- scope:
path: 'content/_fr'
values:
lang: fr
- base_path: /fr
include:
# dotfiles are excluded by default
diff --git a/_includes/language_picker.html b/_includes/language_picker.html
index d1c410301..029e2d5a3 100644
--- a/_includes/language_picker.html
+++ b/_includes/language_picker.html
@@ -24,26 +24,7 @@
>
{% for locale in site.languages %}
- {% if page.lang == 'en' %}
- {% if locale == 'en' %}
- {% assign locale_url = page.url %}
- {% elsif locale == page.lang %}
- {% assign locale_url = page.url %}
- {% else %}
- {% assign locale_url = page.url | prepend: locale | prepend: '/' %}
- {% endif %}
- {% else %}
- {% if locale == 'en' and page.lang == 'es' %}
- {% assign locale_url = page.url | remove_first: 'es/' %}
- {% elsif locale == 'en' and page.lang == 'fr' %}
- {% assign locale_url = page.url | remove_first: 'fr/' %}
- {% elsif locale == page.lang %}
- {% assign locale_url = page.url %}
- {% else %}
- {% assign locale_url = page.url | replace_first: page.lang, locale %}
- {% endif %}
- {% endif %}
-
+
{{ site.data.[locale].settings.global.locales[locale] }}
diff --git a/_plugins/locale_url_filter.rb b/_plugins/locale_url_filter.rb
index 0b4f587e6..54c0edbfd 100644
--- a/_plugins/locale_url_filter.rb
+++ b/_plugins/locale_url_filter.rb
@@ -2,14 +2,23 @@ module Jekyll
module LocaleUrlFilter
LOCALE_STRING_CONSTANT = '__LOCALE_BASE_URL__'.freeze
- def locale_url(path = '')
+ def locale_url(path = '', locale = nil)
site_base_url = @context.registers[:site].baseurl
- locale_prefix = @context.registers[:page]['base_path']
- site_base_url.to_s + locale_prefix.to_s + path
+ locale ||= @context.registers[:page]['lang']
+ permalink = @context.registers[:site].collections[locale].metadata['permalink']
+ site_base_url.to_s + Jekyll::URL.new(
+ template: permalink,
+ placeholders: { collection: locale, path: path },
+ ).to_s
+ end
+
+ def delocalize_url(path, locale = nil)
+ locale ||= @context.registers[:page]['lang']
+ path.gsub(%r{^/#{locale}/}, '/')
end
def replace_locale_base_url(input)
- input.gsub LOCALE_STRING_CONSTANT, locale_url
+ input.gsub(LOCALE_STRING_CONSTANT, locale_url.chomp('/'))
end
end
end
diff --git a/spec/_plugins/locale_url_filter_spec.rb b/spec/_plugins/locale_url_filter_spec.rb
new file mode 100644
index 000000000..2a50da505
--- /dev/null
+++ b/spec/_plugins/locale_url_filter_spec.rb
@@ -0,0 +1,278 @@
+require 'jekyll'
+require './_plugins/locale_url_filter'
+
+class JekyllFilter
+ include Jekyll::LocaleUrlFilter
+
+ def initialize(config, page_data)
+ @site = Jekyll::Site.new(Jekyll::Configuration.from(config))
+ page = Jekyll::Page.new(@site, @site.source, '', 'README.md')
+ page.data.merge!(page_data)
+ @context = Liquid::Context.new(@site.site_payload, {}, site: @site, page: page)
+ end
+end
+
+RSpec.describe Jekyll::LocaleUrlFilter do
+ let(:config) { {} }
+ let(:page_data) { { 'lang' => 'en' } }
+ let(:instance) { JekyllFilter.new(config, page_data) }
+
+ describe '#locale_url' do
+ let(:path) { '' }
+ let(:locale) { nil }
+ subject(:locale_url) { instance.locale_url(path, locale) }
+
+ context 'without site base url' do
+ let(:config) do
+ {
+ 'collections' => {
+ 'en' => { 'permalink' => '/:path/' },
+ 'es' => { 'permalink' => '/:path/' },
+ },
+ }
+ end
+
+ context 'without path' do
+ context 'without locale' do
+ it 'renders without locale' do
+ expect(locale_url).to eq('/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'renders without locale' do
+ expect(locale_url).to eq('/')
+ end
+ end
+ end
+
+ context 'with path' do
+ let(:path) { '/path/' }
+
+ context 'without locale' do
+ it 'renders without locale' do
+ expect(locale_url).to eq('/path/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'renders without locale' do
+ expect(locale_url).to eq('/path/')
+ end
+ end
+ end
+ end
+
+ context 'with collection in permalink' do
+ let(:config) do
+ {
+ 'collections' => {
+ 'en' => { 'permalink' => '/:collection/:path/' },
+ 'es' => { 'permalink' => '/:collection/:path/' },
+ },
+ }
+ end
+
+ context 'without path' do
+ context 'without locale' do
+ it 'renders with locale from page data' do
+ expect(locale_url).to eq('/en/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'renders with locale' do
+ expect(locale_url).to eq('/es/')
+ end
+ end
+ end
+
+ context 'with path' do
+ let(:path) { '/path/' }
+
+ context 'without locale' do
+ it 'renders without locale' do
+ expect(locale_url).to eq('/en/path/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'renders without locale' do
+ expect(locale_url).to eq('/es/path/')
+ end
+ end
+ end
+ end
+
+ context 'with site base url' do
+ context 'without collection in permalink' do
+ let(:config) do
+ {
+ 'baseurl' => 'https://example.com',
+ 'collections' => {
+ 'en' => { 'permalink' => '/:path/' },
+ 'es' => { 'permalink' => '/:path/' },
+ },
+ }
+ end
+
+ context 'without path' do
+ context 'without locale' do
+ it 'renders without locale' do
+ expect(locale_url).to eq('https://example.com/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'renders without locale' do
+ expect(locale_url).to eq('https://example.com/')
+ end
+ end
+ end
+
+ context 'with path' do
+ let(:path) { '/path/' }
+
+ context 'without locale' do
+ it 'renders without locale' do
+ expect(locale_url).to eq('https://example.com/path/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'renders without locale' do
+ expect(locale_url).to eq('https://example.com/path/')
+ end
+ end
+ end
+ end
+
+ context 'with collection in permalink' do
+ let(:config) do
+ {
+ 'baseurl' => 'https://example.com',
+ 'collections' => {
+ 'en' => { 'permalink' => '/:collection/:path/' },
+ 'es' => { 'permalink' => '/:collection/:path/' },
+ },
+ }
+ end
+
+ context 'without path' do
+ context 'without locale' do
+ it 'renders with locale from page data' do
+ expect(locale_url).to eq('https://example.com/en/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'renders with locale' do
+ expect(locale_url).to eq('https://example.com/es/')
+ end
+ end
+ end
+
+ context 'with path' do
+ let(:path) { '/path/' }
+
+ context 'without locale' do
+ it 'renders without locale' do
+ expect(locale_url).to eq('https://example.com/en/path/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'renders without locale' do
+ expect(locale_url).to eq('https://example.com/es/path/')
+ end
+ end
+ end
+ end
+ end
+ end
+
+ describe '#delocalize_url' do
+ let(:path) { '' }
+ let(:locale) { nil }
+ let(:page_data) { { 'lang' => 'es' } }
+ subject(:delocalized_url) { instance.delocalize_url(path, locale) }
+
+ context 'path not including locale' do
+ let(:path) { '/fr/example/' }
+
+ context 'without locale' do
+ it 'uses page data and does not modify path' do
+ expect(delocalized_url).to eq(path)
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'does not modify path' do
+ expect(delocalized_url).to eq(path)
+ end
+ end
+ end
+
+ context 'path including locale' do
+ let(:path) { '/es/example/' }
+
+ context 'without locale' do
+ it 'uses page data and delocalizes url' do
+ expect(delocalized_url).to eq('/example/')
+ end
+ end
+
+ context 'with locale' do
+ let(:locale) { 'es' }
+
+ it 'delocalizes url' do
+ expect(delocalized_url).to eq('/example/')
+ end
+ end
+ end
+ end
+
+ describe '#replace_locale_base_url' do
+ let(:input) { "#{Jekyll::LocaleUrlFilter::LOCALE_STRING_CONSTANT}/help/" }
+ subject(:locale_url) { instance.replace_locale_base_url(input) }
+
+ context 'without site base url' do
+ let(:config) { { 'collections' => { 'en' => { 'permalink' => '/:path/' } } } }
+
+ it 'replaces using page data' do
+ expect(locale_url).to eq('/help/')
+ end
+ end
+
+ context 'with site base url' do
+ let(:config) do
+ {
+ 'baseurl' => 'https://example.com',
+ 'collections' => { 'en' => { 'permalink' => '/:path/' } },
+ }
+ end
+
+ it 'replaces using page data' do
+ expect(locale_url).to eq('https://example.com/help/')
+ end
+ end
+ end
+end