draft_generators 0.0.3

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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +6 -0
  3. data/.document +5 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +637 -0
  6. data/Gemfile +16 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.markdown +24 -0
  9. data/Rakefile +51 -0
  10. data/VERSION +1 -0
  11. data/draft_generators.gemspec +120 -0
  12. data/lib/devise_customization_service.rb +95 -0
  13. data/lib/draft_generators.rb +8 -0
  14. data/lib/generators/draft/devise/devise_generator.rb +92 -0
  15. data/lib/generators/draft/devise/views/templates/confirmations/new.html.erb +49 -0
  16. data/lib/generators/draft/devise/views/templates/mailer/confirmation_instructions.html.erb +5 -0
  17. data/lib/generators/draft/devise/views/templates/mailer/email_changed.html.erb +7 -0
  18. data/lib/generators/draft/devise/views/templates/mailer/password_change.html.erb +3 -0
  19. data/lib/generators/draft/devise/views/templates/mailer/reset_password_instructions.html.erb +8 -0
  20. data/lib/generators/draft/devise/views/templates/mailer/unlock_instructions.html.erb +7 -0
  21. data/lib/generators/draft/devise/views/templates/passwords/edit.html.erb +83 -0
  22. data/lib/generators/draft/devise/views/templates/passwords/new.html.erb +49 -0
  23. data/lib/generators/draft/devise/views/templates/registrations/edit.html.erb +159 -0
  24. data/lib/generators/draft/devise/views/templates/registrations/new.html.erb +113 -0
  25. data/lib/generators/draft/devise/views/templates/registrations_with_sentinels/edit.html.erb +160 -0
  26. data/lib/generators/draft/devise/views/templates/registrations_with_sentinels/new.html.erb +102 -0
  27. data/lib/generators/draft/devise/views/templates/sessions/new.html.erb +51 -0
  28. data/lib/generators/draft/devise/views/templates/shared/_links.html.erb +25 -0
  29. data/lib/generators/draft/devise/views/templates/unlocks/new.html.erb +49 -0
  30. data/lib/generators/draft/devise/views/views_generator.rb +41 -0
  31. data/lib/generators/draft/layout/USAGE +49 -0
  32. data/lib/generators/draft/layout/layout_generator.rb +66 -0
  33. data/lib/generators/draft/layout/templates/_bootstrapcdn_assets.html.erb +10 -0
  34. data/lib/generators/draft/layout/templates/_flashes.html.erb +23 -0
  35. data/lib/generators/draft/layout/templates/_navbar.html.erb +75 -0
  36. data/lib/generators/draft/layout/templates/layout.html.erb +40 -0
  37. data/lib/generators/draft/model/USAGE +14 -0
  38. data/lib/generators/draft/model/model_generator.rb +42 -0
  39. data/lib/generators/draft/resource/USAGE +11 -0
  40. data/lib/generators/draft/resource/resource_generator.rb +172 -0
  41. data/lib/generators/draft/resource/templates/controllers/controller.rb +97 -0
  42. data/lib/generators/draft/resource/templates/controllers/read_only_controller.rb +13 -0
  43. data/lib/generators/draft/resource/templates/specs/crud_spec.rb +300 -0
  44. data/lib/generators/draft/resource/templates/specs/factories.rb +32 -0
  45. data/lib/generators/draft/resource/templates/views/association_new_form.html.erb +67 -0
  46. data/lib/generators/draft/resource/templates/views/create_row.html.erb +13 -0
  47. data/lib/generators/draft/resource/templates/views/destroy_row.html.erb +13 -0
  48. data/lib/generators/draft/resource/templates/views/edit_form.html.erb +72 -0
  49. data/lib/generators/draft/resource/templates/views/edit_form_with_errors.html.erb +85 -0
  50. data/lib/generators/draft/resource/templates/views/index.html.erb +102 -0
  51. data/lib/generators/draft/resource/templates/views/new_form.html.erb +73 -0
  52. data/lib/generators/draft/resource/templates/views/new_form_with_errors.html.erb +86 -0
  53. data/lib/generators/draft/resource/templates/views/show.html.erb +90 -0
  54. data/lib/generators/draft/resource/templates/views/update_row.html.erb +9 -0
  55. data/lib/generators/draft/scaffold/scaffold_controller_generator.rb +16 -0
  56. data/lib/generators/draft/scaffold/scaffold_erb_generator.rb +25 -0
  57. data/lib/generators/draft/scaffold/scaffold_generator.rb +15 -0
  58. data/lib/generators/draft/scaffold/templates/_card.html.erb +37 -0
  59. data/lib/generators/draft/scaffold/templates/_form.html.erb +44 -0
  60. data/lib/generators/draft/scaffold/templates/_list_item.html.erb +13 -0
  61. data/lib/generators/draft/scaffold/templates/_table_row.html.erb +23 -0
  62. data/lib/generators/draft/scaffold/templates/edit.html.erb +17 -0
  63. data/lib/generators/draft/scaffold/templates/index.html.erb +71 -0
  64. data/lib/generators/draft/scaffold/templates/new.html.erb +17 -0
  65. data/lib/generators/draft/scaffold/templates/show.html.erb +5 -0
  66. data/lib/rails_tag_service.rb +47 -0
  67. metadata +197 -0
@@ -0,0 +1,66 @@
1
+ module Draft
2
+ class LayoutGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ class_option :theme, type: :string, default: "none", desc: "Bootstrap theme"
6
+ class_option :layout_file, type: :string, default: "application", desc: "Layout filename"
7
+ class_option :skip_cdn, type: :boolean, default: false, desc: "Skip connecting CDN assets"
8
+
9
+ def generate_layout
10
+ if bootswatch?
11
+ log :insert, "Adding #{theme_name.capitalize} Bootswatch"
12
+ else
13
+ log :insert, "Adding Bootstrap"
14
+ end
15
+
16
+ log :insert, "Adding Font Awesome"
17
+ log :insert, "Adding navbar"
18
+ log :insert, "Adding alerts"
19
+ log :insert, "Adding sticky footer; you may need to add
20
+
21
+ padding-bottom: 70px
22
+
23
+ to the body of the document."
24
+
25
+ template "layout.html.erb", "app/views/layouts/#{options["layout_file"]}.html.erb"
26
+
27
+ template "_navbar.html.erb", "app/views/shared/_navbar.html.erb"
28
+
29
+ template "_flashes.html.erb", "app/views/shared/_flashes.html.erb"
30
+
31
+ unless skip_cdn?
32
+ template "_bootstrapcdn_assets.html.erb", "app/views/shared/_bootstrapcdn_assets.html.erb"
33
+ end
34
+ end
35
+
36
+ protected
37
+
38
+ def bootswatch?
39
+ if theme_name.present?
40
+ theme_name != "none"
41
+ end
42
+ end
43
+
44
+ def theme_name
45
+ options["theme"].downcase
46
+ end
47
+
48
+ def skip_cdn?
49
+ options["skip_cdn"]
50
+ end
51
+
52
+ def app_resources
53
+ route_names.reject { |name| /^rails_info.*/.match(name) || /^rails_mailers.*/.match(name) || name.pluralize != name }
54
+ end
55
+
56
+ def devise_routes
57
+ route_names.map do |name|
58
+ /new_(.*)_registration/.match(name)
59
+ end.compact
60
+ end
61
+
62
+ def route_names
63
+ @route_names ||= Rails.application.routes.routes.map(&:name).uniq.compact
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,10 @@
1
+ <% if bootswatch? -%>
2
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/4.0.0-beta.3/<%= theme_name %>/bootstrap.min.css">
3
+ <% else -%>
4
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
5
+ <% end -%>
6
+ <link rel="stylesheet"href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" >
7
+
8
+ <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
10
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
@@ -0,0 +1,23 @@
1
+ <div class="row">
2
+ <div class="col-md-12">
3
+ <%% if notice.present? %>
4
+ <div class="alert alert-success alert-dismissable" role="alert">
5
+ <%%= notice %>
6
+
7
+ <button type="button" class="close" data-dismiss="alert" aria-label="Close">
8
+ <span aria-hidden="true">&times;</span>
9
+ </button>
10
+ </div>
11
+ <%% end %>
12
+
13
+ <%% if alert.present? %>
14
+ <div class="alert alert-warning alert-dismissable" role="alert">
15
+ <%%= alert %>
16
+
17
+ <button type="button" class="close" data-dismiss="alert" aria-label="Close">
18
+ <span aria-hidden="true">&times;</span>
19
+ </button>
20
+ </div>
21
+ <%% end %>
22
+ </div>
23
+ </div>
@@ -0,0 +1,75 @@
1
+ <nav class="navbar navbar-expand-lg navbar-light bg-light mb-4">
2
+ <div class="container">
3
+ <a class="navbar-brand" href="/">
4
+ <%= Rails.application.class.parent_name %>
5
+ </a>
6
+
7
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsible-nav-links" aria-controls="collapsible-nav-links" aria-expanded="false" aria-label="Toggle navigation">
8
+ <span class="navbar-toggler-icon"></span>
9
+ </button>
10
+
11
+ <div class="collapse navbar-collapse" id="collapsible-nav-links">
12
+ <ul class="navbar-nav mr-auto">
13
+ <li class="nav-item dropdown">
14
+ <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
15
+ Resources
16
+ </a>
17
+ <div class="dropdown-menu" aria-labelledby="navbarDropdown">
18
+ <% app_resources.each do |resource| -%>
19
+ <a href="/<%= resource %>" class="dropdown-item">
20
+ <%= resource.humanize.titleize %>
21
+ </a>
22
+ <% end -%>
23
+ </div>
24
+ </li>
25
+ </ul>
26
+ <% if devise_routes.any? -%>
27
+ <% devise_routes.each do |devise_route| -%>
28
+ <ul class="navbar-nav">
29
+ <%% if current_<%= devise_route[1]%>.blank? %>
30
+ <li class="nav-item">
31
+ <a href="/<%= devise_route[1].pluralize %>/sign_in" class="nav-link">
32
+ <% if devise_routes.size > 1 -%>
33
+ <%= devise_route[1].classify %> sign in
34
+ <% else -%>
35
+ Sign in
36
+ <% end -%>
37
+ </a>
38
+ </li>
39
+
40
+ <li class="nav-item">
41
+ <a href="/<%= devise_route[1].pluralize %>/sign_up" class="nav-link">
42
+ <% if devise_routes.size > 1 -%>
43
+ <%= devise_route[1].classify %> sign up
44
+ <% else -%>
45
+ Sign up
46
+ <% end -%>
47
+ </a>
48
+ </li>
49
+ <%% else %>
50
+ <li class="nav-item">
51
+ <a href="/<%= devise_route[1].pluralize %>/edit" class="nav-link">
52
+ <% if devise_routes.size > 1 -%>
53
+ <%= devise_route[1].classify %> edit profile
54
+ <% else -%>
55
+ Edit profile
56
+ <% end -%>
57
+ </a>
58
+ </li>
59
+
60
+ <li class="nav-item">
61
+ <a href="/<%= devise_route[1].pluralize %>/sign_out" data-method="delete" class="nav-link">
62
+ <% if devise_routes.size > 1 -%>
63
+ <%= devise_route[1].classify %> sign out
64
+ <% else -%>
65
+ Sign out
66
+ <% end -%>
67
+ </a>
68
+ </li>
69
+ <%% end %>
70
+ </ul>
71
+ <% end -%>
72
+ <% end -%>
73
+ </div> <!-- .navbar-collapse -->
74
+ </div> <!-- .container -->
75
+ </nav>
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>
5
+ <%= Rails.application.class.parent_name %>
6
+ </title>
7
+
8
+ <% unless skip_cdn? -%>
9
+ <%%= render "shared/bootstrapcdn_assets" %>
10
+
11
+ <% end -%>
12
+ <%%= csrf_meta_tags %>
13
+
14
+ <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
15
+ <%%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
16
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.0.0-alpha14/css/tempusdominus-bootstrap-4.min.css" />
17
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.0.0-alpha14/js/tempusdominus-bootstrap-4.min.js"></script>
18
+ <script src="//maps.google.com/maps/api/js?v=3.24&key=AIzaSyCOTPWiuvyyo6sKoIBzKA4-1ol-vTOIOlM"></script>
19
+ <script src="//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"></script>
20
+
21
+
22
+ <meta name="viewport" content="width=device-width, initial-scale=1">
23
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
24
+ <meta charset="utf-8">
25
+ <style>
26
+ body { padding-bottom: 70px }
27
+ </style>
28
+ </head>
29
+
30
+ <body>
31
+ <%%= render "shared/navbar" %>
32
+
33
+ <div class="container">
34
+ <%%= render "shared/flashes" %>
35
+
36
+ <%%= yield %>
37
+ </div>
38
+
39
+ </body>
40
+ </html>
@@ -0,0 +1,14 @@
1
+ Description:
2
+
3
+ Generates the files you need to get started saving information to a
4
+ database table:
5
+
6
+ - A Ruby script that will create the database table (called a "migration")
7
+ - A Ruby class that will serve as a translator for talking to the table
8
+ (called a "model")
9
+ - A file that will make it easy to manage the table using the Active Admin
10
+ gem
11
+
12
+ Examples:
13
+
14
+ rails generate draft:model photo source:string caption:text
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/named_base"
4
+
5
+ module Draft
6
+ class ModelGenerator < Rails::Generators::NamedBase
7
+ argument :attributes, type: :array, default: [],
8
+ banner: "field[:type][:index] field[:type][:index]"
9
+ def generate_model
10
+ invoke "model"
11
+ end
12
+
13
+ def generate_active_admin
14
+ if Gem.loaded_specs.has_key? "activeadmin"
15
+ invoke "active_admin:resource", [singular_table_name]
16
+
17
+ permit_active_admin_params
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def permit_active_admin_params
24
+ if File.exist?("app/admin/#{singular_table_name}.rb")
25
+ insert_code(singular_table_name)
26
+ elsif File.exist?("app/admin/#{plural_table_name}.rb")
27
+ insert_code(plural_table_name)
28
+ end
29
+ end
30
+
31
+ def insert_code(file_name)
32
+ sentinel = /.*ActiveAdmin.register.*do.*/
33
+ inside "app" do
34
+ inside "admin" do
35
+ insert_into_file "#{file_name}.rb", after: sentinel do
36
+ "\n permit_params #{attributes_names.map { |name| ":#{name}" }.join(', ')}\n"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ Description:
2
+
3
+ Generates an entire database-backed CRUD resource with a web interface:
4
+
5
+ - the database table (migration to create it)
6
+ - the model to interact with it
7
+ - routes, controller, and views for users to CRUD
8
+
9
+ Examples:
10
+
11
+ rails generate draft:resource post title body:text published:boolean
@@ -0,0 +1,172 @@
1
+ module Draft
2
+ class ResourceGenerator < Rails::Generators::NamedBase
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
6
+ class_option :skip_model, type: :boolean, default: false, desc: "Skip model, migration, and specs"
7
+ class_option :skip_controller, type: :boolean, default: false, desc: "Skip controller and routes"
8
+ class_option :read_only, type: :boolean, default: false, desc: "Only generates the index and show actions"
9
+ class_option :skip_validation_alerts, type: :boolean, default: false, desc: "Skip validation failure alerts"
10
+ class_option :skip_post, type: :boolean, default: false, desc: "Skip HTTP POST verb"
11
+ class_option :skip_redirect, type: :boolean, default: false, desc: "Skip redirecting after create, update, and destroy"
12
+ class_option :only_new_form, type: :boolean, default: false, desc: "Generate association new form"
13
+ class_option :new_form_name, type: :string, default: "", desc: "Partial name"
14
+ class_option :associated_table_name, type: :string, default: "", desc: "Associatiated table name"
15
+ class_option :with_sentinels, type: :boolean, default: false, desc: "Skip adding comments to generated files"
16
+
17
+ def generate_controller
18
+ return if skip_controller?
19
+
20
+ if read_only?
21
+ template "controllers/read_only_controller.rb", "app/controllers/#{plural_table_name.underscore}_controller.rb"
22
+ else
23
+ template "controllers/controller.rb", "app/controllers/#{plural_table_name.underscore}_controller.rb"
24
+ end
25
+ end
26
+
27
+ def generate_model
28
+ return if skip_model?
29
+ invoke "draft:model"
30
+ end
31
+
32
+ def create_root_folder
33
+ empty_directory File.join("app/views", "#{singular_table_name}_templates")
34
+ end
35
+
36
+ def generate_view_files
37
+ available_views.each do |view|
38
+ filename = view_filename_with_extensions(view)
39
+ template filename, File.join("app/views", "#{singular_table_name}_templates", File.basename(options[:new_form_name].presence || filename))
40
+ end
41
+ end
42
+
43
+ def generate_routes
44
+ return if skip_controller?
45
+
46
+ if read_only?
47
+ read_only_routes
48
+ else
49
+ golden_seven_routes
50
+ end
51
+ end
52
+
53
+ def generate_specs
54
+ # Hotfix to prevent specs during MSM Associations
55
+ return
56
+ # return if read_only? || skip_controller? || skip_model?
57
+
58
+ template "specs/crud_spec.rb", "spec/features/crud_#{plural_table_name.underscore}_spec.rb"
59
+ template "specs/factories.rb", "spec/factories/#{plural_table_name.underscore}.rb"
60
+ end
61
+
62
+ private
63
+
64
+ def golden_seven_routes
65
+ log :route, "RESTful routes"
66
+
67
+ route <<-RUBY.gsub(/^ /, "")
68
+
69
+ # Routes for the #{singular_table_name.humanize} resource:
70
+
71
+ # CREATE
72
+ get("/#{plural_table_name}/new", { :controller => "#{plural_table_name}", :action => "new_form" })
73
+ #{skip_post? ? "get" : "post"}("/create_#{singular_table_name}", { :controller => "#{plural_table_name}", :action => "create_row" })
74
+
75
+ # READ
76
+ get("/#{plural_table_name}", { :controller => "#{plural_table_name}", :action => "index" })
77
+ get("/#{plural_table_name}/:id_to_display", { :controller => "#{plural_table_name}", :action => "show" })
78
+
79
+ # UPDATE
80
+ get("/#{plural_table_name}/:prefill_with_id/edit", { :controller => "#{plural_table_name}", :action => "edit_form" })
81
+ #{skip_post? ? "get" : "post"}("/update_#{singular_table_name}/:id_to_modify", { :controller => "#{plural_table_name}", :action => "update_row" })
82
+
83
+ # DELETE
84
+ get("/delete_#{singular_table_name}/:id_to_remove", { :controller => "#{plural_table_name}", :action => "destroy_row" })
85
+
86
+ #------------------------------
87
+ RUBY
88
+ end
89
+
90
+ def read_only_routes
91
+ log :route, "Index and show routes"
92
+
93
+ route <<-RUBY.gsub(/^ /, "")
94
+
95
+ # Routes for the #{singular_table_name.humanize} resource:
96
+
97
+ # READ
98
+ get("/#{plural_table_name}", { :controller => "#{plural_table_name}", :action => "index" })
99
+ get("/#{plural_table_name}/:id_to_display", { :controller => "#{plural_table_name}", :action => "show" })
100
+
101
+ #------------------------------
102
+ RUBY
103
+ end
104
+
105
+ def skip_controller?
106
+ options[:skip_controller] || options[:only_new_form]
107
+ end
108
+
109
+ def skip_model?
110
+ options[:skip_model] || options[:only_new_form]
111
+ end
112
+
113
+ def read_only?
114
+ options[:read_only]
115
+ end
116
+
117
+ def skip_validation_alerts?
118
+ options[:skip_validation_alerts]
119
+ end
120
+
121
+ def skip_post?
122
+ options[:skip_post]
123
+ end
124
+
125
+ def skip_redirect?
126
+ options[:skip_redirect]
127
+ end
128
+
129
+ def only_new_form?
130
+ options[:only_new_form]
131
+ end
132
+
133
+ def with_sentinels?
134
+ options[:with_sentinels]
135
+ end
136
+
137
+ def new_form_hidden_variable
138
+ "@#{options[:associated_table_name].singularize}.id"
139
+ end
140
+
141
+ def new_form_create_path
142
+ "create_#{singular_table_name}_from_#{options[:associated_table_name].singularize}"
143
+ end
144
+
145
+ def route(routing_code)
146
+ sentinel = /\.routes\.draw do(?:\s*\|map\|)?\s*$/
147
+
148
+ inside "config" do
149
+ insert_into_file "routes.rb", routing_code, after: sentinel
150
+ end
151
+ end
152
+
153
+ def available_views
154
+ if read_only?
155
+ %w(index show)
156
+ elsif skip_redirect?
157
+ %w(index show new_form create_row edit_form update_row destroy_row)
158
+ elsif only_new_form?
159
+ %w(association_new_form)
160
+ else
161
+ %w(index new_form new_form_with_errors edit_form edit_form_with_errors show)
162
+ end
163
+ end
164
+
165
+ def view_filename_with_extensions(name)
166
+ filename = [name, :html, :erb].compact.join(".")
167
+ folders = ["views"]
168
+ filename = File.join(folders, filename) if folders.any?
169
+ filename
170
+ end
171
+ end
172
+ end