bridgetownrb / bridgetown

A next-generation progressive site generator & fullstack framework, powered by Ruby
https://www.bridgetownrb.com
MIT License
1.16k stars 112 forks source link

feat: Localised urls/slugs for static pages #605

Open lux-shaun opened 2 years ago

lux-shaun commented 2 years ago

Summary

Currently, paths for html pages are defined by the filename, or overwritten by frontmatter. With I18n, it would be quite useful to be able to localise this. This is partly SEO and partly general user friendly urls for non-English speakers.

Motivation

Additional flexibility in I18n routing.

Reference-level explanation

This is a feature that is supported in middleman: https://middlemanapp.com/advanced/localization/#localizing-paths

Essentially, you can use I18n keys to alter the slug on a per-locale basis. E.g. /en/hello maps to /es/hola

I'm not sure how best to implement this in the core, but I was able to write a small plugin that demonstrates the functionality. This has a couple issues, such as not interacting with the existing I18n route logic, and not always reloading right in development mode, but it works well enough.

class Builders::I18nSlug < SiteBuilder
  def build
    generator do
      # raise site.collections.pages.resources.inspect
      site.collections.pages.resources.each do |resource|
        path = translated_path(resource)
        resource.data['permalink'] = "#{locale_prefix(resource)}/#{path}.html" if path
      end
    end
  end

  private

  def translated_path(resource)
    key = resource.data.slug_key
    I18n.with_locale(resource.data.locale) { I18n.t(key, scope: 'paths', default: nil) }
  end

  def locale_prefix(resource)
    prefix = ''
    if resource.data.locale != config.default_locale || config.prefix_default_locale
      prefix << "/#{resource.data.locale}"
    end
    prefix
  end
end
jaredcwhite commented 2 years ago

@robodinoshaun I agree this would be a good feature to have. Currently you'd have to manually add the permalink in front matter locale overrides for each language. Doing something more automated would be ideal.