localized_scaffold 0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/Gemfile +6 -0
  2. data/README.rdoc +273 -0
  3. data/generators/locales/standard.de-FO.yml +106 -0
  4. data/generators/locales/standard.de.yml +106 -0
  5. data/generators/locales/standard.en.yml +106 -0
  6. data/generators/localized_devise_views_generator.rb +100 -0
  7. data/generators/localized_scaffold_generator.rb +624 -0
  8. data/generators/templates/devise/locales/devise.de-FO.yml +45 -0
  9. data/generators/templates/devise/locales/devise.de.yml +60 -0
  10. data/generators/templates/devise/locales/devise_views.de.yml +78 -0
  11. data/generators/templates/devise/locales/devise_views.en.yml +79 -0
  12. data/generators/templates/devise/views/confirmations/new.html.erb +23 -0
  13. data/generators/templates/devise/views/mailer/confirmation_instructions.html.erb +6 -0
  14. data/generators/templates/devise/views/mailer/reset_password_instructions.html.erb +8 -0
  15. data/generators/templates/devise/views/mailer/unlock_instructions.html.erb +6 -0
  16. data/generators/templates/devise/views/passwords/edit.html.erb +30 -0
  17. data/generators/templates/devise/views/passwords/new.html.erb +23 -0
  18. data/generators/templates/devise/views/registrations/edit.html.erb +54 -0
  19. data/generators/templates/devise/views/registrations/new.html.erb +34 -0
  20. data/generators/templates/devise/views/sessions/new.html.erb +32 -0
  21. data/generators/templates/devise/views/shared/_links.erb +25 -0
  22. data/generators/templates/devise/views/unlocks/new.html.erb +23 -0
  23. data/generators/templates/erb/scaffold/_form.html.erb +11 -0
  24. data/generators/templates/erb/scaffold/_index.html.erb +54 -0
  25. data/generators/templates/erb/scaffold/edit.html.erb +20 -0
  26. data/generators/templates/erb/scaffold/index.html.erb +73 -0
  27. data/generators/templates/erb/scaffold/layout.html.erb +51 -0
  28. data/generators/templates/erb/scaffold/new.html.erb +18 -0
  29. data/generators/templates/erb/scaffold/scaffold_generator.rb +57 -0
  30. data/generators/templates/erb/scaffold/show.html.erb +22 -0
  31. data/generators/templates/locales/de.yml +61 -0
  32. data/generators/templates/locales/en.yml +61 -0
  33. data/generators/templates/rails/helper/helper.rb +118 -0
  34. data/generators/templates/rails/helper/scaffold_helper.rb +53 -0
  35. data/generators/templates/rails/scaffold_controller/controller.rb +338 -0
  36. data/generators/templates/rails/stylesheets/templates/scaffold.css +203 -0
  37. data/generators/templates/test_unit/scaffold/templates/functional_test.rb +117 -0
  38. data/init.rb +3 -0
  39. data/install.rb +1 -0
  40. data/lib/tasks/localized_scaffold.rake +39 -0
  41. data/localized_scaffold.rb +7 -0
  42. data/rails/init.rb +3 -0
  43. data/test/localized_scaffold_test.rb +8 -0
  44. data/test/test_helper.rb +3 -0
  45. data/uninstall.rb +1 -0
  46. 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"