ab_admin 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Guardfile +1 -1
- data/app/assets/images/admin/flags/b_uk.png +0 -0
- data/app/assets/images/admin/preloader.gif +0 -0
- data/app/assets/javascripts/ab_admin/application.js +1 -28
- data/app/assets/javascripts/ab_admin/components/admin_assets.js.coffee +29 -6
- data/app/assets/javascripts/ab_admin/components/gmaps.js.coffee +120 -91
- data/app/assets/javascripts/ab_admin/components/google_translate.js.coffee +3 -2
- data/app/assets/javascripts/ab_admin/core/batch_actions.js.coffee +4 -7
- data/app/assets/javascripts/ab_admin/core/init.js.coffee +8 -10
- data/app/assets/javascripts/ab_admin/core/ui_utils.js.coffee +53 -24
- data/app/assets/javascripts/ab_admin/core/utils.js.coffee +7 -0
- data/app/assets/javascripts/ab_admin/inputs/datetime_input.js.coffee +1 -2
- data/app/assets/javascripts/ab_admin/main.js +28 -0
- data/app/assets/stylesheets/ab_admin/application.css.scss +1 -10
- data/app/assets/stylesheets/ab_admin/bootstrap_and_overrides.css.scss +4 -0
- data/app/assets/stylesheets/ab_admin/components/_base.css.scss +4 -1
- data/app/assets/stylesheets/ab_admin/components/_form.css.scss +10 -13
- data/app/assets/stylesheets/ab_admin/components/_geo_input.css.scss +5 -9
- data/app/assets/stylesheets/ab_admin/fileupload.css.scss +68 -102
- data/app/assets/stylesheets/ab_admin/main.css.scss +8 -0
- data/app/controllers/admin/base_controller.rb +18 -14
- data/app/controllers/admin/manager_controller.rb +51 -6
- data/app/controllers/admin/users_controller.rb +23 -0
- data/app/views/admin/fileupload/_asset.html.slim +8 -0
- data/app/views/admin/fileupload/_container.html.slim +10 -0
- data/app/views/admin/fileupload/_file.html.slim +5 -0
- data/app/views/admin/fileupload/_ftmpl.html.slim +6 -0
- data/app/views/admin/fileupload/_tmpl.html.slim +9 -0
- data/app/views/admin/users/_form.html.slim +1 -0
- data/config/locales/en.yml +5 -60
- data/config/locales/ru.yml +14 -63
- data/config/routes.rb +7 -4
- data/features/dsl/custom_actions.feature +62 -0
- data/features/dsl/parent_resource.feature +18 -0
- data/features/step_definitions/configuration_steps.rb +6 -0
- data/features/step_definitions/dsl/parent_resource_steps.rb +8 -0
- data/features/step_definitions/settings_steps.rb +1 -1
- data/features/step_definitions/web_steps/transforms_steps.rb +3 -0
- data/features/support/paths.rb +3 -0
- data/lib/ab_admin.rb +5 -0
- data/lib/ab_admin/abstract_resource.rb +28 -4
- data/lib/ab_admin/carrierwave/base_uploader.rb +22 -22
- data/lib/ab_admin/concerns/admin_addition.rb +2 -2
- data/lib/ab_admin/concerns/utilities.rb +4 -4
- data/lib/ab_admin/config/base.rb +18 -0
- data/lib/ab_admin/controllers/head_options.rb +1 -1
- data/lib/ab_admin/core_ext/array.rb +4 -0
- data/lib/ab_admin/core_ext/string.rb +9 -10
- data/lib/ab_admin/hooks/quiet_scope_page.rb +16 -16
- data/lib/ab_admin/hooks/simple_form_hooks.rb +13 -13
- data/lib/ab_admin/i18n_tools/model_translator.rb +67 -0
- data/lib/ab_admin/models/asset.rb +32 -1
- data/lib/ab_admin/models/attachment_file.rb +1 -1
- data/lib/ab_admin/models/locator.rb +7 -0
- data/lib/ab_admin/models/settings.rb +7 -0
- data/lib/ab_admin/models/structure.rb +4 -0
- data/lib/ab_admin/utils.rb +2 -2
- data/lib/ab_admin/version.rb +1 -1
- data/lib/ab_admin/views/admin_helpers.rb +3 -3
- data/lib/ab_admin/views/admin_navigation_helpers.rb +1 -1
- data/lib/ab_admin/views/form_builder.rb +42 -39
- data/lib/ab_admin/views/helpers.rb +5 -0
- data/lib/ab_admin/views/manager_helpers.rb +10 -0
- data/lib/ab_admin/views/search_form_builder.rb +12 -5
- data/lib/generators/ab_admin/install/install_generator.rb +1 -1
- data/lib/generators/ab_admin/install/templates/config/admin_menu.rb +2 -2
- data/lib/generators/ab_admin/install/templates/helpers/admin/structures_helper.rb +1 -1
- data/lib/generators/ab_admin/install/templates/models/attachment_file.rb +2 -0
- data/lib/generators/ab_admin/install/templates/models/locator.rb +0 -1
- data/lib/generators/ab_admin/install/templates/models/settings.rb +0 -1
- data/lib/generators/ab_admin/install/templates/models/static_page.rb +1 -0
- data/lib/generators/ab_admin/install/templates/{scripts → script}/unicorn.sh +0 -0
- data/lib/generators/ab_admin/install/templates/uploaders/avatar_uploader.rb +4 -0
- data/lib/generators/ab_admin/resource/templates/_search_form.haml.erb +1 -1
- data/lib/generators/ab_admin/resource/templates/_search_form.slim.erb +1 -1
- data/lib/generators/ab_admin/resource/templates/_table.haml.erb +1 -2
- data/lib/generators/ab_admin/resource/templates/_table.slim.erb +1 -2
- data/lib/generators/template.rb +1 -0
- data/lib/tasks/i18n.rake +7 -0
- data/spec/dummy/app/models/ab_admin/ab_admin_collection.rb +35 -0
- data/spec/dummy/app/models/ab_admin/ab_admin_product.rb +2 -0
- data/spec/dummy/app/models/admin_menu.rb +4 -2
- data/spec/dummy/app/models/collection.rb +3 -1
- data/spec/generators/install_generator_spec.rb +1 -1
- data/spec/generators/resource_generator_spec.rb +1 -1
- data/spec/models/avatar_spec.rb +29 -2
- metadata +25 -12
- data/app/views/admin/fileupload/_asset.html.erb +0 -5
- data/app/views/admin/fileupload/_container.html.erb +0 -28
- data/app/views/admin/fileupload/_fcontainer.html.erb +0 -25
- data/app/views/admin/fileupload/_file.html.erb +0 -5
- data/app/views/admin/fileupload/_ftmpl.html.erb +0 -7
- data/app/views/admin/fileupload/_tmpl.html.erb +0 -9
- data/lib/ab_admin/utils/csv_builder.rb +0 -52
@@ -4,10 +4,11 @@ module AbAdmin
|
|
4
4
|
|
5
5
|
include Singleton
|
6
6
|
|
7
|
-
ACTIONS = [:index, :show, :new, :edit, :create, :update, :destroy, :preview, :batch, :rebuild] unless self.const_defined?(:ACTIONS)
|
7
|
+
ACTIONS = [:index, :show, :new, :edit, :create, :update, :destroy, :preview, :batch, :rebuild, :custom_action] unless self.const_defined?(:ACTIONS)
|
8
8
|
|
9
9
|
attr_accessor :table, :search, :export, :form, :show, :preview_path, :actions, :settings, :custom_settings,
|
10
|
-
:batch_action_list, :action_items, :disabled_action_items, :resource_action_items, :tree_node_renderer
|
10
|
+
:batch_action_list, :action_items, :disabled_action_items, :resource_action_items, :tree_node_renderer,
|
11
|
+
:parent_resources, :custom_actions
|
11
12
|
|
12
13
|
def initialize
|
13
14
|
@actions = ACTIONS
|
@@ -16,6 +17,8 @@ module AbAdmin
|
|
16
17
|
@disabled_action_items = []
|
17
18
|
@default_action_items_for = {}
|
18
19
|
@action_items_for = {}
|
20
|
+
@parent_resources = []
|
21
|
+
@custom_actions = []
|
19
22
|
@model = self.class.name.sub('AbAdmin', '').safe_constantize
|
20
23
|
add_admin_addition_to_model
|
21
24
|
end
|
@@ -57,7 +60,7 @@ module AbAdmin
|
|
57
60
|
ACTIONS - Array(options[:except]).map(&:to_sym)
|
58
61
|
else
|
59
62
|
actions_to_keep
|
60
|
-
end
|
63
|
+
end << :custom_action
|
61
64
|
end.map(&:to_sym)
|
62
65
|
end
|
63
66
|
|
@@ -93,6 +96,21 @@ module AbAdmin
|
|
93
96
|
def tree(&block)
|
94
97
|
instance.tree_node_renderer = block
|
95
98
|
end
|
99
|
+
|
100
|
+
def belongs_to(*args)
|
101
|
+
options = args.extract_options!
|
102
|
+
args.each do |name|
|
103
|
+
instance.parent_resources << OpenStruct.new(:name => name, :options => options)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def member_action(name, options={}, &block)
|
108
|
+
instance.custom_actions << AbAdmin::Config::CustomAction.new(name, options, &block)
|
109
|
+
end
|
110
|
+
|
111
|
+
def collection_action(name, options={}, &block)
|
112
|
+
instance.custom_actions << AbAdmin::Config::CustomAction.new(name, options.merge(:collection => true), &block)
|
113
|
+
end
|
96
114
|
end
|
97
115
|
|
98
116
|
def export
|
@@ -118,7 +136,13 @@ module AbAdmin
|
|
118
136
|
end
|
119
137
|
|
120
138
|
def resource_action_items
|
121
|
-
@resource_action_items ||= [:edit, :show, :destroy, :preview]
|
139
|
+
@resource_action_items ||= [:edit, :show, :destroy, :preview] & @actions
|
140
|
+
end
|
141
|
+
|
142
|
+
def custom_action_for(name, context)
|
143
|
+
custom_action = @custom_actions.detect { |a| a.name == name.to_sym }
|
144
|
+
raise "No allowed custom action found #{name}" if !custom_action || !custom_action.for_context?(context)
|
145
|
+
custom_action
|
122
146
|
end
|
123
147
|
|
124
148
|
end
|
@@ -10,24 +10,24 @@ module AbAdmin
|
|
10
10
|
include ::CarrierWave::MiniMagick
|
11
11
|
include ::CarrierWave::MimeTypes
|
12
12
|
include AbAdmin::Utils::EvalHelpers
|
13
|
-
|
13
|
+
|
14
14
|
storage :file
|
15
|
-
|
15
|
+
|
16
16
|
process :set_content_type
|
17
|
-
|
17
|
+
|
18
18
|
with_options :if => :image? do |img|
|
19
19
|
img.process :strip
|
20
20
|
img.process :cropper => lambda { |model| model.cropper_geometry }
|
21
21
|
img.process :rotate => lambda { |model| model.rotate_degrees }
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
process :set_model_info
|
25
|
-
|
26
|
-
# default store assets path
|
25
|
+
|
26
|
+
# default store assets path
|
27
27
|
def store_dir
|
28
28
|
"uploads/#{model.class.to_s.underscore}/#{model.id}"
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
# Strips out all embedded information from the image
|
32
32
|
# process :strip
|
33
33
|
#
|
@@ -38,13 +38,13 @@ module AbAdmin
|
|
38
38
|
img
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# Reduces the quality of the image to the percentage given
|
43
43
|
# process :quality => 85
|
44
44
|
#
|
45
45
|
def quality(percentage)
|
46
46
|
percentage = normalize_param(percentage)
|
47
|
-
|
47
|
+
|
48
48
|
unless percentage.blank?
|
49
49
|
manipulate! do |img|
|
50
50
|
img.quality(percentage.to_s)
|
@@ -53,13 +53,13 @@ module AbAdmin
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
# Rotate image by degress
|
58
58
|
# process :rotate => "-90"
|
59
59
|
#
|
60
60
|
def rotate(degrees = nil)
|
61
61
|
degrees = normalize_param(degrees)
|
62
|
-
|
62
|
+
|
63
63
|
unless degrees.blank?
|
64
64
|
manipulate! do |img|
|
65
65
|
img.rotate(degrees.to_s)
|
@@ -68,7 +68,7 @@ module AbAdmin
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# Crop image by specific coordinates
|
73
73
|
# http://www.imagemagick.org/script/command-line-processing.php?ImageMagick=6ddk6c680muj4eu2vr54vdveb7#geometry
|
74
74
|
# process :cropper => [size, offset]
|
@@ -76,7 +76,7 @@ module AbAdmin
|
|
76
76
|
#
|
77
77
|
def cropper(*geometry)
|
78
78
|
geometry = normalize_param(geometry[0]) if geometry.size == 1
|
79
|
-
|
79
|
+
|
80
80
|
if geometry && geometry.size == 4
|
81
81
|
manipulate! do |img|
|
82
82
|
img.crop '%ix%i+%i+%i' % geometry
|
@@ -86,10 +86,10 @@ module AbAdmin
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
def watermark(path_to_file)
|
89
|
+
def watermark(path_to_file, gravity='SouthEast')
|
90
90
|
manipulate! do |img|
|
91
91
|
logo = ::MiniMagick::Image.open(path_to_file)
|
92
|
-
img.composite(logo) { |c| c.gravity
|
92
|
+
img.composite(logo) { |c| c.gravity gravity }
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
@@ -97,31 +97,31 @@ module AbAdmin
|
|
97
97
|
image_name = [model.class.to_s.underscore, version_name].compact.join('_')
|
98
98
|
"/assets/defaults/#{image_name}.png"
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
def image?(new_file = nil)
|
102
102
|
(file || new_file).content_type.include? 'image'
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
def dimensions
|
106
106
|
[magick[:width], magick[:height]]
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
def magick
|
110
110
|
#@magick ||= ::MiniMagick::Image.new(current_path)
|
111
111
|
::MiniMagick::Image.new(current_path)
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
protected
|
115
|
-
|
115
|
+
|
116
116
|
def set_model_info
|
117
117
|
model.data_content_type = file.content_type
|
118
118
|
model.data_file_size = file.size
|
119
|
-
|
119
|
+
|
120
120
|
if image? && model.has_dimensions?
|
121
121
|
model.width, model.height = dimensions
|
122
122
|
end
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
def normalize_param(value)
|
126
126
|
if value.is_a?(Proc) || value.is_a?(Method)
|
127
127
|
evaluate_method(model, value, file)
|
@@ -5,8 +5,8 @@ module AbAdmin
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
scope
|
9
|
-
scope
|
8
|
+
scope(:admin, scoped) unless respond_to?(:admin)
|
9
|
+
scope(:base, scoped) unless respond_to?(:base)
|
10
10
|
scope :ids, lambda { |ids| where("#{quoted_table_name}.id IN (?)", AbAdmin.val_to_array(ids).push(0)) }
|
11
11
|
|
12
12
|
class_attribute :batch_actions, :instance_writer => false
|
@@ -101,9 +101,9 @@ module AbAdmin
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
-
def
|
104
|
+
def generate_token(column=:guid)
|
105
105
|
loop do
|
106
|
-
token = Devise.friendly_token
|
106
|
+
token = ::Devise.friendly_token
|
107
107
|
break token unless to_adapter.find_first({column => token})
|
108
108
|
end
|
109
109
|
end
|
@@ -113,9 +113,9 @@ module AbAdmin
|
|
113
113
|
"#{self.class.model_name.singular}_#{id}"
|
114
114
|
end
|
115
115
|
|
116
|
-
def generate_token(column)
|
116
|
+
def generate_token(column=:guid)
|
117
117
|
begin
|
118
|
-
self[column] = Devise.friendly_token
|
118
|
+
self[column] = ::Devise.friendly_token
|
119
119
|
end while self.class.exists?(column => self[column])
|
120
120
|
end
|
121
121
|
end
|
data/lib/ab_admin/config/base.rb
CHANGED
@@ -126,5 +126,23 @@ module AbAdmin
|
|
126
126
|
normalize_display_options!
|
127
127
|
end
|
128
128
|
end
|
129
|
+
|
130
|
+
class CustomAction
|
131
|
+
include AbAdmin::Config::OptionalDisplay
|
132
|
+
|
133
|
+
attr_reader :name, :options, :data
|
134
|
+
|
135
|
+
def initialize(name, options={}, &block)
|
136
|
+
raise 'Can not create member action without a block' unless block_given?
|
137
|
+
@name = name
|
138
|
+
@options = options
|
139
|
+
@data = block
|
140
|
+
normalize_display_options!
|
141
|
+
end
|
142
|
+
|
143
|
+
def collection?
|
144
|
+
options[:collection]
|
145
|
+
end
|
146
|
+
end
|
129
147
|
end
|
130
148
|
end
|
@@ -6,7 +6,7 @@ module AbAdmin
|
|
6
6
|
def head_options(record, options = {})
|
7
7
|
return if record.nil?
|
8
8
|
|
9
|
-
options = { :spliter =>
|
9
|
+
options = { :spliter => AbAdmin.title_spliter, :append_title => true }.merge(options)
|
10
10
|
|
11
11
|
header = options[:header] || (record.respond_to?(:header) ? record.header : nil)
|
12
12
|
|
@@ -55,26 +55,25 @@ class String
|
|
55
55
|
self.tr(keyboard[from], keyboard[to])
|
56
56
|
end
|
57
57
|
|
58
|
+
def count_words
|
59
|
+
clean_text.scan(/(\p{Alnum}+([-'.]\p{Alnum}+)*)/u).size
|
60
|
+
end
|
61
|
+
|
58
62
|
def words_count
|
59
63
|
frequencies = Hash.new(0)
|
60
64
|
downcase.scan(/(\w+([-'.]\w+)*)/) { |word, ignore| frequencies[word] += 1 }
|
61
|
-
|
65
|
+
frequencies
|
62
66
|
end
|
63
67
|
|
64
68
|
def self.randomize(length = 8)
|
65
69
|
Array.new(length) { (rand(122-97) + 97).chr }.join
|
66
70
|
end
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
require 'htmlentities'
|
72
|
-
class String
|
73
|
-
def clean_text
|
74
|
-
coder = HTMLEntities.new
|
75
|
-
coder.decode(self.no_html)
|
76
|
-
end
|
72
|
+
def clean_text
|
73
|
+
coder = HTMLEntities.new
|
74
|
+
coder.decode(self.no_html)
|
77
75
|
end
|
76
|
+
|
78
77
|
end
|
79
78
|
|
80
79
|
unless ''.respond_to?(:each)
|
@@ -1,16 +1,16 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Scoping
|
3
|
-
module Named
|
4
|
-
module ClassMethods
|
5
|
-
def valid_scope_name?(name)
|
6
|
-
silence_names = [:page, :visible, :un_visible, :admin, :base]
|
7
|
-
if respond_to?(name, true) && !silence_names.include?(name.to_sym)
|
8
|
-
logger.warn "Creating scope :#{name}. " \
|
9
|
-
"Overwriting existing method #{self.name}.#{name}."
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
1
|
+
#module ActiveRecord
|
2
|
+
# module Scoping
|
3
|
+
# module Named
|
4
|
+
# module ClassMethods
|
5
|
+
# def valid_scope_name?(name)
|
6
|
+
# silence_names = [:page, :visible, :un_visible, :admin, :base]
|
7
|
+
# if respond_to?(name, true) && !silence_names.include?(name.to_sym)
|
8
|
+
# logger.warn "Creating scope :#{name}. " \
|
9
|
+
# "Overwriting existing method #{self.name}.#{name}."
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#end
|
16
|
+
#
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'simple_form'
|
1
|
+
#require 'simple_form'
|
2
2
|
|
3
3
|
#module WrappedButton
|
4
4
|
# def wrapped_button(*args, &block)
|
@@ -17,15 +17,15 @@ require 'simple_form'
|
|
17
17
|
# end
|
18
18
|
#end
|
19
19
|
#SimpleForm::FormBuilder.send :include, WrappedButton
|
20
|
-
|
21
|
-
|
22
|
-
def item_wrapper_class
|
23
|
-
"radio #{options.delete(:item_wrapper_class)}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
def item_wrapper_class
|
29
|
-
"radio #{options.delete(:item_wrapper_class)}"
|
30
|
-
end
|
31
|
-
end
|
20
|
+
#
|
21
|
+
#::SimpleForm::Inputs::CollectionRadioButtonsInput.class_exec do
|
22
|
+
# def item_wrapper_class
|
23
|
+
# "radio #{options.delete(:item_wrapper_class) || 'inline'}"
|
24
|
+
# end
|
25
|
+
#end
|
26
|
+
#
|
27
|
+
#::SimpleForm::Inputs::CollectionCheckBoxesInput.class_exec do
|
28
|
+
# def item_wrapper_class
|
29
|
+
# "radio #{options.delete(:item_wrapper_class) || 'inline'}"
|
30
|
+
# end
|
31
|
+
#end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module AbAdmin
|
2
|
+
module I18nTools
|
3
|
+
class ModelTranslator
|
4
|
+
|
5
|
+
IGNORE_COLUMNS = %w(id reset_password_sent_at remember_created_at current_sign_in_at confirmation_token
|
6
|
+
reset_password_token password_salt failed_attempts)
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@locales = Globalize.available_locales
|
10
|
+
@models = AbAdmin.translate_models.map{|m| m.constantize }
|
11
|
+
@models_i18n_hash = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def make_hash
|
15
|
+
@locales.each do |locale|
|
16
|
+
I18n.with_locale(locale) do
|
17
|
+
@models_i18n_hash[locale] = {'activerecord' => {'attributes' => {}, 'models' => {}}}
|
18
|
+
|
19
|
+
models_hash = @models.each_with_object({}) do |model, h|
|
20
|
+
model_i18n = {
|
21
|
+
'zero' => model.model_name.human(:count => 0),
|
22
|
+
'one' => model.model_name.human(:count => 1),
|
23
|
+
'few' => (model.model_name.human(:count => 2) rescue model.model_name.human(:count => 1)),
|
24
|
+
'many' => (model.model_name.human(:count => 9) rescue model.model_name.human(:count => 1)),
|
25
|
+
'other' => (model.model_name.human(:count => 9) rescue model.model_name.human(:count => 1))
|
26
|
+
}
|
27
|
+
@models_i18n_hash[locale]['activerecord']['models'][model.model_name.i18n_key.to_s]= model_i18n
|
28
|
+
attributes = model.columns.map(&:name)
|
29
|
+
attributes.concat(model.translated_attribute_names.map(&:to_s)) if model.translates?
|
30
|
+
attributes.reject! { |el| IGNORE_COLUMNS.include?(el) }
|
31
|
+
h[model.model_name.underscore] = attributes.each_with_object({}) do |attr, o|
|
32
|
+
o[attr] = ha(model, attr, locale).presence || attr
|
33
|
+
model.reflect_on_all_associations.map(&:name).map(&:to_s).reject { |a| a =~ /^translation/ }.each do |assoc|
|
34
|
+
o[assoc] = ha(model, assoc, locale)
|
35
|
+
end
|
36
|
+
if model.new.respond_to?("#{attr}_#{locale.to_s}".to_sym)
|
37
|
+
@locales.each do |locale_1|
|
38
|
+
o["#{attr}_#{locale_1.to_s}"] = "#{ha(model, attr, locale)} (#{I18n.t(locale_1, :scope => [:attrs])})"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end.sort.to_hash
|
42
|
+
end
|
43
|
+
@models_i18n_hash[locale]['activerecord']['attributes'] = models_hash
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def ha(model, attr, locale)
|
49
|
+
model.human_attribute_name(attr, :locale => locale)
|
50
|
+
end
|
51
|
+
|
52
|
+
def write_yaml
|
53
|
+
locale_dir = Rails.root.join('config/locales')
|
54
|
+
@locales.each do |locale|
|
55
|
+
Locator.save(locale_dir.join("#{locale}.attrs.yml"), {locale.to_s => @models_i18n_hash[locale]})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.i18n_models!
|
60
|
+
model_translator = new
|
61
|
+
model_translator.make_hash
|
62
|
+
model_translator.write_yaml
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|