i18n_backend_database 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +29 -0
- data/README.textile +125 -0
- data/data/locales.yml +4 -0
- data/generators/i18n_backend_database/i18n_backend_database_generator.rb +8 -0
- data/generators/i18n_backend_database/templates/migrate/create_i18n_tables.rb +25 -0
- data/init.rb +1 -0
- data/lib/controllers/locales_controller.rb +86 -0
- data/lib/controllers/translations_controller.rb +141 -0
- data/lib/ext/i18n.rb +68 -0
- data/lib/google_language.rb +33 -0
- data/lib/i18n_backend_database.rb +9 -0
- data/lib/i18n_backend_database/database.rb +263 -0
- data/lib/i18n_util.rb +148 -0
- data/lib/models/locale.rb +67 -0
- data/lib/models/translation.rb +46 -0
- data/lib/models/translation_option.rb +26 -0
- data/lib/public/images/custom1_bar.gif +0 -0
- data/lib/public/images/custom1_box.gif +0 -0
- data/lib/public/images/percentImage.png +0 -0
- data/lib/public/images/percentImage_back.png +0 -0
- data/lib/public/images/percentImage_back1.png +0 -0
- data/lib/public/images/percentImage_back2.png +0 -0
- data/lib/public/images/percentImage_back3.png +0 -0
- data/lib/public/images/percentImage_back4.png +0 -0
- data/lib/public/javascripts/jsProgressBarHandler.js +509 -0
- data/lib/routing.rb +15 -0
- data/lib/views/layouts/translations.html.erb +23 -0
- data/lib/views/locales/edit.html.erb +20 -0
- data/lib/views/locales/index.html.erb +22 -0
- data/lib/views/locales/new.html.erb +19 -0
- data/lib/views/locales/show.html.erb +14 -0
- data/lib/views/translations/asset_translations.html.erb +32 -0
- data/lib/views/translations/edit.html.erb +35 -0
- data/lib/views/translations/index.html.erb +27 -0
- data/lib/views/translations/new.html.erb +19 -0
- data/lib/views/translations/show.html.erb +32 -0
- data/lib/views/translations/translations.html.erb +28 -0
- data/lib/views/translations/update.rjs +7 -0
- data/routes.rb +3 -0
- data/spec/assets/public/es/favicons/favicon1.gif +0 -0
- data/spec/assets/public/es/images/icons/icon1.gif +0 -0
- data/spec/assets/public/es/images/image1.gif +0 -0
- data/spec/assets/public/favicons/favicon1.gif +0 -0
- data/spec/assets/public/favicons/favicon2.gif +0 -0
- data/spec/assets/public/images/icons/icon1.gif +0 -0
- data/spec/assets/public/images/icons/icon2.gif +0 -0
- data/spec/assets/public/images/image1.gif +0 -0
- data/spec/assets/public/images/image2.gif +0 -0
- data/spec/assets/public/images/promo/sfc08_140x400_3.gif +0 -0
- data/spec/assets/views/test_view1.html.erb +1 -0
- data/spec/assets/views/test_view2.html.erb +30 -0
- data/spec/caching_spec.rb +87 -0
- data/spec/controllers/locales_controller_spec.rb +173 -0
- data/spec/controllers/locales_routing_spec.rb +59 -0
- data/spec/controllers/translations_controller_spec.rb +189 -0
- data/spec/controllers/translations_routing_spec.rb +59 -0
- data/spec/database_spec.rb +199 -0
- data/spec/i18n_ext_spec.rb +40 -0
- data/spec/localize_spec.rb +66 -0
- data/spec/localize_text_spec.rb +76 -0
- data/spec/models/locale_spec.rb +111 -0
- data/spec/models/translation_spec.rb +44 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/translate_asset_spec.rb +57 -0
- data/spec/translate_spec.rb +546 -0
- data/tasks/i18n.rake +60 -0
- metadata +155 -0
data/LICENSE
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
* Copyright (c) 2008, 2009
|
2
|
+
* ELC Technologies. All rights reserved.
|
3
|
+
*
|
4
|
+
* Redistribution and use in source and binary forms, with or without
|
5
|
+
* modification, are permitted provided that the following conditions
|
6
|
+
* are met:
|
7
|
+
* 1. Redistributions of source code must retain the above copyright
|
8
|
+
* notice, this list of conditions and the following disclaimer.
|
9
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
* notice, this list of conditions and the following disclaimer in the
|
11
|
+
* documentation and/or other materials provided with the distribution.
|
12
|
+
* 3. All advertising materials mentioning features or use of this software
|
13
|
+
* must display the following acknowledgement:
|
14
|
+
* This product includes software developed by ELC Technologies
|
15
|
+
* 4. Neither the name of the Company nor the names of its contributors
|
16
|
+
* may be used to endorse or promote products derived from this software
|
17
|
+
* without specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
20
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
23
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
25
|
+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
26
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
27
|
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
28
|
+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
29
|
+
* SUCH DAMAGE.
|
data/README.textile
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
h1. A Database Backend For Rails I18N
|
2
|
+
|
3
|
+
Stores your translations in the database, rather than yaml files. As you tag items with i18n.t() throughout your code base, all untranslated items are marked and added to the database. An admin panel is provided so translators can quickly translate untranslated text. All lookups occur in a cache store of your choice prior to hitting the database.
|
4
|
+
|
5
|
+
h2. DISCLAIMER!
|
6
|
+
|
7
|
+
* -In implementing this into another project, I realized that the currency support is currently broken. It basically boils down to the i18n gem accessing some of the Rails i18n yaml's in a different way than others. In this case, it's requesting a parent key, and expects a hash to be returned containing the children. This is not baked in the plugin at the moment, and any contributions toward this would be well received.- Thank you wlorentson!
|
8
|
+
|
9
|
+
* The translations_controller is unprotected, and you'll probably want to add some kind of authorization filter to it to make sure the outside world can't access it.
|
10
|
+
|
11
|
+
h2. Installation
|
12
|
+
|
13
|
+
<pre>
|
14
|
+
<code>
|
15
|
+
script/generate i18n_backend_database # add migration
|
16
|
+
rake db:migrate # migrate
|
17
|
+
|
18
|
+
rake i18n:populate:load_default_locales # populate default locales
|
19
|
+
rake i18n:populate:from_rails # populate the locales and translations tables from all Rails Locale YAML files.
|
20
|
+
rake i18n:populate:from_application # populate the translation tables from translation calls within the application.
|
21
|
+
rake i18n:populate:synchronize_translations # create non-default locale translation records from default locale translations.
|
22
|
+
rake i18n:populate:all # run all populate tasks.
|
23
|
+
rake i18n:translate:google # translate all untranslated string values using Google Language Translation API.
|
24
|
+
</code>
|
25
|
+
</pre>
|
26
|
+
|
27
|
+
|
28
|
+
In config/initialisers/i18n.rb
|
29
|
+
|
30
|
+
<pre>
|
31
|
+
<code>
|
32
|
+
I18n.backend = I18n::Backend::Database.new # registers the backend
|
33
|
+
I18n.backend.cache_store = :memory_store # optional: specify an alternate cache store
|
34
|
+
I18n.backend.localize_text_tag = '##' # optional: specify an alternate localize text tag, the default is ^^
|
35
|
+
</code>
|
36
|
+
</pre>
|
37
|
+
|
38
|
+
In config/routes.rb to register admin panel routes
|
39
|
+
|
40
|
+
<pre>
|
41
|
+
<code>
|
42
|
+
map.from_plugin 'i18n_backend_database'
|
43
|
+
</code>
|
44
|
+
</pre>
|
45
|
+
|
46
|
+
h2. Use
|
47
|
+
|
48
|
+
All non-user generated text provided by the application needs to be wrapped in a call to I18n.t().
|
49
|
+
<pre>
|
50
|
+
<code>
|
51
|
+
I18n.t("Hello there!")
|
52
|
+
</code>
|
53
|
+
</pre>
|
54
|
+
|
55
|
+
Interpolation is handled by passing in key/value pairs as a value to an interpolation tag ( {{ }} ).
|
56
|
+
<pre>
|
57
|
+
<code>
|
58
|
+
I18n.t("Hello there {{name}}!", :name => "Dylan")
|
59
|
+
</code>
|
60
|
+
</pre><pre>
|
61
|
+
<code>
|
62
|
+
I18n.t("Click {{here}} or {{there}}", :here => "link_to(I18n.t('midnite'), croix_path)", :there => "link_to(I18n.t('staten_island'), wu_path)")
|
63
|
+
</code>
|
64
|
+
</pre>
|
65
|
+
|
66
|
+
Pluralization is handled by passing in a "count" key value pair, which is a unique interpolation value.
|
67
|
+
<pre>
|
68
|
+
<code>
|
69
|
+
I18n.t("You are {{count}} years old", :count => 100)
|
70
|
+
</code>
|
71
|
+
</pre>
|
72
|
+
|
73
|
+
Links to external documents that need to be translated should be tagged as well.
|
74
|
+
<pre>
|
75
|
+
<code>
|
76
|
+
I18n.t('http://www.elctech.com/core')
|
77
|
+
</code>
|
78
|
+
</pre>
|
79
|
+
|
80
|
+
All fragment cache view blocks need to have their keys prepended with the current locale.
|
81
|
+
<pre>
|
82
|
+
<code>
|
83
|
+
cache("#{I18n.locale}-footer_#{controller.action_name}")
|
84
|
+
</code>
|
85
|
+
</pre>
|
86
|
+
|
87
|
+
Date/Time localization is handled by using the I18n.l method. The format used will be :default (see next item for explanation).
|
88
|
+
<pre>
|
89
|
+
<code>
|
90
|
+
I18n.l(@user.joined_at)
|
91
|
+
</code>
|
92
|
+
</pre>
|
93
|
+
|
94
|
+
Date/Time localization can take a format parameter that corresponds to a key in the translations table (the Rails defaults :default, :short, and :long are available). We could in theory create our own like en.date.formats.espn_default.
|
95
|
+
<pre>
|
96
|
+
<code>
|
97
|
+
I18n.l(@user.joined_at, :format => :default)
|
98
|
+
I18n.l(@user.joined_at, :format => :short)
|
99
|
+
I18n.l(@user.joined_at, :format => :espn_default)
|
100
|
+
</code>
|
101
|
+
</pre>
|
102
|
+
|
103
|
+
Date/Time localization can take a custom format string as well.
|
104
|
+
<pre>
|
105
|
+
<code>
|
106
|
+
I18n.l(@user.joined_at, :format => "%B %e, %Y")
|
107
|
+
</code>
|
108
|
+
</pre>
|
109
|
+
|
110
|
+
Text stored in a database can be localized by tagging the text being stored and then localizing in the view etc.
|
111
|
+
<pre>
|
112
|
+
<code>
|
113
|
+
I18n.tlt("is now friends with") => "^^is now friends with^^"
|
114
|
+
I18n.lt("shane ^^is now friends with^^ dylan") => "shane ahora es con amigos dylan"
|
115
|
+
</code>
|
116
|
+
</pre>
|
117
|
+
|
118
|
+
Images can be translated with the I18n.ta tag
|
119
|
+
<pre>
|
120
|
+
<code>
|
121
|
+
<%= image_tag(I18n.ta("logos/elc.gif"), :size => "134x75") %>
|
122
|
+
</code>
|
123
|
+
</pre>
|
124
|
+
In this example, for a locale es, there should be an image: public/es/images/logos/elc.gif
|
125
|
+
|
data/data/locales.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class CreateI18nTables < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :locales do |t|
|
4
|
+
t.string :code
|
5
|
+
t.string :name
|
6
|
+
end
|
7
|
+
add_index :locales, :code
|
8
|
+
|
9
|
+
create_table :translations do |t|
|
10
|
+
t.string :key
|
11
|
+
t.text :raw_key
|
12
|
+
t.text :value
|
13
|
+
t.integer :pluralization_index, :default => 1
|
14
|
+
t.integer :locale_id
|
15
|
+
end
|
16
|
+
add_index :translations, [:locale_id, :key, :pluralization_index]
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.down
|
21
|
+
drop_table :locales
|
22
|
+
drop_table :translations
|
23
|
+
drop_table :asset_translations
|
24
|
+
end
|
25
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'i18n_backend_database'
|
@@ -0,0 +1,86 @@
|
|
1
|
+
class LocalesController < ActionController::Base
|
2
|
+
prepend_view_path(File.join(File.dirname(__FILE__), "..", "views"))
|
3
|
+
# GET /locales
|
4
|
+
# GET /locales.xml
|
5
|
+
def index
|
6
|
+
@locales = Locale.find(:all)
|
7
|
+
|
8
|
+
respond_to do |format|
|
9
|
+
format.html # index.html.erb
|
10
|
+
format.xml { render :xml => @locales }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /locales/1
|
15
|
+
# GET /locales/1.xml
|
16
|
+
def show
|
17
|
+
@locale = Locale.find_by_code(params[:id])
|
18
|
+
|
19
|
+
respond_to do |format|
|
20
|
+
format.html # show.html.erb
|
21
|
+
format.xml { render :xml => @locale }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# GET /locales/new
|
26
|
+
# GET /locales/new.xml
|
27
|
+
def new
|
28
|
+
@locale = Locale.new
|
29
|
+
|
30
|
+
respond_to do |format|
|
31
|
+
format.html # new.html.erb
|
32
|
+
format.xml { render :xml => @locale }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# GET /locales/1/edit
|
37
|
+
def edit
|
38
|
+
@locale = Locale.find_by_code(params[:id])
|
39
|
+
end
|
40
|
+
|
41
|
+
# POST /locales
|
42
|
+
# POST /locales.xml
|
43
|
+
def create
|
44
|
+
@locale = Locale.new(params[:locale])
|
45
|
+
|
46
|
+
respond_to do |format|
|
47
|
+
if @locale.save
|
48
|
+
flash[:notice] = 'Locale was successfully created.'
|
49
|
+
format.html { redirect_to(@locale) }
|
50
|
+
format.xml { render :xml => @locale, :status => :created, :location => @locale }
|
51
|
+
else
|
52
|
+
format.html { render :action => "new" }
|
53
|
+
format.xml { render :xml => @locale.errors, :status => :unprocessable_entity }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# PUT /locales/1
|
59
|
+
# PUT /locales/1.xml
|
60
|
+
def update
|
61
|
+
@locale = Locale.find_by_code(params[:id])
|
62
|
+
|
63
|
+
respond_to do |format|
|
64
|
+
if @locale.update_attributes(params[:locale])
|
65
|
+
flash[:notice] = 'Locale was successfully updated.'
|
66
|
+
format.html { redirect_to(@locale) }
|
67
|
+
format.xml { head :ok }
|
68
|
+
else
|
69
|
+
format.html { render :action => "edit" }
|
70
|
+
format.xml { render :xml => @locale.errors, :status => :unprocessable_entity }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# DELETE /locales/1
|
76
|
+
# DELETE /locales/1.xml
|
77
|
+
def destroy
|
78
|
+
@locale = Locale.find_by_code(params[:id])
|
79
|
+
@locale.destroy
|
80
|
+
|
81
|
+
respond_to do |format|
|
82
|
+
format.html { redirect_to(locales_url) }
|
83
|
+
format.xml { head :ok }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
class TranslationsController < ActionController::Base
|
2
|
+
prepend_view_path(File.join(File.dirname(__FILE__), "..", "views"))
|
3
|
+
layout 'translations'
|
4
|
+
before_filter :find_locale
|
5
|
+
|
6
|
+
## FIXME: you'll probably want add authorization to this controller!
|
7
|
+
|
8
|
+
# GET /translations
|
9
|
+
# GET /translations.xml
|
10
|
+
def index
|
11
|
+
@translations = @locale.translations.find(:all, :order => "raw_key, pluralization_index")
|
12
|
+
|
13
|
+
respond_to do |format|
|
14
|
+
format.html # index.html.erb
|
15
|
+
format.xml { render :xml => @translations }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /translations
|
20
|
+
# GET /translations.xml
|
21
|
+
def translations
|
22
|
+
@locale ||= Locale.default_locale
|
23
|
+
@translation_option = TranslationOption.find(params[:translation_option])
|
24
|
+
|
25
|
+
if @translation_option == TranslationOption.translated
|
26
|
+
@translations = @locale.translations.translated
|
27
|
+
else
|
28
|
+
@translations = @locale.translations.untranslated
|
29
|
+
end
|
30
|
+
|
31
|
+
respond_to do |format|
|
32
|
+
format.html # index.html.erb
|
33
|
+
format.xml { render :xml => @translations }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# GET /asset_translations
|
38
|
+
# GET /asset_translations.xml
|
39
|
+
def asset_translations
|
40
|
+
@locale ||= Locale.default_locale
|
41
|
+
@translation_option = TranslationOption.find(params[:translation_option])
|
42
|
+
|
43
|
+
@asset_translations = I18n.asset_translations
|
44
|
+
@untranslated_assets = I18n.untranslated_assets(@locale.code)
|
45
|
+
@percentage_translated = (((@asset_translations.size - @untranslated_assets.size).to_f / @asset_translations.size.to_f * 100).round) rescue 0
|
46
|
+
|
47
|
+
if @translation_option == TranslationOption.translated
|
48
|
+
@asset_translations = @asset_translations.reject{|e| @untranslated_assets.include?(e)}
|
49
|
+
else
|
50
|
+
@asset_translations = @untranslated_assets
|
51
|
+
end
|
52
|
+
|
53
|
+
respond_to do |format|
|
54
|
+
format.html # index.html.erb
|
55
|
+
format.xml { render :xml => @untranslated_assets }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# GET /translations/1
|
60
|
+
# GET /translations/1.xml
|
61
|
+
def show
|
62
|
+
@translation = @locale.translations.find(params[:id])
|
63
|
+
|
64
|
+
respond_to do |format|
|
65
|
+
format.html # show.html.erb
|
66
|
+
format.xml { render :xml => @translation }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# GET /translations/new
|
71
|
+
# GET /translations/new.xml
|
72
|
+
def new
|
73
|
+
@translation = Translation.new
|
74
|
+
|
75
|
+
respond_to do |format|
|
76
|
+
format.html # new.html.erb
|
77
|
+
format.xml { render :xml => @translation }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# GET /translations/1/edit
|
82
|
+
def edit
|
83
|
+
@translation = @locale.translations.find(params[:id])
|
84
|
+
end
|
85
|
+
|
86
|
+
# POST /translations
|
87
|
+
# POST /translations.xml
|
88
|
+
def create
|
89
|
+
@translation = @locale.translations.build(params[:translation])
|
90
|
+
|
91
|
+
respond_to do |format|
|
92
|
+
if @translation.save
|
93
|
+
flash[:notice] = 'Translation was successfully created.'
|
94
|
+
format.html { redirect_to locale_translation_path(@locale, @translation) }
|
95
|
+
format.xml { render :xml => @translation, :status => :created, :location => @translation }
|
96
|
+
else
|
97
|
+
format.html { render :action => "new" }
|
98
|
+
format.xml { render :xml => @translation.errors, :status => :unprocessable_entity }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# PUT /translations/1
|
104
|
+
# PUT /translations/1.xml
|
105
|
+
def update
|
106
|
+
@translation = @locale.translations.find(params[:id])
|
107
|
+
@first_time_translating = @translation.value.nil?
|
108
|
+
|
109
|
+
respond_to do |format|
|
110
|
+
if @translation.update_attributes(params[:translation])
|
111
|
+
format.html do
|
112
|
+
flash[:notice] = 'Translation was successfully updated.'
|
113
|
+
redirect_to locale_translation_path(@locale, @translation)
|
114
|
+
end
|
115
|
+
format.xml { head :ok }
|
116
|
+
format.js {}
|
117
|
+
else
|
118
|
+
format.html { render :action => "edit" }
|
119
|
+
format.xml { render :xml => @translation.errors, :status => :unprocessable_entity }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# DELETE /translations/1
|
125
|
+
# DELETE /translations/1.xml
|
126
|
+
def destroy
|
127
|
+
@translation = @locale.translations.find(params[:id])
|
128
|
+
@translation.destroy
|
129
|
+
|
130
|
+
respond_to do |format|
|
131
|
+
format.html { redirect_to(locale_translations_url) }
|
132
|
+
format.xml { head :ok }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def find_locale
|
139
|
+
@locale = Locale.find_by_code(params[:locale_id])
|
140
|
+
end
|
141
|
+
end
|
data/lib/ext/i18n.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module I18n
|
2
|
+
APP_DIRECTORY = 'app/views'
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def locale_segment
|
7
|
+
I18n.locale.to_s == I18n.default_locale.to_s ? "" : "/#{I18n.locale}"
|
8
|
+
end
|
9
|
+
alias :ls :locale_segment
|
10
|
+
|
11
|
+
def localize_text(text, options = {})
|
12
|
+
locale = options[:locale] || I18n.locale
|
13
|
+
backend.localize_text(locale, text)
|
14
|
+
end
|
15
|
+
alias :lt :localize_text
|
16
|
+
|
17
|
+
def tag_localized_text(text)
|
18
|
+
backend.localize_text_tag + text + backend.localize_text_tag
|
19
|
+
end
|
20
|
+
alias :tlt :tag_localized_text
|
21
|
+
|
22
|
+
def translate_asset(asset, options={})
|
23
|
+
locale = options.delete(:locale) || I18n.locale
|
24
|
+
if locale_asset = locale_asset(asset, locale)
|
25
|
+
locale_asset
|
26
|
+
else
|
27
|
+
asset
|
28
|
+
end
|
29
|
+
end
|
30
|
+
alias ta translate_asset
|
31
|
+
|
32
|
+
def untranslated_assets(locale)
|
33
|
+
return [] if locale.to_s == I18n.default_locale.to_s #default locale assets are assumed to exist
|
34
|
+
assets = asset_translations
|
35
|
+
assets.reject! {|asset| locale_asset_exists?(locale, asset) }
|
36
|
+
assets
|
37
|
+
end
|
38
|
+
|
39
|
+
def asset_translations(dir=APP_DIRECTORY)
|
40
|
+
assets = []
|
41
|
+
Dir.glob("#{dir}/*").each do |item|
|
42
|
+
if File.directory?(item)
|
43
|
+
assets += asset_translations(item)
|
44
|
+
else
|
45
|
+
File.readlines(item).each do |l|
|
46
|
+
assets += l.scan(/I18n.ta\(["'](.*?)["']\)/).flatten
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
assets.uniq
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def locale_asset_exists?(locale, asset)
|
56
|
+
File.exists?("#{ActionView::Helpers::AssetTagHelper::ASSETS_DIR}/#{locale}#{asset_path(asset)}")
|
57
|
+
end
|
58
|
+
|
59
|
+
def locale_asset(asset, locale)
|
60
|
+
locale_asset_exists?(locale, asset) ? "/#{locale}#{asset_path(asset)}" : nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def asset_path(asset)
|
64
|
+
asset[0] == ?/ ? asset : "/images/#{asset}"
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|