|
| 1 | +Jekyll::Hooks.register [:site], :pre_render do |site| |
| 2 | + default_locale = site.config["locale"] || "en" |
| 3 | + locales = Array(site.config["locales"] || default_locale) |
| 4 | + locales.unshift(default_locale) unless locales.include?(default_locale) |
| 5 | + return if locales.length == 0 |
| 6 | + |
| 7 | + doc_map = {} |
| 8 | + |
| 9 | + (site.pages + site.documents).each do |doc| |
| 10 | + basename = File.basename(doc.path) |
| 11 | + doc_locale = basename[/\.(\w+)\.\w+$/, 1] |
| 12 | + next unless doc.data["i18n"] == true |
| 13 | + |
| 14 | + if doc_locale && locales.include?(doc_locale) |
| 15 | + default_doc_path = doc.path.sub(/\.#{Regexp.escape(doc_locale)}(?=\.\w+$)/, "") |
| 16 | + else |
| 17 | + doc_locale = default_locale |
| 18 | + default_doc_path = doc.path |
| 19 | + end |
| 20 | + doc_map[default_doc_path] ||= {} |
| 21 | + doc_map[default_doc_path][doc_locale] = doc |
| 22 | + end |
| 23 | + |
| 24 | + generate_fallback_doc = lambda do |fallback_doc, locale| |
| 25 | + if fallback_doc.is_a?(Jekyll::Page) |
| 26 | + base, dir, name = fallback_doc.instance_variable_get(:@base), fallback_doc.instance_variable_get(:@dir), fallback_doc.instance_variable_get(:@name) |
| 27 | + new_doc = Jekyll::PageWithoutAFile.new(fallback_doc.site, base, dir, name) |
| 28 | + site.pages << new_doc |
| 29 | + else |
| 30 | + path, collection = fallback_doc.instance_variable_get(:@path), fallback_doc.collection |
| 31 | + new_doc = Jekyll::Document.new(path, site: fallback_doc.site, collection: collection) |
| 32 | + collection.docs << new_doc |
| 33 | + end |
| 34 | + |
| 35 | + new_doc.content = fallback_doc.content |
| 36 | + fallback_doc.data.each { |k, v| new_doc.data[k] = v } |
| 37 | + new_doc.data["permalink"] = "/#{locale}#{fallback_doc.url}" |
| 38 | + new_doc.data["lang"] = locale |
| 39 | + end |
| 40 | + |
| 41 | + doc_map.each_value do |docs| |
| 42 | + default_doc = docs[default_locale] |
| 43 | + next unless default_doc |
| 44 | + |
| 45 | + locales.each do |locale| |
| 46 | + if docs[locale] |
| 47 | + docs[locale].data["lang"] = locale |
| 48 | + docs[locale].data["origin_lang"] = locale |
| 49 | + if locale != default_locale |
| 50 | + docs[locale].data["permalink"] = "/#{locale}#{default_doc.url}" |
| 51 | + docs[locale].instance_variable_set(:@url, nil) |
| 52 | + end |
| 53 | + else |
| 54 | + fallback_doc = default_doc |
| 55 | + generate_fallback_doc.call(fallback_doc, locale) |
| 56 | + end |
| 57 | + end |
| 58 | + end |
| 59 | +end |
0 commit comments