Module: Jekyll::L10n::UrlFilter

Defined in:
lib/jekyll-l10n/jekyll/url_filter.rb

Overview

URL Filter - Liquid filters for locale-aware URL generation

Provides Liquid filters for use in Jekyll templates to generate locale-prefixed URLs. These filters are automatically registered with Liquid during plugin initialization.

This module is designed to be included in Liquid::Template's filter registry, making the filters available in all Jekyll templates.

Key responsibilities:

  • Generate locale-prefixed URLs in BCP 47 hyphenated form
  • Switch between locale variants of the same page
  • Build structured locale-switcher menu data
  • Validate locales against site configuration (with form normalization)
  • Handle edge cases (external URLs, anchors, protocols)

Examples:

Usage in Jekyll Liquid templates

<!-- Add locale prefix to URL -->
<a href="{{ '/about/' | locale_url: 'es_ES' }}">Acerca de</a>
<!-- Produces: /es-ES/about/ -->

<!-- Switch to different locale variant -->
<a href="{{ page.url | switch_locale_url: 'fr' }}">Français</a>

<!-- Build a language-switcher menu -->
{% assign menu = page.url | locale_menu %}

See Also:

Instance Method Summary collapse

Instance Method Details

#locale_menu(url) ⇒ Array<Hash>

Build the full locale-switcher menu for the current page.

Returns one entry per locale available to the current page (via the existing #configured_locales resolution — site-wide with_locales_data.locales config, or a page-level front-matter override — always including English even if not explicitly configured). Each entry carries everything a theme needs to render a menu item with zero locale-specific logic of its own: a display name, a switch-target URL, and whether it's the page's current locale.

Examples:

{{ page.url | locale_menu }}
# => [{"code"=>"en","name"=>"English","url"=>"/about/","current"=>false},
#     {"code"=>"es_ES","name"=>"Spanish (Spain)","url"=>"/es-ES/about/","current"=>true}]

Parameters:

  • url (String)

    The current page's URL (e.g. page.url)

Returns:

  • (Array<Hash>)

    Array of { 'code', 'name', 'url', 'current' } hashes, one per locale. code is the canonical underscore form (e.g. "es_ES"), name is the ISO-resolved display name (e.g. "Spanish (Spain)"), url is what #switch_locale_url produces for that locale, and current is true only for the locale matching the page's own locale.



120
121
122
123
124
125
126
127
128
129
# File 'lib/jekyll-l10n/jekyll/url_filter.rb', line 120

def locale_menu(url)
  menu_locales.map do |locale|
    {
      'code' => locale,
      'name' => LocaleNameResolver.resolve(locale),
      'url' => switch_locale_url(url, locale),
      'current' => locale == (current_locale || 'en')
    }
  end
end

#locale_url(url, locale = nil) ⇒ String

Generate a locale-prefixed URL for the given URL and locale

Adds a locale prefix in BCP 47 hyphenated form to the given URL. For example, '/about/' becomes '/es-ES/about/' for locale 'es_ES'. The filter handles various edge cases and only applies the prefix when appropriate.

The method performs several checks to determine if prefixing is appropriate:

  • Invalid locale codes (nil, empty, or 'en') are skipped
  • URLs already localized are not prefixed again
  • External URLs, anchors, and relative paths are not modified

Examples:

<!-- Explicit underscore locale converted to hyphen in URL -->
{{ '/about/' | locale_url: 'es_ES' }}  # => '/es-ES/about/'

<!-- Current page's locale -->
{{ '/about/' | locale_url }}  # => '/es/about/' (if page locale is 'es')

Parameters:

  • url (String)

    The URL to prefix (e.g., '/about/', '/path/to/page/')

  • locale (String, nil) (defaults to: nil)

    The locale code (e.g., 'es_ES', 'pt_BR'). Defaults to nil (uses current page's locale). If nil, uses page's locale from context.

Returns:

  • (String)

    The locale-prefixed URL in BCP 47 form, or original URL if prefixing is not appropriate



62
63
64
65
66
67
68
# File 'lib/jekyll-l10n/jekyll/url_filter.rb', line 62

def locale_url(url, locale = nil)
  locale ||= current_locale
  return url if should_skip?(url, locale)

  url_segment = LocaleUrlFormatter.to_url_segment(locale)
  "/#{url_segment}#{url}"
end

#switch_locale_url(url, target_locale) ⇒ String

Generate a URL for the given locale variant of the current page

Switches the current URL to a different locale variant. For example, if the current page is '/es-ES/about/', calling this with 'fr' returns '/fr/about/'. This is useful for building language switcher menus.

This filter first extracts the base URL (without locale prefix) from the given URL, then applies the target locale using the standard locale_url logic.

Examples:

<!-- Current page is /es-ES/about/, switch to French -->
{{ page.url | switch_locale_url: 'fr' }}  # => '/fr/about/'

<!-- Build a language switcher -->
<a href="{{ page.url | switch_locale_url: 'es_ES' }}">Español (España)</a>
<a href="{{ page.url | switch_locale_url: 'fr' }}">Français</a>

Parameters:

  • url (String)

    The current URL (may or may not have a locale prefix)

  • target_locale (String)

    The target locale code (e.g., 'es_ES', 'fr', 'pt_BR')

Returns:

  • (String)

    The URL for the target locale, or original URL if locale is invalid



89
90
91
92
93
94
95
96
97
98
# File 'lib/jekyll-l10n/jekyll/url_filter.rb', line 89

def switch_locale_url(url, target_locale)
  # Validate target locale is configured
  return url unless valid_target_locale?(target_locale)

  # Get base URL without locale prefix
  base_url_value = base_url(url)

  # Apply target locale using existing locale_url logic
  locale_url(base_url_value, target_locale)
end