weeler 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/README.md +4 -0
- data/app/.DS_Store +0 -0
- data/app/assets/.DS_Store +0 -0
- data/app/assets/javascripts/.DS_Store +0 -0
- data/app/assets/javascripts/weeler.js.coffee +8 -0
- data/app/assets/javascripts/weeler/.DS_Store +0 -0
- data/app/assets/javascripts/weeler/bootstrap-fileupload.js +169 -0
- data/app/assets/javascripts/weeler/bootstrap.js +1992 -0
- data/app/assets/javascripts/weeler/bootstrap.rowlink.js +71 -0
- data/app/assets/javascripts/weeler/bootstrap.switch.js +382 -0
- data/app/assets/javascripts/weeler/jquery.pnotify.js +912 -0
- data/app/assets/stylesheets/.DS_Store +0 -0
- data/app/assets/stylesheets/weeler.css +9 -0
- data/app/assets/stylesheets/weeler/.DS_Store +0 -0
- data/app/assets/stylesheets/weeler/bootstrap-fileupload.css +132 -0
- data/app/assets/stylesheets/weeler/bootstrap.css +6086 -0
- data/app/assets/stylesheets/weeler/bootstrap.min.css +9 -0
- data/app/assets/stylesheets/weeler/bootstrap.rowlink.css +50 -0
- data/app/assets/stylesheets/weeler/bootstrap.spinner.css +43 -0
- data/app/assets/stylesheets/weeler/bootstrap.switch.css +408 -0
- data/app/assets/stylesheets/weeler/jquery.pnotify.css +84 -0
- data/app/assets/stylesheets/weeler/style.css.scss.erb +48 -0
- data/app/controllers/weeler/base_controller.rb +16 -0
- data/app/controllers/weeler/home_controller.rb +8 -0
- data/app/controllers/weeler/translations_controller.rb +151 -0
- data/app/views/kaminari/_first_page.html.erb +13 -0
- data/app/views/kaminari/_gap.html.erb +8 -0
- data/app/views/kaminari/_last_page.html.erb +13 -0
- data/app/views/kaminari/_next_page.html.erb +14 -0
- data/app/views/kaminari/_page.html.erb +12 -0
- data/app/views/kaminari/_paginator.html.erb +23 -0
- data/app/views/kaminari/_prev_page.html.erb +13 -0
- data/app/views/layouts/weeler/base.html.erb +86 -0
- data/app/views/weeler/home/about.html.erb +16 -0
- data/app/views/weeler/home/index.html.erb +4 -0
- data/app/views/weeler/translations/_form.html.erb +43 -0
- data/app/views/weeler/translations/_translation.html.erb +11 -0
- data/app/views/weeler/translations/edit.html.erb +19 -0
- data/app/views/weeler/translations/index.html.erb +106 -0
- data/app/views/weeler/translations/new.html.erb +19 -0
- data/config/initializers/weeler_mime_types.rb +1 -0
- data/lib/.DS_Store +0 -0
- data/lib/generators/weeler/.DS_Store +0 -0
- data/lib/generators/weeler/install_generator.rb +73 -0
- data/lib/generators/weeler/templates/initializers/weeler.rb +7 -0
- data/lib/generators/weeler/templates/migrations/create_weeler_translations.rb +16 -0
- data/lib/i18n/.DS_Store +0 -0
- data/lib/i18n/backend/.DS_Store +0 -0
- data/lib/i18n/backend/weeler.rb +76 -0
- data/lib/i18n/backend/weeler/store_procs.rb +39 -0
- data/lib/i18n/backend/weeler/translation.rb +118 -0
- data/lib/i18n/humanize_missing_translations.rb +11 -0
- data/lib/i18n/weeler.rb +6 -0
- data/lib/weeler.rb +25 -1
- data/lib/weeler/.DS_Store +0 -0
- data/lib/weeler/engine.rb +11 -0
- data/lib/weeler/route_mapper.rb +41 -0
- data/lib/weeler/version.rb +1 -1
- data/rspec.html +454 -0
- data/spec/.DS_Store +0 -0
- data/spec/controllers/translations_controller_spec.rb +41 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/weeler/posts_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +23 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/weeler.rb +2 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20131015144900_create_weeler_translations.rb +16 -0
- data/spec/dummy/db/production.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +29 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/log/development.log +19 -0
- data/spec/dummy/log/production.log +4 -0
- data/spec/dummy/log/test.log +38396 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/translations.rb +7 -0
- data/spec/routing/routes_spec.rb +140 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/weeler/.DS_Store +0 -0
- data/spec/weeler/i18n_backend_weeler_spec.rb +169 -0
- data/spec/weeler/i18n_humanize_missing_translations_spec.rb +18 -0
- data/weeler.gemspec +14 -0
- metadata +354 -3
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class="row">
|
2
|
+
<div class="col-12-lg">
|
3
|
+
<h2>About</h2>
|
4
|
+
<h3>History</h3>
|
5
|
+
<p>In late 2013 Arturs and Artis decided to make CMS for programmers. Arturs built first prototype on Ruby in few weeks and they implemented Weeler in few projects.</p>
|
6
|
+
<h3>Now</h3>
|
7
|
+
<p>Weeler is the most popular and the most powerful CMS system today.</p>
|
8
|
+
<h3>Technology</h3>
|
9
|
+
<ul>
|
10
|
+
<li>Ruby</li>
|
11
|
+
<li>on Rails - most advanced MVC framework</li>
|
12
|
+
<li>RSpec for testing</li>
|
13
|
+
<li>Bundler for dependencies</li>
|
14
|
+
</ul>
|
15
|
+
</div>
|
16
|
+
</div>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<%= form_for translation, {url: weeler_translation_path(translation), html: {class: "form-horizontal", role: "form"}} do |f| %>
|
2
|
+
<h4>Basic (required)</h4>
|
3
|
+
<div class="form-group">
|
4
|
+
<label class="col-lg-2 col-md-2 control-label">Locale</label>
|
5
|
+
<div class="col-lg-10 col-md-10">
|
6
|
+
<%= f.text_field :locale, {class: "form-control", placeholder: "en"} %>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
<div class="form-group">
|
10
|
+
<label class="col-lg-2 col-md-2 control-label">Key</label>
|
11
|
+
<div class="col-lg-10 col-md-10">
|
12
|
+
<%= f.text_field :key, {class: "form-control", placeholder: "footer.middle"} %>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
<div class="form-group">
|
16
|
+
<label class="col-lg-2 col-md-2 control-label">Value</label>
|
17
|
+
<div class="col-lg-10 col-md-10">
|
18
|
+
<%= f.text_area :value, {class: "form-control"} %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<h4>Ext</h4>
|
22
|
+
|
23
|
+
<div class="form-group">
|
24
|
+
<label class="col-lg-2 col-md-2 control-label">Interpolations</label>
|
25
|
+
<div class="col-lg-10 col-md-10">
|
26
|
+
<p class="form-control-static">
|
27
|
+
<label><%= translation.interpolations.join(", ") %></label>
|
28
|
+
</p>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<div class="form-group">
|
33
|
+
<label class="col-lg-2 col-md-2 control-label">Is procedure?</label>
|
34
|
+
<div class="col-lg-4 col-md-4">
|
35
|
+
<%= f.select :is_proc, {"No" => false, "Yes" => true}, {}, {class: "form-control"} %>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
<p class="text-center">
|
39
|
+
<button type="submit" class="btn btn-primary">Save</button>
|
40
|
+
<a class="btn btn-link" href="<%= weeler_translations_path %>">Cancel</a>
|
41
|
+
<%= link_to 'Remove', weeler_translation_path(translation), :confirm => "Are you sure you want remove?", :method => :delete, :class => "btn btn-danger" %>
|
42
|
+
</p>
|
43
|
+
<% end %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<tr>
|
2
|
+
<td>
|
3
|
+
<a href="<%= edit_weeler_translation_path(translation.id) %>">
|
4
|
+
<%= translation.locale %>
|
5
|
+
</a>
|
6
|
+
</td>
|
7
|
+
<td><%= translation.key %></a></td>
|
8
|
+
<td><%= translation.value %></a></td>
|
9
|
+
<td><%= translation.interpolations %></a></td>
|
10
|
+
<td class="text-center"><%= translation.created_at.strftime("%d/%m/%Y") %></td>
|
11
|
+
</tr>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div class="header container">
|
2
|
+
<div class="row">
|
3
|
+
<div class="col-lg-12 col-md-12">
|
4
|
+
<div class="page-header">
|
5
|
+
<h1>Edit translation</h1>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="edit_user container">
|
12
|
+
<div class="row">
|
13
|
+
<div class="col-lg-12 col-md-12">
|
14
|
+
|
15
|
+
<%= render partial: "form", locals: {translation: @translation} %>
|
16
|
+
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
</div>
|
@@ -0,0 +1,106 @@
|
|
1
|
+
<div class="header container">
|
2
|
+
<div class="row">
|
3
|
+
<div class="col-lg-12">
|
4
|
+
<div class="page-header">
|
5
|
+
<h1>Translations</h1>
|
6
|
+
<p class="lead text-muted">Statis translation data over all your app. You can safely edit translation values. Also you can export excel document, translate in all locales you need and import it back.</p>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div class="row">
|
14
|
+
<nav class="navbar navbar-default" role="navigation">
|
15
|
+
|
16
|
+
<!-- Collect the nav links, forms, and other content for toggling -->
|
17
|
+
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
18
|
+
|
19
|
+
<!-- Groups dropdown -->
|
20
|
+
<ul class="nav navbar-nav navbar-left">
|
21
|
+
<li class="dropdown">
|
22
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><%= (params[:group].capitalize if params[:group]) || "All groups" %> <b class="caret"></b></a>
|
23
|
+
<ul class="dropdown-menu">
|
24
|
+
<li><a href="<%= weeler_translations_path(locale: params[:locale]) %>">All</a></li>
|
25
|
+
<% @groups.each do |group| %>
|
26
|
+
<% if group.present? %>
|
27
|
+
<li><a href="<%= weeler_translations_path(locale: params[:locale], group: group) %>"><%= group.capitalize %></a></li>
|
28
|
+
<% end %>
|
29
|
+
<% end %>
|
30
|
+
</ul>
|
31
|
+
</li>
|
32
|
+
</ul>
|
33
|
+
|
34
|
+
<!-- Locales dropdown -->
|
35
|
+
<ul class="nav navbar-nav">
|
36
|
+
<li class="dropdown">
|
37
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><%= (params[:locale].capitalize if params[:locale]) || "All locales" %> <b class="caret"></b></a>
|
38
|
+
<ul class="dropdown-menu">
|
39
|
+
<li><a href="<%= weeler_translations_path(group: params[:group]) %>">All</a></li>
|
40
|
+
<% I18n::Backend::Weeler::Translation.available_locales.each do |locale| %>
|
41
|
+
<% if locale.present? %>
|
42
|
+
<li><a href="<%= weeler_translations_path(group: params[:group], locale: locale) %>"><%= locale.capitalize %></a></li>
|
43
|
+
<% end %>
|
44
|
+
<% end %>
|
45
|
+
</ul>
|
46
|
+
</li>
|
47
|
+
</ul>
|
48
|
+
|
49
|
+
<!-- Import and export data -->
|
50
|
+
<form class="navbar-form navbar-left" role="import" method="post" action="<%= import_weeler_translations_path %>" enctype="multipart/form-data">
|
51
|
+
<%= form_tag import_weeler_translations_path, {:multipart => true, class: "navbar-form navbar-left"} do %>
|
52
|
+
<div class="form-group fileupload fileupload-new" data-provides="fileupload">
|
53
|
+
<span class="btn btn-file"><span class="fileupload-new">Select file</span><span class="fileupload-exists">Change</span><input type="file" name="file" /></span>
|
54
|
+
<span class="fileupload-preview"></span>
|
55
|
+
<a href="#" class="close fileupload-exists" data-dismiss="fileupload" style="float: none">×</a>
|
56
|
+
</div>
|
57
|
+
<div class="btn-group">
|
58
|
+
<button type="submit" class="btn btn-default">Import</button>
|
59
|
+
<a class="btn btn-default" href="<%= export_weeler_translations_path(locale: params[:locale], group: params[:group], format: :xlsx) %>">Export</a>
|
60
|
+
</div>
|
61
|
+
<% end %>
|
62
|
+
|
63
|
+
<!-- Search -->
|
64
|
+
<%= form_tag weeler_translations_path, method: 'get', class: "navbar-form navbar-right", role: "search" do %>
|
65
|
+
<%= hidden_field_tag :locale, params[:locale] if params[:locale].present? %>
|
66
|
+
<%= hidden_field_tag :group, params[:group] if params[:group].present? %>
|
67
|
+
<div class="form-group">
|
68
|
+
<%= text_field_tag :query, params[:query], class: "form-control", placeholder: "Search" %>
|
69
|
+
</div>
|
70
|
+
<button type="submit" class="btn btn-default">Submit</button>
|
71
|
+
<% end %>
|
72
|
+
|
73
|
+
</div><!-- /.navbar-collapse -->
|
74
|
+
</nav>
|
75
|
+
</div>
|
76
|
+
|
77
|
+
<div class="container">
|
78
|
+
<div class="row">
|
79
|
+
<div class="col-lg-12">
|
80
|
+
<table class="table table-hover" data-provides="rowlink">
|
81
|
+
<thead>
|
82
|
+
<tr>
|
83
|
+
<th>Locale</th>
|
84
|
+
<th>Key</th>
|
85
|
+
<th class="text-center">Value</th>
|
86
|
+
<th class="text-center">Interpolations</th>
|
87
|
+
<th class="text-center">Created</th>
|
88
|
+
</tr>
|
89
|
+
</thead>
|
90
|
+
<tbody id="translations">
|
91
|
+
<% @translations.each do |translation| %>
|
92
|
+
<%= render :partial => "weeler/translations/translation", locals: {translation: translation} %>
|
93
|
+
<% end %>
|
94
|
+
</tbody>
|
95
|
+
</table>
|
96
|
+
</div>
|
97
|
+
</div>
|
98
|
+
</div>
|
99
|
+
|
100
|
+
<div class="container">
|
101
|
+
<div class="row">
|
102
|
+
<div class="col-lg-12">
|
103
|
+
<%= paginate @translations, params: {controller: "weeler/translations", action: "index", locale: params[:locale], group: params[:group] }, previous_label: "<<", next_label: ">>" %>
|
104
|
+
</div>
|
105
|
+
</div>
|
106
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div class="header container">
|
2
|
+
<div class="row">
|
3
|
+
<div class="col-lg-12 col-md-12">
|
4
|
+
<div class="page-header">
|
5
|
+
<h1>New translation</h1>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="edit_user container">
|
12
|
+
<div class="row">
|
13
|
+
<div class="col-lg-12 col-md-12">
|
14
|
+
|
15
|
+
<%= render partial: "form", locals: {translation: @translation} %>
|
16
|
+
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
Mime::Type.register( 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', :xlsx )
|
data/lib/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
require 'rails/generators/active_record'
|
4
|
+
|
5
|
+
module Weeler
|
6
|
+
module Generators
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
8
|
+
include Rails::Generators::Migration
|
9
|
+
|
10
|
+
def self.next_migration_number(path)
|
11
|
+
unless @prev_migration_nr
|
12
|
+
@prev_migration_nr = ActiveRecord::Generators::Base.next_migration_number(path).to_i
|
13
|
+
else
|
14
|
+
@prev_migration_nr += 1
|
15
|
+
end
|
16
|
+
|
17
|
+
@prev_migration_nr.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
source_root File.expand_path('../templates', __FILE__)
|
21
|
+
|
22
|
+
def install_initializer
|
23
|
+
copy_files 'initializers', 'config/initializers'
|
24
|
+
end
|
25
|
+
|
26
|
+
def install_migrations
|
27
|
+
get_file_list('migrations').each do |migration|
|
28
|
+
migration_template "migrations/#{migration}", "db/migrate/#{migration}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#def install_models
|
33
|
+
# copy_files 'models', 'app/models'
|
34
|
+
#end
|
35
|
+
|
36
|
+
#def install_views
|
37
|
+
# copy_files 'views', 'app/views'
|
38
|
+
#end
|
39
|
+
|
40
|
+
#def install_controllers
|
41
|
+
# copy_files 'controllers', 'app/controllers'
|
42
|
+
#end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def copy_files subdir, dest_dir
|
47
|
+
raise ArgumEnterror unless subdir.is_a? String
|
48
|
+
raise ArgumEnterror unless dest_dir.is_a? String
|
49
|
+
raise ArgumetnError if subdir.blank?
|
50
|
+
raise ArgumetnError if dest_dir.blank?
|
51
|
+
|
52
|
+
get_file_list(subdir).each do |image|
|
53
|
+
copy_file [subdir, image].join('/'), [dest_dir, image].join('/')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_file_list subdir
|
58
|
+
raise ArgumentError unless subdir.is_a? String
|
59
|
+
raise ArgumetnError if subdir.blank?
|
60
|
+
dir = get_current_dir
|
61
|
+
search_path = [dir, 'templates', subdir].join('/') + '/'
|
62
|
+
file_list = Dir.glob(search_path + '**/*').map { |filename| File.directory?(filename) ? nil : filename.sub(search_path, '') }
|
63
|
+
file_list.delete nil
|
64
|
+
return file_list
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_current_dir
|
68
|
+
File.dirname(__FILE__)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateWeelerTranslations < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :weeler_translations do |t|
|
4
|
+
t.string :locale
|
5
|
+
t.string :key
|
6
|
+
t.text :value
|
7
|
+
t.text :interpolations
|
8
|
+
t.boolean :is_proc, :default => false
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :weeler_translations, :locale
|
14
|
+
add_index :weeler_translations, :key
|
15
|
+
end
|
16
|
+
end
|
data/lib/i18n/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'i18n/backend/base'
|
2
|
+
require 'i18n/backend/weeler/translation'
|
3
|
+
|
4
|
+
module I18n
|
5
|
+
module Backend
|
6
|
+
class Weeler
|
7
|
+
PLURAL_KEYS = ["zero", "one", "other"]
|
8
|
+
|
9
|
+
autoload :StoreProcs, 'i18n/backend/weeler/store_procs'
|
10
|
+
autoload :Translation, 'i18n/backend/weeler/translation'
|
11
|
+
|
12
|
+
module Implementation
|
13
|
+
include Base, Flatten
|
14
|
+
|
15
|
+
def available_locales
|
16
|
+
begin
|
17
|
+
Translation.available_locales
|
18
|
+
rescue ::ActiveRecord::StatementInvalid
|
19
|
+
[]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def store_translations(locale, data, options = {})
|
24
|
+
escape = options.fetch(:escape, true)
|
25
|
+
flatten_translations(locale, data, escape, false).each do |key, value|
|
26
|
+
Translation.locale(locale).lookup(expand_keys(key)).delete_all
|
27
|
+
Translation.create(:locale => locale.to_s, :key => key.to_s, :value => value)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def lookup(locale, key, scope = [], options = {})
|
34
|
+
key = normalize_flat_keys(locale, key, scope, options[:separator])
|
35
|
+
result = Translation.locale(locale).lookup(key).load
|
36
|
+
|
37
|
+
if result.empty?
|
38
|
+
if ::Weeler.create_missing_translations
|
39
|
+
interpolations = options.keys - I18n::RESERVED_KEYS
|
40
|
+
keys = options[:count] ? PLURAL_KEYS.map { |k| [key, k].join(FLATTEN_SEPARATOR) } : [key]
|
41
|
+
keys.each { |key| store_translation(locale, key, interpolations) }
|
42
|
+
end
|
43
|
+
nil
|
44
|
+
elsif result.first.key == key
|
45
|
+
result.first.value
|
46
|
+
else
|
47
|
+
chop_range = (key.size + FLATTEN_SEPARATOR.size)..-1
|
48
|
+
result = result.inject({}) do |hash, r|
|
49
|
+
hash[r.key.slice(chop_range)] = r.value
|
50
|
+
hash
|
51
|
+
end
|
52
|
+
result.deep_symbolize_keys
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz']
|
57
|
+
def expand_keys(key)
|
58
|
+
key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, key|
|
59
|
+
keys << [keys.last, key].compact.join(FLATTEN_SEPARATOR)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Store single empty translation
|
64
|
+
def store_translation(locale, key, interpolations)
|
65
|
+
translation = Weeler::Translation.new :locale => locale.to_s, :key => key
|
66
|
+
translation.interpolations = interpolations
|
67
|
+
translation.save
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
include Implementation
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# This module is intended to be mixed into the Weeler backend to allow
|
2
|
+
# storing Ruby Procs as translation values in the database.
|
3
|
+
#
|
4
|
+
# I18n.backend = I18n::Backend::Weeler.new
|
5
|
+
# I18n::Backend::Weeler::Translation.send(:include, I18n::Backend::Weeler::StoreProcs)
|
6
|
+
#
|
7
|
+
# The StoreProcs module requires the ParseTree and ruby2ruby gems and therefor
|
8
|
+
# was extracted from the original backend.
|
9
|
+
#
|
10
|
+
# ParseTree is not compatible with Ruby 1.9.
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'ruby2ruby'
|
14
|
+
require 'parse_tree'
|
15
|
+
require 'parse_tree_extensions'
|
16
|
+
rescue LoadError => e
|
17
|
+
puts "can't use StoreProcs because: #{e.message}"
|
18
|
+
end
|
19
|
+
|
20
|
+
module I18n
|
21
|
+
module Backend
|
22
|
+
class Weeler
|
23
|
+
module StoreProcs
|
24
|
+
def value=(v)
|
25
|
+
case v
|
26
|
+
when Proc
|
27
|
+
write_attribute(:value, v.to_ruby)
|
28
|
+
write_attribute(:is_proc, true)
|
29
|
+
else
|
30
|
+
write_attribute(:value, v)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Translation.send(:include, self) if method(:to_s).respond_to?(:to_ruby)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|