localeapp-handlebars_i18n 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ .localeapp
2
+ coverage
3
+ .yardoc
4
+ doc
5
+ *.gem
@@ -0,0 +1,3 @@
1
+ --readme README.yard
2
+ --no-private
3
+ --exclude README.markdown
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+ # Specify your gem's dependencies in localeapp-handlebars_i18n.gemspec
3
+ gemspec
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ localeapp-handlebars_i18n (0.0.1)
5
+ localeapp
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.1.3)
11
+ gli (2.5.0)
12
+ i18n (0.6.1)
13
+ json (1.7.5)
14
+ localeapp (0.6.8)
15
+ gli
16
+ i18n
17
+ json
18
+ rest-client
19
+ ya2yaml
20
+ mime-types (1.19)
21
+ multi_json (1.4.0)
22
+ rack (1.4.1)
23
+ rake (0.9.2.2)
24
+ rest-client (1.6.7)
25
+ mime-types (>= 1.16)
26
+ rspec (2.12.0)
27
+ rspec-core (~> 2.12.0)
28
+ rspec-expectations (~> 2.12.0)
29
+ rspec-mocks (~> 2.12.0)
30
+ rspec-core (2.12.1)
31
+ rspec-expectations (2.12.0)
32
+ diff-lcs (~> 1.1.3)
33
+ rspec-mocks (2.12.0)
34
+ simplecov (0.7.1)
35
+ multi_json (~> 1.0)
36
+ simplecov-html (~> 0.7.1)
37
+ simplecov-html (0.7.1)
38
+ ya2yaml (0.31)
39
+ yard (0.8.3)
40
+
41
+ PLATFORMS
42
+ ruby
43
+
44
+ DEPENDENCIES
45
+ localeapp-handlebars_i18n!
46
+ rack
47
+ rake
48
+ rspec
49
+ simplecov
50
+ yard
@@ -0,0 +1,4 @@
1
+ # Localeapp::HandlebarsI18n
2
+
3
+ Documentation for Localeapp::HandlebarsI18n is hosted at
4
+ <a href="http://rubydoc.info/github/randym/localeapp-handlebars_i18n/master/file/README.yard">rubydoc.info</a>
@@ -0,0 +1,107 @@
1
+ = Localeapp::HanldebarsI18n
2
+
3
+ Localeapp::HandlebarsI18n is a set of tools for parsing hanldebars
4
+ templates for a specific helper to collect missing i18n keys and report
5
+ them to the Localeapp service.
6
+
7
+ = Usage
8
+
9
+ I usually set this up as a rake task so that I can push up missing
10
+ tranlstions, push any new translations in the default locale yml file
11
+ and finally pull down any new localizations from Localeapp.
12
+
13
+ Here is an overly verbose example of a rake task that does just that!
14
+
15
+ !!!ruby
16
+ namespace :localeapp do
17
+ desc "push missing handlebars keys up to localeapp and update locale yml from localeapp"
18
+ task :update do
19
+ require 'localeapp-handlebars_i18n'
20
+ Localeapp::HandlebarsI18n.configure do |config|
21
+ config.hbs_load_path = Dir[File.expand_path '../assets/scripts/app/templates/**/*.hbs', __FILE__]
22
+ config.yml_load_path = File.expand_path '../locales/', __FILE__
23
+ config.localeapp_api_key = ENV['LOCALEAPP_API_KEY']
24
+ config.default_locale = :en
25
+ config.hbs_helper = 't'
26
+ end
27
+ Localeapp::HandlebarsI18n.send_missing_translations
28
+ system "localeapp push locales/#{Localeapp::HandlebarsI18n.default_locale}.yml"
29
+ system "localeapp pull"
30
+ end
31
+ end
32
+
33
+ = The details
34
+
35
+ This gem requires that you have a good understanding of how to get up
36
+ and running with Localeapp. For it to be truly useful, you will also
37
+ either be building a Rails application that compiles i18n localizaion
38
+ information for use by I18n-js or Emberjs.STRINGS. To raise that barrier
39
+ to entry just a little bit higher, you will be using handlebars for your
40
+ view templates and have a localization helper setup in handlebars that
41
+ lets you do stuff like !{{t some.string}} in your template to push out a
42
+ localized string.
43
+
44
+ If you are looking for a good example of all of this, have a look at
45
+ travis-web!
46
+
47
+ If all of that makes sense to you, here is an explanation of the
48
+ configuration options that you will need to set up to push out missing
49
+ tranlsations to Localeapp.
50
+
51
+
52
+ === hbs_load_path
53
+ This is the path to all of your handlebars templates. All of the files
54
+ listed here will be scanned for a handlebars set using the helper you
55
+ specify in the following option.
56
+
57
+ === hbs_helper
58
+ By default, this is going to look for !{{t some.key}} - or more
59
+ specifically /!{{t (.*?)}}/ capturing what should be your tranlsation
60
+ keys and comparing them to the data found in the following option.
61
+
62
+ === yml_load_path
63
+ This is where your locale files live. The default locale is :en when
64
+ looking up handlebars localizations but you can override this with the
65
+ following configuration
66
+
67
+ === default_locale
68
+ This is a symbol that defines the default locale you are working
69
+ against. Most folks are using :en as the defualt locale, so that is what
70
+ this gem uses. You can set it to any locale symbol you like but you need
71
+ to be sure the file [default_locale].yml exists in the directory you
72
+ specified for yml_load_path.
73
+
74
+ === localeapp_api_key
75
+ This is your secret api key for using locale app. I usually export it
76
+ to an shell variable, but how you manage it is up to you. Just dont post
77
+ it to your public repo or anyone in the world will be able to update all
78
+ your tranlsations to their favorite four letter word.
79
+
80
+
81
+ = Coverage
82
+ As always, this gem has 100% test coverage and 100% documentation
83
+
84
+
85
+ = License
86
+ Copyright (c) 2012 Randy Morgan
87
+
88
+ Permission is hereby granted, free of charge, to any person
89
+ obtaining a copy of this software and associated documentation
90
+ files (the "Software"), to deal in the Software without
91
+ restriction, including without limitation the rights to use,
92
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
93
+ copies of the Software, and to permit persons to whom the
94
+ Software is furnished to do so, subject to the following
95
+ conditions:
96
+
97
+ The above copyright notice and this permission notice shall be
98
+ included in all copies or substantial portions of the Software.
99
+
100
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
101
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
102
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
103
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
104
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
105
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
106
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
107
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/setup"
3
+
4
+ desc "run the specs"
5
+ task :spec do
6
+ sh "rspec -cfs spec"
7
+ end
8
+
9
+ task :default => :spec
10
+
11
+ desc "build the gem"
12
+ task :build do
13
+ system "gem build localeapp-handlebars_i18n.gemspec"
14
+ end
15
+ desc "build and release the gem"
16
+ task :release => :build do
17
+ system "gem push localeapp-handlebars_i18n-#{Localeapp::HandlebarsI18n::VERSION}.gem"
18
+ end
@@ -0,0 +1,162 @@
1
+ require 'localeapp'
2
+
3
+ # The Localeapp Module - we place HandlebarsI18n under this namespace
4
+ module Localeapp
5
+
6
+ # A singleton module that reports missing translations found in handebars templates to Localeapp.
7
+ # Once you have set everything up with configure it is a simple matter of calling Localeapp::HandlebarsI18n.send_missing_translations and you are done.
8
+ module HandlebarsI18n
9
+
10
+ class << self
11
+
12
+ # configures HanldebarsI18n
13
+ # @param [Object] output You can pass in an object that accepts calls to puts for logging. By default $stdout will be used.
14
+ # @param [Proc] block A configuration block
15
+ # @example
16
+ # Localeapp::HandlebarsI18.configure do |config|
17
+ # config.localeapp_api_key = ENV['LOCALEAPP_API_KEY']
18
+ # config.hbs_helper = 't'
19
+ # config.hbs_load_path = Dir[File.expand_path '../support/**.hbs', __FILE__]
20
+ # config.yml_load_path = File.expand_path '../support/', __FILE__
21
+ # config.default_locale = :ru
22
+ # end
23
+ def configure(output = $stdout, &block)
24
+ @output = output
25
+ instance_eval &block if block_given?
26
+ register_missing_translations
27
+ end
28
+
29
+ # The string name of your handlebars helper function for translation.
30
+ # Here is an example coffeescript handlebars helper registration that creates a helper named 't'
31
+ # that uses I18n-js for javascript localizations. If you had a helper like the one below, you would
32
+ # pass 't' into this method. 't' is also the default so if you are already using a helper named 't'
33
+ # you do not need to configure this.
34
+ #
35
+ # This helper is interpolated into the regular expression used to scan for translation keys:
36
+ # "{{#{hbs_helper}} (.*?)}}"
37
+ #
38
+ # @example
39
+ # Handlebars.registerHelper 't', (key) ->
40
+ # safe I18n.t(key)
41
+ # @param [String] helper The name of your handlebars helper used for localization.
42
+ def hbs_helper=(helper)
43
+ @hbs_helper
44
+ end
45
+
46
+ # @see hbs_helper=
47
+ def hbs_helper
48
+ @hbs_helper ||= 't'
49
+ end
50
+
51
+ # The default locale to load when comparing handlebar translation keys and I18n translation keys.
52
+ # This is used when loading YAML data into I18n's simple backend
53
+ # @param [Symbol] locale the locale to load.
54
+ def default_locale=(locale)
55
+ @default_locale = locale
56
+ end
57
+
58
+ # @see default_locale=
59
+ def default_locale
60
+ @default_locale ||= :en
61
+ end
62
+
63
+ # The directory where your locale .yml files live.
64
+ # @param [String] dir The directory to search for the default locale's YAML data
65
+ def yml_load_path=(dir)
66
+ @yml_load_path = dir
67
+ end
68
+
69
+ # This defines the yml file to load for I18n. It retuns an interpolated string of the yml_load_path value you configured
70
+ # and the default locale.
71
+ # @return [String]
72
+ def yml_load_path
73
+ "#{@yml_load_path}/#{default_locale}.yml"
74
+ end
75
+
76
+ # Sets the array of handlebars templates that will be searched for localization helpers. Dir.glob is pretty dang handy here.
77
+ # @param [Array] files The files to search.
78
+ # @see hbs_helper
79
+ def hbs_load_path=(files)
80
+ @hbs_load_path = files.flatten
81
+ end
82
+
83
+ # Returns the files you specified or an empty array
84
+ # @return [Array]
85
+ def hbs_load_path
86
+ @hbs_load_path ||= []
87
+ end
88
+
89
+ # Configures localeapp to use the api key you specify when reporting missing translations.
90
+ # @param [String] api_key The localeapp api key.
91
+ def localeapp_api_key=(api_key)
92
+ Localeapp.configure do |config|
93
+ config.api_key= api_key
94
+ end
95
+ end
96
+
97
+ # Sends any missing translations to Localeapp.
98
+ # @note If you have not configured Localeapp::HandlebarsI18n you will recieve an error with an example on how to do so.
99
+ def send_missing_translations
100
+ ensure_configured
101
+ return if Localeapp.missing_translations[default_locale].empty?
102
+ @output.puts "sending missing translations to localeapp"
103
+ Localeapp::sender.post_missing_translations
104
+ end
105
+
106
+ private
107
+ def hbs_locale_keys
108
+ @hbs_locale_keys ||= hbs_load_path.map do |file|
109
+ extract_keys(file)
110
+ end.flatten.compact.uniq
111
+ end
112
+
113
+
114
+ def ensure_configured
115
+ if @hbs_load_path.nil? || @yml_load_path.nil?
116
+ raise ArgumentError, <<ERROR_MSG
117
+ "You must configure Localeapp::Reporter before sending missing translations.
118
+ example:
119
+
120
+ Localeapp::Reporter.configure do |config|
121
+ config.localeapp_api_key = ENV['LOCALEAPP_API_KEY']
122
+ config.yml_load_path = 'locales/'
123
+ config.hbs_load_path = 'assets/scripts/app/templates/**/*.hbs'
124
+ config.hbs_helper = 't'
125
+ config.default_locale = :en
126
+ end
127
+ ERROR_MSG
128
+ end
129
+ end
130
+
131
+
132
+ def matcher
133
+ @matcher ||= Regexp.new("{{#{hbs_helper} (.*?)}}")
134
+ end
135
+
136
+ def backend
137
+ @backend ||= I18n::Backend::Simple.new.tap do |simple|
138
+ simple.load_translations yml_load_path
139
+ end
140
+ end
141
+
142
+ def extract_keys(template_file)
143
+ template = IO.read(template_file)
144
+ template.scan(matcher)
145
+ end
146
+
147
+ def register_missing_translations
148
+ hbs_locale_keys.each do |key|
149
+ key.gsub!(/[\"\']/, '')
150
+ begin
151
+ backend.translate(default_locale, key)
152
+ rescue Exception => e
153
+ @output.puts "translation missing: #{key}"
154
+ Localeapp.missing_translations.add(default_locale, key, key.split('.').last)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+
@@ -0,0 +1,6 @@
1
+ module Localeapp
2
+ module HandlebarsI18n
3
+ # The current version
4
+ VERSION = '0.0.1'
5
+ end
6
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path('../lib/localeapp-handlebars_i18n/version', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ["Randy Morgan"]
5
+ gem.email = ["digital.ipseity@gmail.com"]
6
+ gem.description = %q{A localeapp reporter for working with handlebars templates with localizations.}
7
+ gem.summary = %q{Parses handlebars templates for localization helpers and adds missing keys to localeapp.}
8
+ gem.homepage = "http://github.com/randym/localeapp-handlebars_i18n"
9
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
10
+ gem.files = `git ls-files`.split("\n")
11
+ gem.test_files = `git ls-files -- {spec}/*`.split("\n")
12
+ gem.name = "localeapp-handlebars_i18n"
13
+ gem.require_paths = ["lib"]
14
+ gem.version = Localeapp::HandlebarsI18n::VERSION
15
+
16
+ gem.add_dependency "localeapp"
17
+ gem.add_development_dependency "rspec"
18
+ gem.add_development_dependency "rack"
19
+ gem.add_development_dependency "rake"
20
+ gem.add_development_dependency "yard"
21
+ gem.add_development_dependency "simplecov"
22
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+ require 'localeapp-handlebars_i18n'
3
+
4
+ describe Localeapp::HandlebarsI18n do
5
+ class Log
6
+ class << self
7
+ def data
8
+ @data ||= []
9
+ end
10
+ def puts(text)
11
+ data << text
12
+ end
13
+ end
14
+ end
15
+ let(:reporter) {
16
+ cloned_module = Localeapp::HandlebarsI18n.clone
17
+ cloned_module.configure(Log) do |config|
18
+ config.localeapp_api_key = 'whatever'
19
+ config.hbs_helper = 't'
20
+ config.hbs_load_path = Dir[File.expand_path '../support/**.hbs', __FILE__]
21
+ config.yml_load_path = File.expand_path '../support/', __FILE__
22
+ config.default_locale = :ru
23
+ end
24
+ cloned_module
25
+ }
26
+ before :each do
27
+ reporter
28
+ end
29
+
30
+ context "with a configured localeapp reporter" do
31
+
32
+ it 'configured the default locale' do
33
+ reporter.default_locale.should == :ru
34
+ end
35
+
36
+ it 'configured the yml_load_path' do
37
+ reporter.yml_load_path.should == File.expand_path("../support/#{reporter.default_locale}.yml", __FILE__)
38
+ end
39
+
40
+ it 'configured the hbs_load_path' do
41
+ reporter.hbs_load_path.should == Dir[File.expand_path '../support/**.hbs', __FILE__]
42
+ end
43
+
44
+ it 'loaded up the i18n backend' do
45
+ expect { reporter.send(:backend).translate(reporter.default_locale, 'existing.key') }.to_not raise_error(ArgumentError)
46
+ expect { reporter.send(:backend).translate(reporter.default_locale, 'missing.key') }.to raise_error(ArgumentError)
47
+ end
48
+
49
+ it "configured Localeapp.missing_translations" do
50
+ Localeapp.missing_translations.should_not be_nil
51
+ end
52
+ it "adds missing {{t missing.key}} translation key to Localeapp.missing_translations" do
53
+ Localeapp.missing_translations[reporter.default_locale].should include('missing.key')
54
+ end
55
+ end
56
+
57
+ context "when sending missing translations" do
58
+ it 'executes a rest client request with the translations in the payload' do
59
+ RestClient::Request.should_receive(:execute).with(hash_including(
60
+ :payload => { :translations => Localeapp.missing_translations.to_send }.to_json)).and_return(double('response', :code => 200))
61
+ reporter.send_missing_translations
62
+ end
63
+ it 'populates the log' do
64
+ # something tells me that if I randomize the order of these specs,
65
+ # this wont pass until a call to send_missing_translations gets
66
+ # sent
67
+ Log.data.should include('sending missing translations to localeapp')
68
+ end
69
+ end
70
+ context "when nothing is configured" do
71
+ before :each do
72
+ @cloned_module = Localeapp::HandlebarsI18n.clone
73
+ end
74
+
75
+ it "send_missing_translations fails with a message to configure." do
76
+ expect { @cloned_module.send_missing_translations }.to raise_error ArgumentError
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,2 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
@@ -0,0 +1 @@
1
+ {{t existing.key}}
@@ -0,0 +1 @@
1
+ {{t missing.key}}
@@ -0,0 +1,3 @@
1
+ ru:
2
+ existing:
3
+ key: An existing key in locale YAML
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: localeapp-handlebars_i18n
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Randy Morgan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: localeapp
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rack
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: yard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: simplecov
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: A localeapp reporter for working with handlebars templates with localizations.
111
+ email:
112
+ - digital.ipseity@gmail.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - .yardopts
119
+ - Gemfile
120
+ - Gemfile.lock
121
+ - README.markdown
122
+ - README.yard
123
+ - Rakefile
124
+ - lib/localeapp-handlebars_i18n.rb
125
+ - lib/localeapp-handlebars_i18n/version.rb
126
+ - localeapp-handlebars_i18n-0.0.1.gem
127
+ - localeapp-handlebars_i18n.gemspec
128
+ - spec/localeapp-handlebars_i18n_spec.rb
129
+ - spec/spec_helper.rb
130
+ - spec/support/existing_t_key.hbs
131
+ - spec/support/missing_t_key.hbs
132
+ - spec/support/ru.yml
133
+ homepage: http://github.com/randym/localeapp-handlebars_i18n
134
+ licenses: []
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ segments:
146
+ - 0
147
+ hash: 1516604966356496189
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ segments:
155
+ - 0
156
+ hash: 1516604966356496189
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 1.8.24
160
+ signing_key:
161
+ specification_version: 3
162
+ summary: Parses handlebars templates for localization helpers and adds missing keys
163
+ to localeapp.
164
+ test_files: []
165
+ has_rdoc: