dry_crud 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/README.rdoc +32 -24
  2. data/Rakefile +73 -19
  3. data/VERSION +1 -1
  4. data/lib/generators/dry_crud/dry_crud_generator.rb +11 -2
  5. data/lib/generators/dry_crud/templates/app/assets/images/actions/delete.png +0 -0
  6. data/lib/generators/dry_crud/templates/app/assets/stylesheets/crud.scss +64 -0
  7. data/lib/generators/dry_crud/templates/app/assets/stylesheets/sample.scss +258 -0
  8. data/lib/generators/dry_crud/templates/app/controllers/crud_controller.rb +30 -24
  9. data/lib/generators/dry_crud/templates/app/controllers/list_controller.rb +93 -7
  10. data/lib/generators/dry_crud/templates/app/helpers/crud_helper.rb +70 -16
  11. data/lib/generators/dry_crud/templates/app/helpers/list_helper.rb +1 -0
  12. data/lib/generators/dry_crud/templates/app/helpers/standard_form_builder.rb +11 -3
  13. data/lib/generators/dry_crud/templates/app/helpers/standard_helper.rb +36 -45
  14. data/lib/generators/dry_crud/templates/app/helpers/standard_table_builder.rb +4 -3
  15. data/lib/generators/dry_crud/templates/app/views/crud/_actions_edit.html.erb +2 -2
  16. data/lib/generators/dry_crud/templates/app/views/crud/_actions_edit.html.haml +3 -0
  17. data/lib/generators/dry_crud/templates/app/views/crud/_actions_index.html.haml +1 -0
  18. data/lib/generators/dry_crud/templates/app/views/crud/_actions_show.html.erb +2 -2
  19. data/lib/generators/dry_crud/templates/app/views/crud/_actions_show.html.haml +3 -0
  20. data/lib/generators/dry_crud/templates/app/views/crud/_attrs.html.erb +1 -1
  21. data/lib/generators/dry_crud/templates/app/views/crud/_attrs.html.haml +1 -0
  22. data/lib/generators/dry_crud/templates/app/views/crud/_form.html.haml +1 -0
  23. data/lib/generators/dry_crud/templates/app/views/crud/_list.html.haml +1 -0
  24. data/lib/generators/dry_crud/templates/app/views/crud/edit.html.erb +0 -2
  25. data/lib/generators/dry_crud/templates/app/views/crud/edit.html.haml +5 -0
  26. data/lib/generators/dry_crud/templates/app/views/crud/new.html.erb +0 -2
  27. data/lib/generators/dry_crud/templates/app/views/crud/new.html.haml +5 -0
  28. data/lib/generators/dry_crud/templates/app/views/crud/show.html.erb +0 -2
  29. data/lib/generators/dry_crud/templates/app/views/crud/show.html.haml +7 -0
  30. data/lib/generators/dry_crud/templates/app/views/layouts/_flash.html.erb +8 -0
  31. data/lib/generators/dry_crud/templates/app/views/layouts/_flash.html.haml +4 -0
  32. data/lib/generators/dry_crud/templates/app/views/layouts/_menu.html.erb +3 -0
  33. data/lib/generators/dry_crud/templates/app/views/layouts/_menu.html.haml +3 -0
  34. data/lib/generators/dry_crud/templates/app/views/layouts/_nav.html.erb +6 -0
  35. data/lib/generators/dry_crud/templates/app/views/layouts/_nav.html.haml +3 -0
  36. data/lib/generators/dry_crud/templates/app/views/layouts/crud.html.erb +40 -21
  37. data/lib/generators/dry_crud/templates/app/views/layouts/crud.html.haml +42 -0
  38. data/lib/generators/dry_crud/templates/app/views/list/_actions_index.html.haml +0 -0
  39. data/lib/generators/dry_crud/templates/app/views/list/_list.html.haml +1 -0
  40. data/lib/generators/dry_crud/templates/app/views/list/_search.html.erb +4 -3
  41. data/lib/generators/dry_crud/templates/app/views/list/_search.html.haml +5 -0
  42. data/lib/generators/dry_crud/templates/app/views/list/index.html.erb +2 -4
  43. data/lib/generators/dry_crud/templates/app/views/list/index.html.haml +7 -0
  44. data/lib/generators/dry_crud/templates/app/views/shared/_error_messages.html.erb +1 -1
  45. data/lib/generators/dry_crud/templates/app/views/shared/_error_messages.html.haml +6 -0
  46. data/lib/generators/dry_crud/templates/app/views/shared/_labeled.html.erb +1 -1
  47. data/lib/generators/dry_crud/templates/app/views/shared/_labeled.html.haml +3 -0
  48. data/lib/generators/dry_crud/templates/config/locales/en_crud.yml +6 -6
  49. data/lib/generators/dry_crud/templates/test/crud_test_model.rb +5 -1
  50. data/lib/generators/dry_crud/templates/test/custom_assertions.rb +4 -4
  51. data/lib/generators/dry_crud/templates/test/functional/crud_controller_test_helper.rb +40 -32
  52. data/lib/generators/dry_crud/templates/test/functional/crud_test_models_controller_test.rb +3 -5
  53. data/lib/generators/dry_crud/templates/test/unit/helpers/crud_helper_test.rb +5 -3
  54. data/lib/generators/dry_crud/templates/test/unit/helpers/standard_form_builder_test.rb +4 -4
  55. data/lib/generators/dry_crud/templates/test/unit/helpers/standard_helper_test.rb +11 -25
  56. data/lib/generators/dry_crud/templates/test/unit/helpers/standard_table_builder_test.rb +9 -9
  57. data/test/templates/Gemfile +13 -6
  58. data/test/templates/app/controllers/admin/cities_controller.rb +14 -0
  59. data/test/templates/app/controllers/admin/countries_controller.rb +14 -0
  60. data/test/templates/app/controllers/people_controller.rb +1 -1
  61. data/test/templates/app/controllers/vips_controller.rb +2 -2
  62. data/test/templates/app/helpers/cities_helper.rb +9 -0
  63. data/test/templates/app/models/city.rb +4 -3
  64. data/test/templates/app/models/country.rb +14 -0
  65. data/test/templates/app/views/admin/cities/_actions_index.html.erb +2 -0
  66. data/test/templates/app/views/admin/cities/_actions_index.html.haml +2 -0
  67. data/test/templates/app/views/admin/cities/_form.html.erb +1 -0
  68. data/test/templates/app/views/admin/cities/_form.html.haml +1 -0
  69. data/test/templates/app/views/{cities → admin/cities}/_hello.html.erb +0 -0
  70. data/test/templates/app/views/admin/cities/_hello.html.haml +1 -0
  71. data/test/templates/app/views/admin/cities/_list.html.erb +6 -0
  72. data/test/templates/app/views/admin/cities/_list.html.haml +5 -0
  73. data/test/templates/app/views/admin/countries/_list.html.erb +5 -0
  74. data/test/templates/app/views/admin/countries/_list.html.haml +4 -0
  75. data/test/templates/app/views/ajax/_actions_index.html.haml +8 -0
  76. data/test/templates/app/views/ajax/_hello.html.haml +1 -0
  77. data/test/templates/app/views/ajax/ajax.js.haml +1 -0
  78. data/test/templates/app/views/layouts/_menu.html.erb +1 -1
  79. data/test/templates/app/views/layouts/_menu.html.haml +3 -0
  80. data/test/templates/app/views/people/_attrs.html.haml +4 -0
  81. data/test/templates/app/views/people/_list.html.haml +1 -0
  82. data/test/templates/config/database.yml +8 -9
  83. data/test/templates/config/locales/en_cities.yml +3 -3
  84. data/test/templates/config/routes.rb +16 -8
  85. data/test/templates/db/migrate/20100511174904_create_people_and_cities.rb +7 -7
  86. data/test/templates/db/seeds.rb +11 -5
  87. data/test/templates/test/fixtures/cities.yml +3 -3
  88. data/test/templates/test/fixtures/countries.yml +11 -0
  89. data/test/templates/test/functional/admin/cities_controller_test.rb +59 -0
  90. data/test/templates/test/functional/admin/countries_controller_test.rb +43 -0
  91. data/test/templates/test/functional/people_controller_test.rb +6 -1
  92. metadata +54 -15
  93. data/lib/generators/dry_crud/templates/app/assets/stylesheets/crud.css +0 -239
  94. data/test/templates/app/controllers/cities_controller.rb +0 -10
  95. data/test/templates/app/views/cities/_form.html.erb +0 -8
  96. data/test/templates/app/views/cities/_list.html.erb +0 -4
  97. data/test/templates/test/functional/cities_controller_test.rb +0 -45
data/README.rdoc CHANGED
@@ -1,40 +1,42 @@
1
1
  = DRY CRUD
2
2
 
3
- DRY CRUD generates simple and extendable controller, views and helpers that support you to DRY up the CRUD code in your Rails project. Start with these elements and build a clean base to efficiently develop your application upon. First, you need to install the gem with
3
+ DRY CRUD generates simple and extendable controller, views and helpers that support you to DRY up the CRUD code in your Rails project. Start with these elements and build a clean base to efficiently develop your application upon.
4
4
 
5
- gem install dry_crud
5
+ Create your Rails application directly with the DRY CRUD application template:
6
6
 
7
- In order to use the generator, you have to register the gem in your Rails application's +Gemfile+. Add the following lines:
8
-
9
- group :development do
10
- gem 'dry_crud'
11
- end
12
-
13
- Don't worry, it's a simple development dependency. You may even savely remove it after you have run in once. So now, you should run the generator to get the goodies:
7
+ rails new [APP_NAME] -m https://raw.github.com/codez/dry_crud/master/template.rb
8
+
9
+ If your application already exists or you prefer the DIY way, then install the Gem (<tt>gem install dry_crud</tt>), add it to your Gemfile and run the generator. You may remove the Gemfile entry again afterwards, it is not required anymore.
14
10
 
15
11
  rails generate dry_crud
12
+
13
+ If you prefer HAML templates instead of ERB, run
14
+
15
+ rails generate dry_crud -t haml
16
16
 
17
17
  To integrate DRY CRUD into your code, only a few additions are required:
18
18
 
19
19
  * For uniform CRUD functionality, just subclass your controllers from +CrudController+.
20
20
  * Overwrite the <tt>:to_s</tt> method of your models for a human-friendly representation in captions.
21
21
 
22
- Version 1.4 and higher are built for Rails 3.1. As of Rails 3.1, views are inheritable as well, so a core functionality of DRY CRUD got into the Rails core itself. For Rails 3.0, use version 1.3.1 or refer to the rails-3.0 branch. If you need a version for Rails 2.3, please get version 0.6.0 of the gem or go to the rails-2.3 branch on Github. DRY CRUD 1.3 is fully compatible with Ruby 1.8.7, Ruby 1.9.2 and JRuby.
22
+ Version 1.5 and higher are built for Rails 3.2. As of Rails 3.1, views are inheritable as well, so a core functionality of DRY CRUD got into the Rails core itself. For Rails 3.0, use version 1.3.1 or refer to the rails-3.0 branch. If you need a version for Rails 2.3, please get version 0.6.0 of the gem or go to the rails-2.3 branch on Github. DRY CRUD 1.3 and above are fully compatible with Ruby 1.8.7, Ruby 1.9.2 and JRuby.
23
23
 
24
24
  == Overview
25
25
 
26
- In most Rails applications, you have some models that require basic CRUD (create, read, update, delete) functionality. There are various possibilities like Rails scaffolding, {Inherited Resources}[https://github.com/josevalim/inherited_resources] or {Dry Scaffold}[http://github.com/grimen/dry_scaffold]. Still, various parts in your application remain duplicated. While you might pull up common methods into a common superclass controller, most views still contain very similar code.
26
+ In most Rails applications, you have some models that require basic CRUD (create, read, update, delete) functionality. There are various possibilities like Rails scaffolding, {Inherited Resources}[https://github.com/josevalim/inherited_resources] or {Dry Scaffold}[http://github.com/grimen/dry_scaffold]. Still, various parts in your application remain duplicated. While you might pull up common methods into a common superclass controller, most views still contain very similar code. And then you also have to remember the entire API of these frameworks.
27
27
 
28
28
  Enter DRY CRUD.
29
29
 
30
30
  <b>
31
- The main idea of DRY CRUD is to concentrate basic functionality of your application, like CRUD actions, uniform formatting, forms and tables into specifically extendable units. DRY CRUD generates various foundation classes that you may freely adapt to your application's needs. For each model, you may transparently customize arbitrary parts or just fallback to the general behavior. This applies not only for controllers, but also for view templates and helpers. There is no black box your code depends on. You lay the foundation that fits your application best.
31
+ The main idea of DRY CRUD is to concentrate basic functionality of your application, like CRUD actions, uniform formatting, forms and tables into specifically extendable units. DRY CRUD generates various foundation classes that you may browse easily and adapt freely to your application's needs. For each model, you may transparently customize arbitrary parts or just fallback to the general behavior. This applies not only for controllers, but also for view templates and helpers. There is no black box your code depends on. You lay the foundation that fits your application best.
32
32
  </b>
33
33
 
34
34
  DRY CRUD is a Rails generator. All code resides in your application and is open for you to inspect and to extend. You may pick whatever you consider useful or adapt what is not sufficient. Even if you do not require any CRUD functionality, you might find some helpers simplifying your work. There are no runtime dependencies to the dry_crud gem. Having said this, DRY CRUD does not want to provide a maximum of functionality that requires a lot of configuration, but rather a clean and lightweight foundation to build your application's requirements upon. This is why DRY CRUD comes as a generator and not as a Rails plugin.
35
35
 
36
36
  DRY CRUD does not depend on any other plugins, but easily allows you to integrate them in order to unify the behavior of your CRUD controllers. You might even use the plugins mentioned above to adapt your generated +CrudController+ base class. All classes come with thorough tests that provide you with a solid foundation for implementing your own adaptions.
37
37
 
38
+ A basic CSS gets you started with your application's layout. For advanced needs, DRY CRUD supports the styles and classes used in {Bootstrap}[http://twitter.github.com/bootstrap/]. A great design never was so close.
39
+
38
40
  If you find yourself adapting the same parts of DRY CRUD for your applications over and over, please feel free to {fork me on Github}[http://github.com/codez/dry_crud].
39
41
 
40
42
  See the Examples section for some use cases and the Generated Files section below for details on the single classes and templates.
@@ -83,12 +85,6 @@ In <tt>app/views/list/index.html.erb</tt>, add the following line for the pagina
83
85
  <%= will_paginate @entries %>
84
86
 
85
87
  And we are done again. All our controllers inheriting from +ListController+, including above +PeopleController+, now have paginated index views. Because our customization for the people table is in the separate <tt>_list</tt> partial, no further modifications are required.
86
- If the current page should be remembered while viewing or editing an entry, just add :page to the remembered_params in <tt>ListController::Memory</tt>:
87
-
88
- controller.remember_params = [:q, :sort, :sort_dir, :page]
89
-
90
- In this case, you should also pass the parameter <tt>page=1</tt> with a hidden field in your <tt>list/_search.html.erb</tt> to start displaying search results at page one.
91
-
92
88
 
93
89
  ==== Special formatting for selected attributes
94
90
 
@@ -101,7 +97,7 @@ In <tt>app/helpers/people.rb</tt>:
101
97
 
102
98
  Should you have attributes with the same name for multiple models that you want to be formatted the same way, you may define a helper method <tt>format_{attr}</tt> for these attributes.
103
99
 
104
- By the way: The method <tt>:f</tt> in +StandardHelper+ uniformly formats arbitrary values according to their class.
100
+ By the way: The method <tt>:f</tt> in +StandardHelper+ uniformly formats arbitrary values according to their class.
105
101
 
106
102
 
107
103
  ==== Filtering the index list
@@ -185,11 +181,23 @@ Even +belongs_to+ associations are automatically rendered with a select field. B
185
181
 
186
182
  Yes, it's bad practice to use finder logic in your views! Define the variable <tt>@hometowns</tt> in your controller instead (as shown in the example above), and you do not even have to specify the <tt>:list</tt> option.
187
183
 
184
+
185
+ === Nested Resources
186
+
187
+ In case you define nested resources, your +CrudController+ subclass should know. Listing and creating entries as well as displaying links for these resources is dependent on the nesting hierarchy. This is how you declare the namespaces and parent resources in your controller:
188
+
189
+ self.nesting = :my_namspace, ParentResource
190
+
191
+ This declaration is for a controller nested in +parent_resources+ within a +:my_namespace+ scope. +ParentResource+ is the corresponding +ActiveRecord+ model. The request param +:parent_resource_id+ is used to load the parent entry, which in turn is used to filter the entries listed and created in your controller.
192
+
193
+ The <tt>ListController::Nesting</tt> module defines this basic behaviour. For more complex setups, have a look there and adjust it to your needs.
194
+
195
+
188
196
  === Internationalization (I18N)
189
197
 
190
198
  All text strings used are externalized to an english locale yaml. The keys are organized by controller and template name plus a generic global scope.
191
199
 
192
- To represent the controller hierarchy used by <tt>render_inheritable</tt>, a special translation helper <tt>:ti</tt> looks up keys along this hierarchy in the following order:
200
+ To represent your controller hierarchy, a special translation helper <tt>:ti</tt> looks up keys along the hierarchy in the following order:
193
201
  {controller_name}.{template_name}.{key}
194
202
  {controller_name}.{action_name}.{key}
195
203
  {controller_name}.global.{key}
@@ -215,7 +223,7 @@ All generated files are supposed to provide a reasonable foundation for the CRUD
215
223
 
216
224
  {controller/crud_controller.rb}[http://codez.ch/dry_crud/?q=CrudController]:: Abstract controller providing basic CRUD actions. This implementation mainly follows the one of the Rails scaffolding controller and responses to HTML and XML requests. Some enhancements were made to ease extendability. Several protected helper methods are there to be (optionally) overriden by subclasses. With the help of additional callbacks, it is possible to hook into the action procedures without overriding the entire method. This class is based on +ListController+.
217
225
 
218
- {controller/list_controller.rb}[http://codez.ch/dry_crud/?q=ListController]:: Abstract controller providing a basic list action. There are two sub-modules that provide search and sort functionality for the table displayed in the list action. A third sub-module remembers the list parameters in order to return to an identical list.
226
+ {controller/list_controller.rb}[http://codez.ch/dry_crud/?q=ListController]:: Abstract controller providing a basic list action. Use this controller if you require read-only functionality. There are two sub-modules that provide search and sort functionality for the table displayed in the list action. A third sub-module remembers the list parameters in order to return to an identical list.
219
227
 
220
228
 
221
229
  === Helpers:
@@ -275,9 +283,9 @@ views/layouts/crud.html.erb:: An example layout showing how to use the <tt>@titl
275
283
 
276
284
  views/layouts/_menu.html.erb:: An empty file to put your menu items into. Included from <tt>crud.html.erb</tt>.
277
285
 
278
- public/stylesheets/crud.css:: A simple CSS with all the classes and ids used in the CRUD code.
286
+ app/assets/stylesheets/crud.scss:: A simple SCSS with all the classes and ids used in the CRUD code.
279
287
 
280
- public/images/action/*.png:: Some sample action icons from the {Open Icon Library}[http://openiconlibrary.sourceforge.net].
288
+ app/assets/images/action/*.png:: Some sample action icons from the {Open Icon Library}[http://openiconlibrary.sourceforge.net].
281
289
 
282
290
 
283
291
  === Tests:
@@ -291,4 +299,4 @@ public/images/action/*.png:: Some sample action icons from the {Open Icon Librar
291
299
  test/several other tests:: Testing the provided implementation and a great base to test your adaptions of the CRUD code.
292
300
 
293
301
 
294
-
302
+ {<img src="https://secure.travis-ci.org/codez/dry_crud.png" />}[http://travis-ci.org/codez/dry_crud]
data/Rakefile CHANGED
@@ -19,16 +19,6 @@ task :test => ['test:app:init'] do
19
19
  end
20
20
  end
21
21
 
22
- require 'rcov/rcovtask'
23
- Rcov::RcovTask.new do |test|
24
- test.libs << "test/test_app/test"
25
- test.test_files = Dir[ "test/test_app/test/**/*_test.rb" ]
26
- test.rcov_opts = ['--text-report',
27
- '-i', '"test\/test_app\/app\/.*"',
28
- '-x', '"\/Library\/Ruby\/.*"']
29
- test.verbose = true
30
- end
31
-
32
22
  namespace :test do
33
23
  namespace :app do
34
24
  task :environment do
@@ -41,7 +31,7 @@ namespace :test do
41
31
  desc "Create a rails test application"
42
32
  task :create do
43
33
  unless File.exist?(TEST_APP_ROOT)
44
- sh "rails new #{TEST_APP_ROOT}"
34
+ sh "rails new #{TEST_APP_ROOT} --skip-bundle"
45
35
  FileUtils.cp(File.join(File.dirname(__FILE__), 'test', 'templates', 'Gemfile'), TEST_APP_ROOT)
46
36
  sh "cd #{TEST_APP_ROOT}; bundle install" # update Gemfile.lock
47
37
  FileUtils.rm_f(File.join(TEST_APP_ROOT, 'test', 'performance', 'browsing_test.rb'))
@@ -52,21 +42,64 @@ namespace :test do
52
42
  task :generate_crud => [:create, :environment] do
53
43
  require File.join(GENERATOR_ROOT, 'dry_crud_generator')
54
44
 
55
- DryCrudGenerator.new('', {:force => true}, :destination_root => TEST_APP_ROOT).invoke_all
45
+ DryCrudGenerator.new('', {:force => true, :templates => ENV['HAML'] ? 'haml' : 'erb'}, :destination_root => TEST_APP_ROOT).invoke_all
56
46
  end
57
47
 
58
- desc "Initializes the test application with a couple of classes"
59
- task :init => :generate_crud do
48
+ desc "Populates the test application with some models and controllers"
49
+ task :populate => :generate_crud do
50
+ # copy test app templates
60
51
  FileUtils.cp_r(File.join(File.dirname(__FILE__), 'test', 'templates', '.'), TEST_APP_ROOT)
52
+
53
+ # replace some unused files
61
54
  FileUtils.rm_f(File.join(TEST_APP_ROOT, 'public', 'index.html'))
62
- FileUtils.mv(File.join(TEST_APP_ROOT, 'app', 'views', 'layouts', 'crud.html.erb'),
63
- File.join(TEST_APP_ROOT, 'app', 'views', 'layouts', 'application.html.erb'),
64
- :force => true)
55
+ layouts = File.join(TEST_APP_ROOT, 'app', 'views', 'layouts')
56
+ FileUtils.mv(File.join(layouts, 'crud.html.erb'),
57
+ File.join(layouts, 'application.html.erb'),
58
+ :force => true) if File.exists?(File.join(layouts, 'crud.html.erb'))
59
+ FileUtils.mv(File.join(layouts, 'crud.html.haml'),
60
+ File.join(layouts, 'application.html.haml'),
61
+ :force => true) if File.exists?(File.join(layouts, 'crud.html.haml'))
62
+
63
+ # remove unused template type, erb or haml
64
+ exclude = ENV['HAML'] ? 'erb' : 'haml'
65
+ Dir.glob(File.join(TEST_APP_ROOT, 'app', 'views', '**', "*.#{exclude}")).each do |f|
66
+ FileUtils.rm(f)
67
+ end
68
+
69
+ # migrate the database
65
70
  FileUtils.cd(TEST_APP_ROOT) do
66
- sh "rake db:migrate db:seed RAILS_ENV=development"
67
- sh "rake db:migrate RAILS_ENV=test" # db:test:prepare does not work for jdbcsqlite3
71
+ sh "rake db:migrate db:seed RAILS_ENV=development --trace"
72
+ sh "rake db:migrate RAILS_ENV=test --trace" # db:test:prepare does not work for jdbcsqlite3
68
73
  end
69
74
  end
75
+
76
+ desc "Initializes the test application with a couple of classes"
77
+ task :init => [:populate,
78
+ :customize]
79
+
80
+ desc "Customize some of the functionality provided by dry_crud"
81
+ task :customize => ['test:app:add_pagination'
82
+ #'test:app:use_bootstrap'
83
+ ]
84
+
85
+ desc "Adds pagination to the test app"
86
+ task :add_pagination => :generate_crud do
87
+ list_ctrl = File.join(TEST_APP_ROOT, 'app', 'controllers', 'list_controller.rb')
88
+ file_replace(list_ctrl, "@entries = list_entries",
89
+ "@entries = list_entries.page(params[:page]).per(10)")
90
+ file_replace(File.join(TEST_APP_ROOT, 'app', 'views', 'list', 'index.html.erb'),
91
+ "<%= render 'list' %>", "<%= paginate @entries %>\n\n<%= render 'list' %>")
92
+ file_replace(File.join(TEST_APP_ROOT, 'app', 'views', 'list', 'index.html.haml'),
93
+ "= render 'list'", "= paginate @entries\n\n= render 'list'")
94
+ end
95
+
96
+ desc "Use Boostrap in the test app"
97
+ task :use_bootstrap => :generate_crud do
98
+ file_replace(File.join(TEST_APP_ROOT, 'app', 'assets', 'stylesheets', 'application.css'), " *= require_self", "*= require twitter/bootstrap\n *= require_self")
99
+ file_replace(File.join(TEST_APP_ROOT, 'app', 'assets', 'javascripts', 'application.js'), "//= require_tree .", "//= require twitter/bootstrap\n//= require_tree .")
100
+ FileUtils.rm(File.join(TEST_APP_ROOT, 'app', 'assets', 'stylesheets', 'sample.scss'))
101
+ end
102
+
70
103
  end
71
104
  end
72
105
 
@@ -91,6 +124,18 @@ task :site => :rdoc do
91
124
  end
92
125
  end
93
126
 
127
+ if RUBY_VERSION == '1.8.7' && RUBY_PLATFORM != 'java'
128
+ require 'rcov/rcovtask'
129
+ Rcov::RcovTask.new do |test|
130
+ test.libs << "test/test_app/test"
131
+ test.test_files = Dir[ "test/test_app/test/**/*_test.rb" ]
132
+ test.rcov_opts = ['--text-report',
133
+ '-i', '"test\/test_app\/app\/.*"',
134
+ '-x', '"\/Library\/Ruby\/.*"']
135
+ test.verbose = true
136
+ end
137
+ end
138
+
94
139
  # :package task
95
140
  Gem::PackageTask.new(DRY_CRUD_GEMSPEC) do |pkg|
96
141
  if Rake.application.top_level_tasks.include?('release')
@@ -125,3 +170,12 @@ task :release do
125
170
  puts " $ rake repackage"
126
171
  puts " $ gem push pkg/dry_crud-#{version}.gem"
127
172
  end
173
+
174
+
175
+ def file_replace(file, expression, replacement)
176
+ return unless File.exists?(file)
177
+ text = File.read(file)
178
+ replaced = text.gsub(expression, replacement)
179
+ puts "WARN: Nothing replaced in '#{file}' for '#{expression}'" if text == replaced
180
+ File.open(file, "w") { |f| f.puts replaced }
181
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.5.0
@@ -2,15 +2,24 @@ require 'rails/generators'
2
2
 
3
3
  class DryCrudGenerator < Rails::Generators::Base
4
4
 
5
+ class_options %w(templates -t) => 'erb'
6
+
7
+
5
8
  def self.source_root
6
9
  File.join(File.dirname(__FILE__), 'templates')
7
10
  end
8
11
 
9
12
  def install_dry_crud
10
13
  # copy everything in template subfolders
14
+ exclude = options[:templates].downcase == 'haml' ? '.erb' : '.haml'
15
+
11
16
  Dir.chdir(self.class.source_root) do
12
- Dir.glob("*").each do |f|
13
- directory(f) if File.directory?(f)
17
+ Dir.glob(File.join('**', '**')).sort.each do |file_source|
18
+ if !File.directory?(file_source) &&
19
+ !file_source.ends_with?(exclude) &&
20
+ file_source != 'INSTALL'
21
+ copy_file(file_source)
22
+ end
14
23
  end
15
24
  end
16
25
 
@@ -0,0 +1,64 @@
1
+
2
+ .right {
3
+ text-align: right;
4
+ }
5
+
6
+ .center {
7
+ text-align: center;
8
+ }
9
+
10
+ .labeled {
11
+ vertical-align: top;
12
+ padding-bottom: 5px;
13
+ clear: both;
14
+ }
15
+
16
+ .labeled label {
17
+ width: 120px;
18
+ padding-right: 5px;
19
+ float: left;
20
+ }
21
+
22
+ .labeled .value {
23
+ margin-left: 130px;
24
+ }
25
+
26
+ .labeled .value p {
27
+ margin: 0;
28
+ }
29
+
30
+ .control-group {
31
+ clear: both;
32
+ }
33
+
34
+ .control-group label {
35
+ float: left;
36
+ width: 120px;
37
+ padding-top: 5px;
38
+ padding-right: 5px;
39
+ }
40
+
41
+ .controls {
42
+ margin-left: 130px;
43
+ }
44
+
45
+ .required {
46
+ font-size: 80%;
47
+ vertical-align: top;
48
+ margin-left: 2px;
49
+ }
50
+
51
+ #error_explanation h2 {
52
+ font-size: 100%;
53
+ margin-top: 0px;
54
+ }
55
+
56
+ #error_explanation ul {
57
+ margin-bottom: 5px;
58
+ }
59
+
60
+ .controls div.field_with_errors {
61
+ background-color: #da9;
62
+ display: inline-block;
63
+ padding: 1px 1px;
64
+ }
@@ -0,0 +1,258 @@
1
+ $container_width: 1000px;
2
+ $theme_color: #2580a2;
3
+
4
+ body, div, p, td, th {
5
+ font-family: Verdana, Geneva, Helvetica, Arial, sans-serif;
6
+ font-size: 13px;
7
+ }
8
+
9
+ body {
10
+ text-align: center;
11
+ margin: 0;
12
+ background-color: #ddf;
13
+ }
14
+
15
+ .container {
16
+ padding: 20px 20px;
17
+ margin: 0 auto;
18
+ text-align: left;
19
+ max-width: $container_width;
20
+ min-width: $container_width - 200px;
21
+ height: 100%;
22
+ background-color: #f6f6ff;
23
+ -moz-box-shadow: 0px 0px 5px $theme_color;
24
+ -webkit-box-shadow: 0px 0px 5px $theme_color;
25
+ box-shadow: 0px 0px 5px $theme_color;
26
+ }
27
+
28
+ #content {
29
+ clear: both;
30
+ padding-top: 5px;
31
+ }
32
+
33
+ h1 {
34
+ font-size: 150%;
35
+ margin: 30px 0 15px 0;
36
+ }
37
+
38
+ .table thead tr:nth-child(odd), .table thead tr:nth-child(even) {
39
+ background-color: #D0D0D0;
40
+ }
41
+
42
+ .table tr:nth-child(odd) {
43
+ background-color: #F8F8F8;
44
+ }
45
+
46
+ .table tr:nth-child(even) {
47
+ background-color: #F0F0F0;
48
+ }
49
+
50
+ td {
51
+ vertical-align: top;
52
+ }
53
+
54
+ td p {
55
+ margin: 0;
56
+ }
57
+
58
+ a {
59
+ color: #2580a2;
60
+ text-decoration: none;
61
+ }
62
+
63
+ a:hover {
64
+ text-decoration: underline;
65
+ }
66
+
67
+ a:visited {
68
+ color: #2580a2;
69
+ }
70
+
71
+ a img {
72
+ border: none;
73
+ }
74
+
75
+ .table {
76
+ margin-top: 10px;
77
+ }
78
+
79
+ table.table {
80
+ border-collapse: collapse;
81
+ width: 100%;
82
+ padding: 0;
83
+ }
84
+
85
+ /* div rendered if no entries available for list */
86
+ div.table {}
87
+
88
+ table.table th {
89
+ text-align: left;
90
+ background-color: $theme_color;
91
+ color: white;
92
+ font-weight: bold;
93
+ padding: 2px 4px;
94
+ }
95
+
96
+ table.table th a {
97
+ color: white;
98
+ text-decoration: none;
99
+ }
100
+
101
+ table.table td {
102
+ padding: 2px 4px;
103
+ }
104
+
105
+ table.table td.action {
106
+ width: 20px;
107
+ text-align: center;
108
+ }
109
+
110
+ label {
111
+ font-style: italic;
112
+ }
113
+
114
+ .form-actions {
115
+ margin-left: 130px;
116
+ }
117
+
118
+ a.action {
119
+ padding: 0 5px;
120
+ }
121
+
122
+ a[class^="icon-"] {
123
+ margin-right: 5px;
124
+ margin-left: 5px;
125
+ }
126
+
127
+ a[class^="icon-"] img {
128
+ vertical-align: text-top;
129
+ }
130
+
131
+ [class^="icon-"] {
132
+ width: 16px;
133
+ height: 16px;
134
+ display: inline-block;
135
+ background: no-repeat;
136
+ vertical-align: top;
137
+ }
138
+
139
+ .icon-plus { background-image: image-url('actions/add.png'); }
140
+ .icon-remove { background-image: image-url('actions/delete.png'); }
141
+ .icon-pencil { background-image: image-url('actions/edit.png'); }
142
+ .icon-list { background-image: image-url('actions/list.png'); }
143
+ .icon-zoom-in { background-image: image-url('actions/show.png'); }
144
+
145
+ input, textarea {
146
+ font-family: Verdana, Geneva, Helvetica, Arial, sans-serif;
147
+ font-size: 10px;
148
+ }
149
+
150
+ input[type=text], input[type=password] {
151
+ width: 180px;
152
+ }
153
+
154
+ input[type=number] {
155
+ width: 80px;
156
+ }
157
+
158
+ textarea {
159
+ width: 180px;
160
+ height: 80px;
161
+ }
162
+
163
+ .cancel {
164
+ font-size: 80%;
165
+ margin-left: 7px;
166
+ }
167
+
168
+ .alert {
169
+ margin: 15px;
170
+ padding: 5px 10px;
171
+ }
172
+
173
+ .alert-success {
174
+ border: solid 2px #6a6;
175
+ background-color: #afa;
176
+ }
177
+
178
+ .alert-error {
179
+ border: solid 2px #da9;
180
+ background-color: #fec;
181
+ }
182
+
183
+ .close {
184
+ float: right;
185
+ }
186
+
187
+ .pull-right {
188
+ float: right;
189
+ }
190
+
191
+ .pull-left {
192
+ float: left;
193
+ }
194
+
195
+ .navbar {
196
+ background: #333;
197
+ -moz-box-shadow: 0px 1px 1px $theme_color;
198
+ -webkit-box-shadow: 0px 1px 1px $theme_color;
199
+ box-shadow: 0px 1px 1px $theme_color;
200
+ padding: 0 20px;
201
+ max-width: $container_width;
202
+ min-width: $container_width - 200px;
203
+ height: 33px;
204
+ margin: -20px;
205
+ }
206
+
207
+ .brand {
208
+ float: left;
209
+ display: block;
210
+ font-weight: bold;
211
+ font-size: 130%;
212
+ color: #ddd;
213
+ padding: 5px;
214
+ }
215
+
216
+ a.brand:hover {
217
+ text-decoration: none;
218
+ color: #ddd;
219
+ }
220
+
221
+ .nav {
222
+ list-style: none;
223
+ margin: 0;
224
+ float: left;
225
+ }
226
+
227
+ .nav li {
228
+ float: left;
229
+ font-size: 110%;
230
+ margin: 0;
231
+ padding: 0;
232
+ }
233
+
234
+ .nav a {
235
+ background: #333 bottom right no-repeat;
236
+ color: #ddd;
237
+ display: block;
238
+ float: left;
239
+ margin: 0;
240
+ padding: 8px 12px 8px;
241
+ text-decoration: none;
242
+ }
243
+
244
+ .nav a:hover {
245
+ background: $theme_color bottom center no-repeat;
246
+ color: #fff;
247
+ }
248
+
249
+ footer {
250
+ margin: auto;
251
+ text-align: right;
252
+ max-width: $container_width;
253
+ min-width: $container_width - 200px;
254
+ }
255
+
256
+ footer * {
257
+ font-size: 80%;
258
+ }