middleman/middleman-more/lib/middleman-more/core_extensions/i18n.rb

151 lines
4.2 KiB
Ruby
Raw Normal View History

2013-04-20 23:58:06 +02:00
class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
option :no_fallbacks, false, "Disable I18n fallbacks"
option :langs, nil, "List of langs, will autodiscover by default"
option :lang_map, {}, "Language shortname map"
option :path, "/:locale/", "URL prefix path"
option :templates_dir, "localizable", "Location of templates to be localized"
option :mount_at_root, nil, "Mount a specific language at the root of the site"
option :data, "locales", "The directory holding your locale configurations"
def initialize(app, options_hash={}, &block)
super
# See https://github.com/svenfuchs/i18n/wiki/Fallbacks
unless options[:no_fallbacks]
require "i18n/backend/fallbacks"
::I18n::Backend::Simple.send(:include, ::I18n::Backend::Fallbacks)
end
2013-04-20 23:58:06 +02:00
app.config.define_setting :locales_dir, "locales", 'The directory holding your locale configurations'
end
2013-04-20 23:58:06 +02:00
def after_configuration
@locales_glob = File.join(app.config[:locals_dir] || options[:data], "**", "*.{rb,yml,yaml}")
2012-03-11 04:40:04 +01:00
2013-04-20 23:58:06 +02:00
# File.fnmatch doesn't support brackets: {rb,yml,yaml}
regex = @locales_glob.sub(/\./, '\.').sub(File.join("**", "*"), ".*").sub(/\//, '\/').sub("{rb,yml,yaml}", "rb|ya?ml")
@locales_regex = %r{^#{regex}}
2013-04-20 23:58:06 +02:00
@maps = {}
2013-04-20 23:58:06 +02:00
::I18n.load_path += Dir[File.join(app.root, @locales_glob)]
::I18n.reload!
2013-04-20 23:58:06 +02:00
@mount_at_root = options[:mount_at_root].nil? ? langs.first : options[:mount_at_root]
2013-04-20 23:58:06 +02:00
::I18n.default_locale = @mount_at_root
# Reset fallbacks to fall back to our new default
if ::I18n.respond_to? :fallbacks
::I18n.fallbacks = ::I18n::Locale::Fallbacks.new
end
2013-04-20 23:58:06 +02:00
if !app.build?
logger.info "== Locales: #{langs.join(", ")} (Default #{@mount_at_root})"
end
2013-04-20 23:58:06 +02:00
# Don't output localizable files
app.ignore File.join(options[:templates_dir], "**")
2013-04-20 23:58:06 +02:00
app.sitemap.provides_metadata_for_path do |url|
if d = get_localization_data(url)
lang, page_id = d
else
# Default to the @mount_at_root lang
page_id = nil
lang = @mount_at_root
end
2013-04-20 23:58:06 +02:00
instance_vars = Proc.new do
@lang = lang
@page_id = page_id
end
locals = { :lang => lang,
:page_id => page_id }
{ :blocks => [instance_vars],
:locals => locals,
:options => { :lang => lang } }
end
2013-04-20 23:58:06 +02:00
app.files.changed(&method(:on_file_changed))
app.files.deleted(&method(:on_file_changed))
end
2013-04-20 23:58:06 +02:00
helpers do
def t(*args)
::I18n.t(*args)
end
end
2013-04-20 23:58:06 +02:00
delegate :logger, :to => :app
2013-04-20 23:58:06 +02:00
def on_file_changed(file)
if @locales_regex =~ file
::I18n.reload!
end
end
2013-04-20 23:58:06 +02:00
def langs
if options[:langs]
Array(options[:langs]).map(&:to_sym)
else
Dir[File.join(app.root, @locales_glob)].map { |file|
File.basename(file).sub(/\.ya?ml$/, "").sub(/\.rb$/, "")
}.sort.map(&:to_sym)
end
end
2013-04-20 23:58:06 +02:00
def get_localization_data(path)
@_localization_data ||= {}
@_localization_data[path]
end
2013-04-20 23:58:06 +02:00
# Update the main sitemap resource list
# @return [void]
def manipulate_resource_list(resources)
@_localization_data = {}
2013-04-20 23:58:06 +02:00
new_resources = []
2013-04-20 23:58:06 +02:00
resources.each do |resource|
next unless File.fnmatch(File.join(options[:templates_dir], "**"), resource.path)
2013-04-20 23:58:06 +02:00
page_id = File.basename(resource.path, File.extname(resource.path))
2013-04-20 23:58:06 +02:00
old_locale = ::I18n.locale
langs.map do |lang|
::I18n.locale = lang
2013-04-20 23:58:06 +02:00
localized_page_id = ::I18n.t("paths.#{page_id}", :default => page_id, :fallback => [])
path = resource.path.sub(options[:templates_dir], "")
2013-04-20 23:58:06 +02:00
# Build lang path
if @mount_at_root == lang
prefix = "/"
else
replacement = options[:lang_map].has_key?(lang) ? options[:lang_map][lang] : lang
prefix = options[:path].sub(":locale", replacement.to_s)
2012-04-16 22:30:22 +02:00
end
2013-04-20 23:58:06 +02:00
path = ::Middleman::Util.normalize_path(
File.join(prefix, path.sub(page_id, localized_page_id))
)
@_localization_data[path] = [lang, path, localized_page_id]
p = ::Middleman::Sitemap::Resource.new(
app.sitemap,
path
)
p.proxy_to(resource.path)
new_resources << p
2012-04-16 22:30:22 +02:00
end
2013-04-20 23:58:06 +02:00
::I18n.locale = old_locale
2012-03-11 04:40:04 +01:00
end
2013-04-20 23:58:06 +02:00
resources + new_resources
2012-03-11 04:40:04 +01:00
end
end