localized_scaffold 0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +6 -0
- data/README.rdoc +273 -0
- data/generators/locales/standard.de-FO.yml +106 -0
- data/generators/locales/standard.de.yml +106 -0
- data/generators/locales/standard.en.yml +106 -0
- data/generators/localized_devise_views_generator.rb +100 -0
- data/generators/localized_scaffold_generator.rb +624 -0
- data/generators/templates/devise/locales/devise.de-FO.yml +45 -0
- data/generators/templates/devise/locales/devise.de.yml +60 -0
- data/generators/templates/devise/locales/devise_views.de.yml +78 -0
- data/generators/templates/devise/locales/devise_views.en.yml +79 -0
- data/generators/templates/devise/views/confirmations/new.html.erb +23 -0
- data/generators/templates/devise/views/mailer/confirmation_instructions.html.erb +6 -0
- data/generators/templates/devise/views/mailer/reset_password_instructions.html.erb +8 -0
- data/generators/templates/devise/views/mailer/unlock_instructions.html.erb +6 -0
- data/generators/templates/devise/views/passwords/edit.html.erb +30 -0
- data/generators/templates/devise/views/passwords/new.html.erb +23 -0
- data/generators/templates/devise/views/registrations/edit.html.erb +54 -0
- data/generators/templates/devise/views/registrations/new.html.erb +34 -0
- data/generators/templates/devise/views/sessions/new.html.erb +32 -0
- data/generators/templates/devise/views/shared/_links.erb +25 -0
- data/generators/templates/devise/views/unlocks/new.html.erb +23 -0
- data/generators/templates/erb/scaffold/_form.html.erb +11 -0
- data/generators/templates/erb/scaffold/_index.html.erb +54 -0
- data/generators/templates/erb/scaffold/edit.html.erb +20 -0
- data/generators/templates/erb/scaffold/index.html.erb +73 -0
- data/generators/templates/erb/scaffold/layout.html.erb +51 -0
- data/generators/templates/erb/scaffold/new.html.erb +18 -0
- data/generators/templates/erb/scaffold/scaffold_generator.rb +57 -0
- data/generators/templates/erb/scaffold/show.html.erb +22 -0
- data/generators/templates/locales/de.yml +61 -0
- data/generators/templates/locales/en.yml +61 -0
- data/generators/templates/rails/helper/helper.rb +118 -0
- data/generators/templates/rails/helper/scaffold_helper.rb +53 -0
- data/generators/templates/rails/scaffold_controller/controller.rb +338 -0
- data/generators/templates/rails/stylesheets/templates/scaffold.css +203 -0
- data/generators/templates/test_unit/scaffold/templates/functional_test.rb +117 -0
- data/init.rb +3 -0
- data/install.rb +1 -0
- data/lib/tasks/localized_scaffold.rake +39 -0
- data/localized_scaffold.rb +7 -0
- data/rails/init.rb +3 -0
- data/test/localized_scaffold_test.rb +8 -0
- data/test/test_helper.rb +3 -0
- data/uninstall.rb +1 -0
- metadata +120 -0
@@ -0,0 +1,624 @@
|
|
1
|
+
# Localized Rails scaffolding with style...
|
2
|
+
|
3
|
+
require 'rails/generators/rails/scaffold/scaffold_generator'
|
4
|
+
require 'rails/generators/rails/stylesheets/stylesheets_generator'
|
5
|
+
require 'rails/generators/test_unit/scaffold/scaffold_generator'
|
6
|
+
|
7
|
+
# Bring in our own ERB based scaffolding generator for views and layout.
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), 'templates', 'erb', 'scaffold',
|
10
|
+
'scaffold_generator')
|
11
|
+
|
12
|
+
# Configure templates without copying them to app directory "lib/templates",
|
13
|
+
# overwriting the default templates path.
|
14
|
+
#
|
15
|
+
# This has no effect unless the generator is called so we don't need to
|
16
|
+
# implement some initializer for that.
|
17
|
+
|
18
|
+
module Rails # :nodoc:
|
19
|
+
module Generators # :nodoc:
|
20
|
+
def self.templates_path # :nodoc:
|
21
|
+
@templates_path = [File.expand_path(File.join(
|
22
|
+
File.dirname(File.dirname(__FILE__)),
|
23
|
+
'generators', 'templates'))]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Same for the stylesheets.
|
29
|
+
|
30
|
+
module Rails # :nodoc:
|
31
|
+
module Generators # :nodoc:
|
32
|
+
class StylesheetsGenerator # :nodoc:
|
33
|
+
def self.source_root
|
34
|
+
return File.expand_path(File.join(Rails::Generators.templates_path,
|
35
|
+
base_name, generator_name, 'templates'),
|
36
|
+
File.dirname(__FILE__))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Same for the functional tests.
|
43
|
+
|
44
|
+
module TestUnit # :nodoc:
|
45
|
+
module Generators # :nodoc:
|
46
|
+
class ScaffoldGenerator # :nodoc:
|
47
|
+
def self.source_root
|
48
|
+
return File.expand_path(File.join(Rails::Generators.templates_path,
|
49
|
+
base_name, generator_name, 'templates'),
|
50
|
+
File.dirname(__FILE__))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# LocalizedScaffoldGenerator implements a generator doing the same as the
|
57
|
+
# standard scaffold generator but generating localized views. It also provides
|
58
|
+
# a few smaller additions needed so often but respects that programmers still
|
59
|
+
# expect scaffolding and no magic meta framework.
|
60
|
+
#
|
61
|
+
# The generator was not written from scratch but hijacks basic functionality
|
62
|
+
# from the scaffolding generator overwriting lookup rules to use the right
|
63
|
+
# templates.
|
64
|
+
|
65
|
+
class LocalizedScaffoldGenerator < Rails::Generators::ScaffoldGenerator
|
66
|
+
desc "Does the same as the normal scaffold generator does (actually overwrites
|
67
|
+
that code) but generates localized views. This is only implemented for ERB, so
|
68
|
+
expect an error message being bailed out if requesting different stuff.
|
69
|
+
|
70
|
+
Here is some more information about the options (as neither me nor you read
|
71
|
+
READMEs at all):
|
72
|
+
|
73
|
+
--str SOMEFIELD
|
74
|
+
|
75
|
+
This option defines the attribute used as the title field. The to_s method of
|
76
|
+
the model is generated to return this field (therefor the name of the option)
|
77
|
+
and its fallback is the value of the searchbar option (see below) or the first
|
78
|
+
attribute if that is missing as well.
|
79
|
+
|
80
|
+
--belongs_to MODELNAME
|
81
|
+
|
82
|
+
This option implements a belongs_to relationship from the generated model to
|
83
|
+
the provided model name. It adds a has_many relationship to that model and
|
84
|
+
generates all paths respecting this relationship. It also generates methods
|
85
|
+
to setup the \"parent\" object and even the unit tests are written to pass.
|
86
|
+
Be sure to add an attribute like \"modelname_id:integer\" as you will receive
|
87
|
+
an error without.
|
88
|
+
|
89
|
+
--searchbar SOMEFIELD
|
90
|
+
|
91
|
+
It often would be nice to get a simple search interface and some A B C picker
|
92
|
+
with the scaffold and that's exactly what this option does. It also adds a
|
93
|
+
validates_presence_of for that field and generates a helper method. See that
|
94
|
+
helper method to customize the search interface.
|
95
|
+
|
96
|
+
--noshow
|
97
|
+
|
98
|
+
Often the show view is not needed as the index view already displays all of
|
99
|
+
its values. Just add this option to suppress its generation.
|
100
|
+
|
101
|
+
--embed NUMBER
|
102
|
+
|
103
|
+
When having a belongs_to relationship, it might be nicer to not only link to
|
104
|
+
that data from the show view of the \"parent\" but to actually embed a couple
|
105
|
+
of items and use the index view only if more than a certain amount of items
|
106
|
+
is available.
|
107
|
+
|
108
|
+
--listify MAPPING
|
109
|
+
|
110
|
+
Some fields only allow a certain set of values and these values have to be
|
111
|
+
localized as well. The listify option implements such a mechanism by creating
|
112
|
+
a set of methods in the model and preparing the localization files. Sample:
|
113
|
+
\"salutation:mr,mrs,none kind:office,private,mobile,other\"
|
114
|
+
|
115
|
+
Here is a sample using all these options in two models:
|
116
|
+
|
117
|
+
rails generate localized_scaffold person salutation:string firstname:string \\
|
118
|
+
lastname:string --searchbar lastname --listify \"salutation:mr,mrs,none\"
|
119
|
+
|
120
|
+
rails generate localized_scaffold phone person_id:integer kind:string \\
|
121
|
+
number:string --belongsto person --embed 10 --str number --noshow \\
|
122
|
+
--listify \"kind:office,private,mobile,other\""
|
123
|
+
|
124
|
+
# Parsed hash with attribute names and their possible values (see listify
|
125
|
+
# option.
|
126
|
+
|
127
|
+
attr_reader :listifies
|
128
|
+
|
129
|
+
# Additional options supported by the localized scaffold generator
|
130
|
+
|
131
|
+
class_option :str, :type => :string,
|
132
|
+
:desc => 'Optional attribute to return in to_s',
|
133
|
+
:default => nil
|
134
|
+
class_option :belongsto, :type => :string,
|
135
|
+
:desc => 'Optional "parent" model this resource belongs to',
|
136
|
+
:default => nil
|
137
|
+
class_option :searchbar, :type => :string,
|
138
|
+
:desc => 'Optional attribute to generate A B C picker and searchbar',
|
139
|
+
:default => nil
|
140
|
+
class_option :noshow, :type => :boolean,
|
141
|
+
:desc => 'Optional flag to suppress generation of show view',
|
142
|
+
:default => nil
|
143
|
+
class_option :embed, :type => :string,
|
144
|
+
:desc => 'Optional number of values to embed in show view of "parent"',
|
145
|
+
:default => 0
|
146
|
+
class_option :listify, :type => :string,
|
147
|
+
:desc => 'Optional localized values for certain fields (see below)',
|
148
|
+
:default => nil
|
149
|
+
|
150
|
+
# Overwritten constructor implementing additional checks where internal
|
151
|
+
# class option handling is too lazy with error messages.
|
152
|
+
|
153
|
+
def initialize(*)
|
154
|
+
super
|
155
|
+
|
156
|
+
if shell.base.options[:belongsto] == 'belongsto'
|
157
|
+
raise Thor::Error, '!!Missing model name for option --belongsto'
|
158
|
+
end
|
159
|
+
|
160
|
+
if shell.base.options[:searchbar] == 'searchbar'
|
161
|
+
raise Thor::Error, '!!Missing field name for option --searchbar'
|
162
|
+
end
|
163
|
+
|
164
|
+
if shell.base.options[:str] == 'str'
|
165
|
+
raise Thor::Error, '!!Missing field name for option --str'
|
166
|
+
end
|
167
|
+
|
168
|
+
if (value = shell.base.options[:listify]) == 'listify'
|
169
|
+
raise Thor::Error, '!!Missing model name for option --listify'
|
170
|
+
end
|
171
|
+
|
172
|
+
if value.blank?
|
173
|
+
@listifies = {}
|
174
|
+
else
|
175
|
+
@listifies = {}
|
176
|
+
|
177
|
+
value.gsub(/([:, ]) +/, '\1').split(' ').each do |set|
|
178
|
+
field, values = set.split(':')
|
179
|
+
|
180
|
+
@listifies[field] = values.split(',')
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
if has_belongsto?
|
185
|
+
attribute_name = "#{belongsto.class_name}_id".downcase
|
186
|
+
|
187
|
+
if attributes.collect { |a| a.name.downcase }.index(attribute_name).nil?
|
188
|
+
raise Thor::Error,
|
189
|
+
"!!Missing something like #{attribute_name}:integer as attribute."
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
index_attributes # Call to check values
|
194
|
+
end
|
195
|
+
|
196
|
+
# Additional rule to copy scaffold helper.
|
197
|
+
|
198
|
+
def copy_scaffold_helper
|
199
|
+
copy_file File.join(Rails::Generators.templates_path, 'rails', 'helper',
|
200
|
+
'scaffold_helper.rb'), File.join('app', 'helpers', 'scaffold_helper.rb')
|
201
|
+
end
|
202
|
+
|
203
|
+
# Additional rule to copy standard locales.
|
204
|
+
|
205
|
+
def copy_standard_locales
|
206
|
+
locales = File.expand_path(File.join(File.dirname(__FILE__), 'locales'))
|
207
|
+
|
208
|
+
Dir.entries(locales).delete_if { |f| not f.match(/.*\.yml$/) }.each do |l|
|
209
|
+
copy_file File.join(locales, l), File.join('config', 'locales', l)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Additional rules to create locale files for model.
|
214
|
+
|
215
|
+
def create_scaffoled_locales
|
216
|
+
locales = File.join(Rails::Generators.templates_path, 'locales')
|
217
|
+
|
218
|
+
Dir.entries(locales).delete_if { |f| not f.match(/.*\.yml$/) }.each do |l|
|
219
|
+
template File.join(locales, l), File.join('config', 'locales',
|
220
|
+
"#{file_name}.#{l}")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Patch application controller to make sure that scaffold layout is used
|
225
|
+
# and scaffold helpers are included. Patch routes and model if having
|
226
|
+
# a "parent" belongs_to relationship and patch the model with additional
|
227
|
+
# methods for lookup of labels of listified fields.
|
228
|
+
|
229
|
+
def patch_routes_and_more
|
230
|
+
controller = File.join('app', 'controllers', 'application_controller.rb')
|
231
|
+
|
232
|
+
if (found = File.new(controller).grep(/layout '[^']*'/).first).blank?
|
233
|
+
gsub_file controller, /(.*class ApplicationController.*)$/e do |match|
|
234
|
+
"#{match}\n layout 'scaffold'\n"
|
235
|
+
end
|
236
|
+
elsif found.index("'application'")
|
237
|
+
gsub_file controller, /layout 'application'/e do |match|
|
238
|
+
"layout 'scaffold'"
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
if File.new(controller).grep(/helper *:scaffold/).first.blank?
|
243
|
+
gsub_file controller, /(.*class ApplicationController.*)$/e do |match|
|
244
|
+
"#{match}\n helper :scaffold\n"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
listify_methods = @listifies.collect do |field, values|
|
249
|
+
values = values.collect { |v| ':' + v.downcase }.join(', ')
|
250
|
+
|
251
|
+
" # Returns an array with allowed #{field} values.
|
252
|
+
|
253
|
+
def self.#{field.pluralize}
|
254
|
+
return [#{values}]
|
255
|
+
end
|
256
|
+
|
257
|
+
# Returns a label for a certain #{file_name} #{field}.
|
258
|
+
|
259
|
+
def self.#{field}_label(#{field})
|
260
|
+
return I18n.t(\"#{file_name}.selects.#{field}.#" + "{#{field}}\")
|
261
|
+
end
|
262
|
+
|
263
|
+
# Returns a list of values for #{field.pluralize} suitable for a select tag.
|
264
|
+
|
265
|
+
def self.#{field.pluralize}_for_select
|
266
|
+
return #{field.pluralize}.collect { |v| [#{field}_label(v), v.to_s] }
|
267
|
+
end"
|
268
|
+
end
|
269
|
+
|
270
|
+
if not listify_methods.empty?
|
271
|
+
gsub_file File.join('app', 'models', "#{singular_name}.rb"),
|
272
|
+
/^(end *)$/e do |match|
|
273
|
+
"\n#{listify_methods.join("\n\n")}\n#{match}"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
gsub_file File.join('app', 'models', "#{singular_name}.rb"),
|
278
|
+
/^(end *)$/e do |match|
|
279
|
+
validates = ''
|
280
|
+
|
281
|
+
if to_s_attribute != searchbar
|
282
|
+
validates = "\n validates_presence_of :#{to_s_attribute}\n"
|
283
|
+
end
|
284
|
+
|
285
|
+
validates + "
|
286
|
+
# Returns something meaningful as string.
|
287
|
+
|
288
|
+
def to_s
|
289
|
+
return #{to_s_attribute}
|
290
|
+
end\n#{match}"
|
291
|
+
end
|
292
|
+
|
293
|
+
if has_searchbar?
|
294
|
+
if has_belongsto?
|
295
|
+
patch = <<EOF
|
296
|
+
|
297
|
+
validates_presence_of :#{searchbar}
|
298
|
+
|
299
|
+
# Returns an array with the first chars of the #{searchbar} field and the
|
300
|
+
# number of occurences in scope of the provided #{belongsto.file_name}.
|
301
|
+
#
|
302
|
+
# Parameters:
|
303
|
+
#
|
304
|
+
# [#{belongsto.file_name}_id] ID of the object to search in
|
305
|
+
|
306
|
+
def self.#{searchbar}_chars(#{belongsto.file_name}_id)
|
307
|
+
return #{class_name}.find(:all,
|
308
|
+
:select => 'lower(substr(#{searchbar}, 1, 1)) as #{searchbar}_chars,
|
309
|
+
count(*) as count',
|
310
|
+
:conditions => ['#{belongsto.file_name}_id == ?', #{belongsto.file_name}_id],
|
311
|
+
:order => 'lower(substr(#{searchbar}_chars, 1, 1)) asc',
|
312
|
+
:group => 'lower(substr(#{searchbar}_chars, 1, 1))').collect { |s|
|
313
|
+
[s.#{searchbar}_chars, s.count]
|
314
|
+
}
|
315
|
+
end
|
316
|
+
EOF
|
317
|
+
else
|
318
|
+
patch = <<EOF
|
319
|
+
|
320
|
+
validates_presence_of :#{searchbar}
|
321
|
+
|
322
|
+
# Returns an array with the first chars of the #{searchbar} field and the
|
323
|
+
# number of occurences.
|
324
|
+
|
325
|
+
def self.#{searchbar}_chars
|
326
|
+
return #{class_name}.find(:all,
|
327
|
+
:select => 'lower(substr(#{searchbar}, 1, 1)) as #{searchbar}_chars,
|
328
|
+
count(*) as count',
|
329
|
+
:order => 'lower(substr(#{searchbar}_chars, 1, 1)) asc',
|
330
|
+
:group => 'lower(substr(#{searchbar}_chars, 1, 1))').collect { |s|
|
331
|
+
[s.#{searchbar}_chars, s.count]
|
332
|
+
}
|
333
|
+
end
|
334
|
+
EOF
|
335
|
+
end
|
336
|
+
|
337
|
+
gsub_file File.join('app', 'models', "#{singular_name}.rb"),
|
338
|
+
/^(#{Regexp.escape("class #{class_name}")}.*)$/e do |match|
|
339
|
+
"#{match}\n#{patch.chomp}"
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
if has_belongsto?
|
344
|
+
unless options[:pretend]
|
345
|
+
gsub_file File.join('config', 'routes.rb'),
|
346
|
+
/^ (#{Regexp.escape("resources :#{plural_name}")})$/mi do |match|
|
347
|
+
" resources :#{belongsto.plural_name} do\n resources :#{plural_name}\n end"
|
348
|
+
end
|
349
|
+
|
350
|
+
gsub_file File.join('app', 'models', "#{belongsto.singular_name}.rb"),
|
351
|
+
/^(#{Regexp.escape("class #{belongsto.class_name}")}.*)$/e do |match|
|
352
|
+
"#{match}\n has_many :#{plural_name}"
|
353
|
+
end
|
354
|
+
|
355
|
+
gsub_file File.join('app', 'models', "#{singular_name}.rb"),
|
356
|
+
/^(#{Regexp.escape("class #{class_name}")}.*)$/e do |match|
|
357
|
+
if embed?
|
358
|
+
"#{match}\n PARENT_EMBED = #{embed_max}\n\n belongs_to :#{belongsto.file_name}"
|
359
|
+
else
|
360
|
+
"#{match}\n belongs_to :#{belongsto.file_name}"
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
begin
|
365
|
+
gsub_file File.join('app', 'views', belongsto.plural_name,
|
366
|
+
'show.html.erb'),
|
367
|
+
/^(#{Regexp.escape("<p>\n <%= link_to t('standard.cmds.back')")}.*)$/e do |match|
|
368
|
+
if embed?
|
369
|
+
"<p>\n <%= render :partial => '#{plural_name}/index', :locals => {
|
370
|
+
:#{plural_name} => @#{belongsto.singular_name}.#{plural_name}.find(:all, :limit => #{class_name}::PARENT_EMBED + 1),
|
371
|
+
:max => #{class_name}::PARENT_EMBED } %>\n</p>\n\n#{match}"
|
372
|
+
else
|
373
|
+
"<p>\n <%= link_to t('#{file_name}.cmds.list'), #{path_of_with_belongsto_if_any}%>\n</p>\n\n#{match}"
|
374
|
+
end
|
375
|
+
end
|
376
|
+
rescue Exception
|
377
|
+
puts "!!Couldn't patch \"#{belongsto.plural_name}/show.html.erb\"."
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
puts "\nThree things to know about the --belongsto option of the generator as it messes
|
382
|
+
around with your models, views and routes:
|
383
|
+
|
384
|
+
1) The following is added to your routes and you might have a second look:
|
385
|
+
|
386
|
+
resources :#{belongsto.plural_name} do
|
387
|
+
resources :#{plural_name}
|
388
|
+
end
|
389
|
+
|
390
|
+
2) We also add a one-to-many relationship to your #{belongsto.class_name} model:
|
391
|
+
|
392
|
+
class #{belongsto.class_name} < ActiveRecord::Base
|
393
|
+
has_many :#{plural_name}
|
394
|
+
end
|
395
|
+
|
396
|
+
3) Finally a link is added between the show and index views of the model the
|
397
|
+
new #{class_name} model belongs to (app/views/#{belongsto.plural_name}/show.html.erb):
|
398
|
+
|
399
|
+
<p>
|
400
|
+
<%= link_to t('#{file_name}.cmds.list'), #{path_of_with_belongsto_if_any}%>
|
401
|
+
</p>
|
402
|
+
|
403
|
+
And please be sure to restart your server to asure new localization files are
|
404
|
+
loaded.
|
405
|
+
|
406
|
+
Here we go...\n\n"
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
# Additional methods needed in templates of LocalizedScaffoldGenerator.
|
412
|
+
|
413
|
+
module Rails
|
414
|
+
module Generators
|
415
|
+
|
416
|
+
# Additional methods needed in templates of LocalizedScaffoldGenerator.
|
417
|
+
# Used to lookup options and implements things like assembling of routes
|
418
|
+
# depending on having or not having a belongs_to relationship.
|
419
|
+
|
420
|
+
module ResourceHelpers
|
421
|
+
|
422
|
+
# Returns true if the generator should generate stuff in scope of a
|
423
|
+
# "parent" resource as belongs_to relationship.
|
424
|
+
|
425
|
+
def has_belongsto?
|
426
|
+
return (not shell.base.options[:belongsto].blank?)
|
427
|
+
end
|
428
|
+
|
429
|
+
# Returns the name of the optional "parent" belongs_to relationship.
|
430
|
+
|
431
|
+
def belongsto
|
432
|
+
return @belongsto if defined? @belongsto
|
433
|
+
|
434
|
+
if (str = shell.base.options[:belongsto]).blank?
|
435
|
+
@belongsto = nil
|
436
|
+
else
|
437
|
+
@belongsto = ScaffoldGenerator.new([str])
|
438
|
+
end
|
439
|
+
|
440
|
+
return @belongsto
|
441
|
+
end
|
442
|
+
|
443
|
+
# Returns true if the generator should generate stuff including a
|
444
|
+
# searchbar.
|
445
|
+
|
446
|
+
def embed?
|
447
|
+
value = shell.base.options[:embed]
|
448
|
+
return (value.blank? ? false : (value.to_i > 0))
|
449
|
+
end
|
450
|
+
|
451
|
+
# Returns true if the generator should generate stuff including a
|
452
|
+
# searchbar.
|
453
|
+
|
454
|
+
def embed_max
|
455
|
+
value = shell.base.options[:embed]
|
456
|
+
return (value.blank? ? 0 : value.to_i)
|
457
|
+
end
|
458
|
+
|
459
|
+
# Returns true if the generator should generate stuff including a
|
460
|
+
# searchbar.
|
461
|
+
|
462
|
+
def has_searchbar?
|
463
|
+
return (not shell.base.options[:searchbar].blank?)
|
464
|
+
end
|
465
|
+
|
466
|
+
# Returns the field to use for searchbar (if any).
|
467
|
+
|
468
|
+
def searchbar
|
469
|
+
return shell.base.options[:searchbar]
|
470
|
+
end
|
471
|
+
|
472
|
+
# Returns the field to use for the to_s method
|
473
|
+
|
474
|
+
def to_s_attribute
|
475
|
+
return @to_s_attribute if defined? @to_s_attribute
|
476
|
+
|
477
|
+
value = shell.base.options[:str]
|
478
|
+
|
479
|
+
if not value.blank?
|
480
|
+
@to_s_attribute = value
|
481
|
+
elsif has_searchbar?
|
482
|
+
@to_s_attribute = searchbar
|
483
|
+
else
|
484
|
+
@to_s_attribute = attributes.first.name
|
485
|
+
end
|
486
|
+
|
487
|
+
return @to_s_attribute
|
488
|
+
end
|
489
|
+
|
490
|
+
# Returns a copy of the attributes array with a maximum of 4 columns
|
491
|
+
|
492
|
+
def index_attributes
|
493
|
+
return @index_attributes if defined? @index_attributes
|
494
|
+
|
495
|
+
parts = attributes.partition { |a| a.name == to_s_attribute }
|
496
|
+
|
497
|
+
if parts.first.empty?
|
498
|
+
raise Thor::Error, "!!Can not find attribute #{to_s_attribute}"
|
499
|
+
end
|
500
|
+
|
501
|
+
if has_belongsto?
|
502
|
+
parts.last.delete_if { |a| a.name == "#{belongsto.file_name}_id" }
|
503
|
+
end
|
504
|
+
|
505
|
+
@index_attributes = parts.first + parts.last[0..3]
|
506
|
+
|
507
|
+
return @index_attributes
|
508
|
+
end
|
509
|
+
|
510
|
+
# Returns a hash of optional fields to handle as lists and their allowed
|
511
|
+
# values.
|
512
|
+
|
513
|
+
def listifies
|
514
|
+
return shell.base.listifies
|
515
|
+
end
|
516
|
+
|
517
|
+
# Returns true if show view should be generated. Redirects to index page
|
518
|
+
# from action and suppresses generation of show view if not.
|
519
|
+
|
520
|
+
def generate_showview?
|
521
|
+
return (shell.base.options[:noshow] != true)
|
522
|
+
end
|
523
|
+
|
524
|
+
# Returns something to prefix controller routes with if rendering for a
|
525
|
+
# belongsto.
|
526
|
+
|
527
|
+
def belongsto_route_prefix_if_any
|
528
|
+
if has_belongsto?
|
529
|
+
return "/#{belongsto.table_name}/1"
|
530
|
+
else
|
531
|
+
return ''
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
# Returns paths like "bar_path(@bar)" or "foo_bar_(@foo, @bar)" which
|
536
|
+
# depends on having a "parent" belongs_to relationship or not.
|
537
|
+
#
|
538
|
+
# Parameters:
|
539
|
+
#
|
540
|
+
# Options:
|
541
|
+
#
|
542
|
+
# [:method] Optional method (e.g. :edit, :new)
|
543
|
+
# [:value1] First value to add to path
|
544
|
+
# [:value2] Second value to add to path
|
545
|
+
# [:extraargs] Additional stuff to add (e.g. ":q = c" for query)
|
546
|
+
|
547
|
+
def path_of_with_belongsto_if_any(options = {})
|
548
|
+
method = options[:method] || nil
|
549
|
+
|
550
|
+
value1 = options[:value1] || "@#{singular_name}"
|
551
|
+
value2 = options[:value2]
|
552
|
+
|
553
|
+
value2 = "@#{belongsto.singular_name}" if has_belongsto? and value2.blank?
|
554
|
+
|
555
|
+
extraargs = options[:extraargs]
|
556
|
+
|
557
|
+
if not extraargs.blank?
|
558
|
+
extraargs1 = ', ' + extraargs
|
559
|
+
extraargs2 = '(' + extraargs + ')'
|
560
|
+
end
|
561
|
+
|
562
|
+
if has_belongsto?
|
563
|
+
case method
|
564
|
+
when nil
|
565
|
+
return "#{belongsto.singular_name}_#{plural_name}_path(#{value2}#{extraargs1})"
|
566
|
+
when :show
|
567
|
+
return "#{belongsto.singular_name}_#{singular_name}_path(#{value2}, #{value1}#{extraargs1})"
|
568
|
+
when :update
|
569
|
+
return "#{belongsto.singular_name}_#{singular_name}_path(#{value2}, #{value1}#{extraargs1})"
|
570
|
+
when :new
|
571
|
+
return "new_#{belongsto.singular_name}_#{singular_name}_path(#{value2}#{extraargs1})"
|
572
|
+
else
|
573
|
+
return "#{method}_#{belongsto.singular_name}_#{singular_name}_path(#{value2}, #{value1}#{extraargs1})"
|
574
|
+
end
|
575
|
+
else
|
576
|
+
case method
|
577
|
+
when nil
|
578
|
+
return "#{plural_name}_path#{extraargs2}"
|
579
|
+
when :show
|
580
|
+
return "#{singular_name}_path(#{value1}#{extraargs1})"
|
581
|
+
when :update
|
582
|
+
return "#{singular_name}_path(#{value1}#{extraargs1})"
|
583
|
+
when :new
|
584
|
+
return "new_#{singular_name}_path#{extraargs2}"
|
585
|
+
else
|
586
|
+
return "#{method}_#{singular_name}_path(#{value1}#{extraargs1})"
|
587
|
+
end
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
# Returns true if the will_paginate gem is installed. For more infos
|
592
|
+
# see gem "will_paginate" on github.com.
|
593
|
+
|
594
|
+
def has_will_paginate?
|
595
|
+
if not defined? @has_will_paginate
|
596
|
+
begin
|
597
|
+
require 'will_paginate'
|
598
|
+
@has_will_paginate = true
|
599
|
+
rescue Exception
|
600
|
+
@has_will_paginate = false
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
return @has_will_paginate
|
605
|
+
end
|
606
|
+
|
607
|
+
# Returns true if JQuery Javascript library is installed (found in
|
608
|
+
# the public javascripts directory). The fallback is to use Prototype.
|
609
|
+
|
610
|
+
def has_javascript_jquery?
|
611
|
+
return File.exists?(File.join(RAILS_ROOT, 'public', 'javascripts',
|
612
|
+
'jquery.js'))
|
613
|
+
end
|
614
|
+
|
615
|
+
# Returns true if the Prototype Javascript library is there. If JQuery
|
616
|
+
# can be found, it is used instead.
|
617
|
+
|
618
|
+
def has_javascript_prototype?
|
619
|
+
return File.exists?(File.join(RAILS_ROOT, 'public', 'javascripts',
|
620
|
+
'prototype.js'))
|
621
|
+
end
|
622
|
+
end
|
623
|
+
end
|
624
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
en:
|
2
|
+
errors:
|
3
|
+
messages:
|
4
|
+
not_found: "nicht gefunden"
|
5
|
+
already_confirmed: "wurde bereits bestätigt"
|
6
|
+
not_locked: "war nicht gesperrt"
|
7
|
+
|
8
|
+
devise:
|
9
|
+
failure:
|
10
|
+
unauthenticated: "Sie müssen sich anmelden oder registrieren bevor es
|
11
|
+
weitergeht."
|
12
|
+
unconfirmed: "Sie müssen Ihren Account bestätigen bevor es weitergeht."
|
13
|
+
locked: "Ihr Account wurde gesperrt."
|
14
|
+
invalid: "Login oder Passwort ungültig."
|
15
|
+
invalid_token: "Ungültiger Autorisierungsschlüssel."
|
16
|
+
timeout: "Ihre Session ist abgelaufen. Bitte melden Sie sich erneut an."
|
17
|
+
inactive: "Ihr Account wurde noch nicht aktiviert."
|
18
|
+
sessions:
|
19
|
+
signed_in: "Erfolgreich angemeldet."
|
20
|
+
signed_out: "Erfolgreich abgemeldet."
|
21
|
+
passwords:
|
22
|
+
send_instructions: "Sie erhalten in ein paar Minuten eine E-Mail mit
|
23
|
+
der Anleitung, wie Sie Ihr Passwort zurücksetzen können."
|
24
|
+
updated: "Ihr Passwort wurde erfolgreich gesetzt. Sie sind nun
|
25
|
+
angemeldet."
|
26
|
+
confirmations:
|
27
|
+
send_instructions: "Sie erhalten in wenigen Minuten eine E-Mail mit der
|
28
|
+
Anleitung, wie Sie Ihren Account aktivieren."
|
29
|
+
confirmed: "Ihr Account wurde erfolgreich bestätigt. Sie sind nun
|
30
|
+
angemeldet."
|
31
|
+
registrations:
|
32
|
+
signed_up: "Sie haben sich erfolgreich registriert und erhalten zur
|
33
|
+
Bestätigung eine E-Mail."
|
34
|
+
updated: "Sie haben Ihren Account erfolgreich aktualisiert."
|
35
|
+
destroyed: "Auf Wiedersehen! Ihr Account wurde erfolgreich gelöscht.
|
36
|
+
Wir hoffen trotzdem Sie bald wiederzusehen."
|
37
|
+
unlocks:
|
38
|
+
send_instructions: "Sie erhalten in ein paar Minuten eine E-Mail mit
|
39
|
+
der Anleitung, wie Sie Ihren Account entsperren können."
|
40
|
+
unlocked: "Ihr Account wurde erfolgreich entsperrt. Sie sind nun
|
41
|
+
angemeldet."
|
42
|
+
mailer:
|
43
|
+
confirmation_instructions: "Anleitung für die Aktivierung Ihres Accounts"
|
44
|
+
reset_password_instructions: "Anleitung für das Zurücksetzen Ihres Passworts"
|
45
|
+
unlock_instructions: "Anleitung für das Entsperren Ihres Accounts"
|