Skip to content

Commit

Permalink
Basic i18n-tasks support with custom parser for Spree.t
Browse files Browse the repository at this point in the history
  • Loading branch information
rposborne committed Oct 14, 2015
1 parent 1f771d6 commit aa5e2bd
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 53 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ spec/dummy
public/spree
.ruby-version
.ruby-gemset
config/locales/en.yml
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ Remove all occurrences of `SpreeI18n::Config.supported_locales` from your code.

---

## Managing Translations

We use i18n-tasks to keep locales normalized with spree upstream.

### Updating Keys with Spree Master
``` bash
be rake spree_i18n:update_en # Pulls en.yml from spree/spree master
i18n-tasks add-missing-nil
```

### Normalizing Locales
``` bash
i18n-tasks normalize
```

See i18n-tasks for the rest of the magic


## Contributing

[See corresponding guidelines][7]
Expand Down
59 changes: 6 additions & 53 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,61 +25,14 @@ task :test_app do
end

namespace :spree_i18n do
desc 'Update by retrieving the latest Spree locale files'
task :update_default do
puts "Fetching latest Spree locale file to #{locales_dir}"
require 'uri'
require 'net/https'

desc 'Update by retrieving the latest Spree locale files for i18n-tasks'
task :update_en do
puts "Fetching latest English Spree locale"
require 'open-uri'
location = 'https://raw.github.com/spree/spree/master/core/config/locales/en.yml'
begin
uri = URI.parse(location)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
puts "Getting from #{uri}"
request = Net::HTTP::Get.new(uri.request_uri)
case response = http.request(request)
when Net::HTTPRedirection then location = response['location']
when Net::HTTPClientError, Net::HTTPServerError then response.error!
end
end until Net::HTTPSuccess == response

FileUtils.mkdir_p(default_dir) unless File.directory?(default_dir)

File.open("#{default_dir}/spree_core.yml", 'w') { |file| file << response.body }
end

desc 'Syncronize translation files with latest en (adds comments with fallback en value)'
task :sync do
puts 'Starting syncronization...'
words = translation_keys

Dir["#{locales_dir}/*.yml"].each do |filename|
basename = File.basename(filename, '.yml')
(comments, other) = Spree::I18nUtils.read_file(filename, basename)
# Initializing hash variable as en fallback if it does not exist
words.each { |k, _v| other[k] ||= "#{words[k]}" }
# Remove if not defined in en locale
other.delete_if { |k, _v| !words[k] }
Spree::I18nUtils.write_file(filename, basename, comments, other, false)
open("config/locales/en.yml", 'wb') do |file|
file << open(location).read
end
end

def translation_keys
(dummy_comments, words) = Spree::I18nUtils.read_file(File.dirname(__FILE__) + '/default/spree_core.yml', 'en')
words
end

def locales_dir
File.join File.dirname(__FILE__), 'config/locales'
end

def default_dir
File.join File.dirname(__FILE__), 'default'
end

def env_locale
ENV['LOCALE'].presence
end
end
151 changes: 151 additions & 0 deletions config/i18n-tasks.yml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks

# The "main" locale.
base_locale: en
## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
# locales: [es, fr]
## Reporting locale, default: en. Available: en, ru.
# internal_locale: en

# Read and write translations.
data:
## Translations are read from the file system. Supported format: YAML, JSON.
## Provide a custom adapter:
# adapter: I18n::Tasks::Data::FileSystem

# Locale files or `File.find` patterns where translations are read from:
read:
## Default:
# - config/locales/%{locale}.yml
## More files:
# - config/locales/**/*.%{locale}.yml
## Another gem (replace %#= with %=):
# - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"

# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
# `i18n-tasks normalize -p` will force move the keys according to these rules
write:
## For example, write devise and simple form keys to their respective files:
# - ['{devise, simple_form}.*', 'config/locales/\1.%{locale}.yml']
## Catch-all default:
# - config/locales/%{locale}.yml

## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
# router: convervative_router

yaml:
write:
# do not wrap lines at 80 characters
line_width: -1

## Pretty-print JSON:
# json:
# write:
# indent: ' '
# space: ' '
# object_nl: "\n"
# array_nl: "\n"

# Find translate calls
search:
## Paths or `File.find` patterns to search in:
paths:
# This currently cannot see into spree.t calls will be easier to support
# in 0.9
<% spree_path = %x[bundle show spree].chomp %>
- "<%=spree_path%>/core/app"
- "<%=spree_path%>/frontend/app"
- "<%=spree_path%>/backend/app"
- "<%=spree_path%>/cmd/app"
- "<%=spree_path%>/api/app"
- "<%=spree_path%>/core/lib"
- "<%=spree_path%>/frontend/lib"
- "<%=spree_path%>/backend/lib"
- "<%=spree_path%>/cmd/lib"
- "<%=spree_path%>/api/lib"

## Root directories for relative keys resolution.
relative_roots:
- app

## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
## %w(*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less *.yml *.json)
exclude:
- app/assets/images
- app/assets/fonts

## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
# include: ["*.rb", "*.html.slim"]

## Default scanner finds t() and I18n.t() calls.
# scanner: I18nTasks::Scanners::SpreeTScanner

## Google Translate
# translation:
# # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate
# api_key: "AbC-dEf5"

## Do not consider these keys missing:
# ignore_missing:
# - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
# - '{devise,simple_form}.*'

## Consider these keys used:
# ignore_unused:
# - 'activerecord.attributes.*'
# - '{devise,kaminari,will_paginate}.*'
# - 'simple_form.{yes,no}'
# - 'simple_form.{placeholders,hints,labels}.*'
# - 'simple_form.{error_notification,required}.:'

## Exclude these keys from the `i18n-tasks eq-base' report:
# ignore_eq_base:
# all:
# - common.ok
# fr,es:
# - common.brand

## Ignore these keys completely:
# ignore:
# - kaminari.*

# Hackity Hack
# See https://github.com/glebm/i18n-tasks/issues/170
<% module AddMissingNil
include ::I18n::Tasks::Command::Collection
cmd :add_missing_nil,
desc: 'Add missing keys with nil values',
pos: '[locale ...]',
args: [:locales]
def add_missing_nil(opt = {})
add_missing opt.merge(value: nil)
end
end
I18n::Tasks::Commands.send :include, AddMissingNil

%>

# Add in spree custom scanner in 0.9
<%
require './lib/i18n/spree_t_scanner.rb'
I18n::Tasks::Configuration::DEFAULTS[:search][:scanners] = [
[
'I18n::Scanners::SpreeTScanner',
{ ignore_lines: { 'opal' => '^\\s*#(?!\\si18n-tasks-use)',
'haml' => '^\\s*-\\s*#(?!\\si18n-tasks-use)',
'slim' => '^\\s*(?:-#|/)(?!\\si18n-tasks-use)',
'coffee' => '^\\s*#(?!\\si18n-tasks-use)',
'erb' => '^\\s*<%\\s*#(?!\\si18n-tasks-use)' }
}
]

]
# Scope this down, so we don't hit Spree.t twice
# if someone is better at regex, it's possible we can have both of these.
# I18n::Tasks::Scanners::PatternScanner.class_eval do
# def translate_call_re
# /(?<=^|[^\w'\-])(?!Spree)t(?:ranslate)?/
# end
# end
%>
32 changes: 32 additions & 0 deletions lib/i18n/spree_t_scanner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'i18n/tasks/scanners/pattern_scanner'
module I18n
module Scanners
class SpreeTScanner < I18n::Tasks::Scanners::PatternWithScopeScanner
# Extract i18n keys from file based on the pattern which must capture the key literal.
# @return [Array<Key>] keys found in file

# Given
# @param [MatchData] match
# @param [String] path
# @return [String] full absolute key name
def match_to_key(match, path, location)
key = super
scope = match[1]
if scope
scope_ns = scope.gsub(/[\[\]\s]+/, ''.freeze).split(','.freeze).map { |arg| strip_literal(arg) } * '.'.freeze
new_key = "#{scope_ns}.#{key}"
else
new_key = key unless match[0] =~ /\A\w/
end

"spree.#{new_key}"
end

def translate_call_re
/Spree.t(?:ranslate)?/
end
end
end
end


0 comments on commit aa5e2bd

Please sign in to comment.