# frozen_string_literal: true module Jekyll # Jekyll multilingual support # # * Posts are put under _LANGUAGE/ directories # * The first language on the config is default # * Translation strings are store in _data/LANGUAGE.yml # * The plugin generates a copy of the site for every language at # _site/LANGUAGE class Site attr_reader :locale # We don't monkey patch because the Site is already instantiated alias process_single process # Process the site once per available locale def process locales.each do |locale| @locale = locale Jekyll.logger.info 'Generating locale:', locale locale_config Jekyll.logger.info 'Destination:', config['destination'] Jekyll.logger.info 'Base URL:', config['baseurl'] symlink process_single # The default locale is placed at the root of the # site and everything else is under a subdirectory, but we symlink # root to default_locale for compatibility self_symlink if default_locale? && !redirect? end # XXX: Default is expected by Sutty so we always create it default_delete default_symlink # If we enable the redirector, the root of the site will consist # of an index.html that allows visitors to select their locale. copy_redirector if redirect? end def locales? locales.length > 1 end # Get locales from configuration def locales @locales ||= config.fetch('locales', []) end def default_locale @default_locale ||= locales.first end def default_locale? default_locale == locale end private # Redefine #render_docs so it doesn't render the locale collections # for each independent locale. # # XXX: Jekyll should render on demand instead of rendering and # writing separately. def render_docs(payload) collections.each do |name, collection| next if locales.include? name collection.docs.each do |document| render_regenerated(document, payload) end end end def locale_config # XXX: Retrocompatibility config['locale'] = config['lang'] = locale config['default_locale'] = default_locale # Don't touch the config unless there's more than one locale or we # aren't using a redirector return unless locales? other_locales_as_collections return if default_locale? && !redirect? @dest = config['destination'] = locale_destination config['baseurl'] = locale_baseurl end # Read the other locales as collections but don't render them, only # make them available to templates. # # The URL will be the permalink with the language prepended. # # {https://rubygems.org/gems/jekyll-linked-posts} def other_locales_as_collections locales.each do |l| next if l == locale config['collections'][l] = { 'output' => false, 'permalink' => [nil, l, config['permalink']].join('/') } end end # Cache original destination def root_destination @root_destination ||= config['destination'] end def orig_baseurl @orig_baseurl ||= config.dig('baseurl') || '' end # Add locale to the site destination def locale_destination File.join(root_destination, locale) end # If the site has a baseurl, we add the locale to it. But we add # it anyway so relative URLs include the locale def locale_baseurl [orig_baseurl, locale].join('/') end # Creates a symlink to the _posts/ directory so Jekyll believes # it's processing a single site. def symlink FileUtils.rm_f('_posts') FileUtils.ln_s("_#{locale}", '_posts') end def redirect? config.fetch('redirect', false) end # TODO: Make configurable def redirector @redirector ||= File.join(locale_destination, 'redirector.html') end def redirector_to_index(redir) File.join(root_destination, File.basename(redir .sub('redirector', 'index'))) end def copy_redirector return unless File.exist? redirector Dir.glob("#{redirector}*").each do |redir| FileUtils.cp(redir, redirector_to_index(redir)) end end def default_delete FileUtils.rm_f default_destination end def default_destination @default_destination ||= File.join(root_destination, 'default') end def default_symlink FileUtils.ln_s(default_locale, default_destination) end def self_symlink FileUtils.rm_f(locale_destination) FileUtils.ln_s('.', locale_destination) end end end