2012-05-07 23:41:39 +02:00
|
|
|
module Middleman
|
|
|
|
module CoreExtensions
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-25 01:51:36 +02:00
|
|
|
# i18n Namespace
|
2012-06-06 04:11:05 +02:00
|
|
|
module Internationalization
|
2012-03-11 04:40:04 +01:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
# Setup extension
|
|
|
|
class << self
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
# Once registerd
|
2012-05-25 01:51:36 +02:00
|
|
|
def registered(app, options={})
|
2012-10-14 04:54:55 +02:00
|
|
|
app.config.define_setting :locales_dir, "locales", 'The directory holding your locale configurations'
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
# Needed for helpers as well
|
|
|
|
app.after_configuration do
|
2013-01-12 02:00:41 +01:00
|
|
|
Localizer.new(self, options)
|
2012-05-07 23:41:39 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
alias :included :registered
|
2012-04-16 22:30:22 +02:00
|
|
|
end
|
2012-08-14 00:39:06 +02:00
|
|
|
|
|
|
|
# Central class for managing i18n extension
|
2012-05-07 23:41:39 +02:00
|
|
|
class Localizer
|
2012-07-15 20:04:45 +02:00
|
|
|
attr_reader :app
|
|
|
|
delegate :logger, :to => :app
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2013-01-12 02:00:41 +01:00
|
|
|
def initialize(app, options={})
|
2012-05-07 23:41:39 +02:00
|
|
|
@app = app
|
2013-02-09 19:15:25 +01:00
|
|
|
@locales_glob = File.join(app.locales_dir, "**", "*.{rb,yml,yaml}")
|
2013-01-12 02:00:41 +01:00
|
|
|
|
2013-02-11 00:41:36 +01:00
|
|
|
# File.fnmatch doesn't support brackets: {rb,yml,yaml}
|
2013-02-09 19:15:25 +01:00
|
|
|
regex = @locales_glob.sub(/\./, '\.').sub(File.join("**", "*"), ".*").sub(/\//, '\/').sub("{rb,yml,yaml}", "rb|ya?ml")
|
2013-01-12 02:00:41 +01:00
|
|
|
@locales_regex = %r{^#{regex}}
|
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
@maps = {}
|
|
|
|
@options = options
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2013-01-12 02:00:41 +01:00
|
|
|
::I18n.load_path += Dir[File.join(app.root, @locales_glob)]
|
|
|
|
::I18n.reload!
|
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
@lang_map = @options[:lang_map] || {}
|
|
|
|
@path = @options[:path] || "/:locale/"
|
|
|
|
@templates_dir = @options[:templates_dir] || "localizable"
|
|
|
|
@mount_at_root = @options.has_key?(:mount_at_root) ? @options[:mount_at_root] : langs.first
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
if !@app.build?
|
2013-02-09 21:34:30 +01:00
|
|
|
logger.info "== Locales: #{langs.join(", ")} (Default #{@mount_at_root})"
|
2012-05-07 23:41:39 +02:00
|
|
|
end
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
# Don't output localizable files
|
|
|
|
@app.ignore File.join(@templates_dir, "**")
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
@app.sitemap.provides_metadata_for_path do |url|
|
|
|
|
if d = get_localization_data(url)
|
|
|
|
lang, page_id = d
|
|
|
|
else
|
2013-02-09 21:40:43 +01:00
|
|
|
# Default to the @mount_at_root lang
|
|
|
|
page_id = nil
|
|
|
|
lang = @mount_at_root
|
2012-05-07 23:41:39 +02:00
|
|
|
end
|
2013-02-09 21:40:43 +01:00
|
|
|
|
|
|
|
instance_vars = Proc.new do
|
|
|
|
@lang = lang
|
|
|
|
@page_id = page_id
|
|
|
|
end
|
|
|
|
|
2013-04-03 08:28:47 +02:00
|
|
|
locals = { :lang => lang,
|
|
|
|
:page_id => page_id }
|
|
|
|
{ :blocks => [instance_vars],
|
|
|
|
:locals => locals,
|
|
|
|
:options => { :lang => lang } }
|
2012-05-07 23:41:39 +02:00
|
|
|
end
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
@app.sitemap.register_resource_list_manipulator(
|
|
|
|
:i18n,
|
2012-05-25 01:51:36 +02:00
|
|
|
self
|
2012-05-07 23:41:39 +02:00
|
|
|
)
|
2012-09-30 22:17:01 +02:00
|
|
|
|
|
|
|
@app.files.changed(&method(:on_file_changed))
|
|
|
|
@app.files.deleted(&method(:on_file_changed))
|
|
|
|
end
|
|
|
|
|
|
|
|
def on_file_changed(file)
|
2013-02-09 09:20:37 +01:00
|
|
|
if @locales_regex =~ file
|
2012-09-30 22:17:01 +02:00
|
|
|
::I18n.reload!
|
|
|
|
end
|
2012-05-07 23:41:39 +02:00
|
|
|
end
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
def langs
|
2013-02-09 21:34:30 +01:00
|
|
|
if @options[:langs]
|
|
|
|
Array(@options[:langs]).map(&:to_sym)
|
|
|
|
else
|
2012-09-30 22:17:01 +02:00
|
|
|
Dir[File.join(@app.root, @locales_glob)].map { |file|
|
2013-02-09 19:15:25 +01:00
|
|
|
File.basename(file).sub(/\.ya?ml$/, "").sub(/\.rb$/, "")
|
2012-05-07 23:41:39 +02:00
|
|
|
}.sort.map(&:to_sym)
|
|
|
|
end
|
|
|
|
end
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
def get_localization_data(path)
|
|
|
|
@_localization_data ||= {}
|
|
|
|
@_localization_data[path]
|
|
|
|
end
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
# Update the main sitemap resource list
|
|
|
|
# @return [void]
|
|
|
|
def manipulate_resource_list(resources)
|
|
|
|
@_localization_data = {}
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
new_resources = []
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
resources.each do |resource|
|
|
|
|
next unless File.fnmatch(File.join(@templates_dir, "**"), resource.path)
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
page_id = File.basename(resource.path, File.extname(resource.path))
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2013-04-03 08:28:47 +02:00
|
|
|
old_locale = ::I18n.locale
|
2012-05-07 23:41:39 +02:00
|
|
|
langs.map do |lang|
|
|
|
|
::I18n.locale = lang
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
localized_page_id = ::I18n.t("paths.#{page_id}", :default => page_id)
|
|
|
|
path = resource.path.sub(@templates_dir, "")
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
# Build lang path
|
|
|
|
if @mount_at_root == lang
|
|
|
|
prefix = "/"
|
|
|
|
else
|
|
|
|
replacement = @lang_map.has_key?(lang) ? @lang_map[lang] : lang
|
|
|
|
prefix = @path.sub(":locale", replacement.to_s)
|
|
|
|
end
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
path = ::Middleman::Util.normalize_path(
|
|
|
|
File.join(prefix, path.sub(page_id, localized_page_id))
|
|
|
|
)
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
@_localization_data[path] = [lang, path, localized_page_id]
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
p = ::Middleman::Sitemap::Resource.new(
|
|
|
|
@app.sitemap,
|
|
|
|
path
|
|
|
|
)
|
|
|
|
p.proxy_to(resource.path)
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
new_resources << p
|
|
|
|
end
|
2013-04-03 08:28:47 +02:00
|
|
|
::I18n.locale = old_locale
|
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
end
|
2012-08-14 00:39:06 +02:00
|
|
|
|
2012-05-07 23:41:39 +02:00
|
|
|
resources + new_resources
|
2012-04-16 22:30:22 +02:00
|
|
|
end
|
|
|
|
end
|
2012-03-11 04:40:04 +01:00
|
|
|
end
|
|
|
|
end
|
2012-06-06 04:11:05 +02:00
|
|
|
end
|