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