hot-glue 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +70 -0
- data/lib/generators/hot_glue/layout/builder.rb +2 -2
- data/lib/generators/hot_glue/markup_templates/erb.rb +1 -1
- data/lib/generators/hot_glue/scaffold_generator.rb +59 -22
- data/lib/generators/hot_glue/templates/erb/_list.erb +22 -19
- data/lib/generators/hot_glue/templates/erb/_new_form.erb +1 -1
- data/lib/hotglue/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afc68861e358b8c531dc375f1430773020b486019ea649e81fb428fcf1e16176
|
4
|
+
data.tar.gz: a1120fd066f8a36cccc5a2f909f9d7dd64e2e8bb1f2a20c4a7c8a88829b014b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d7e6a3503778e7403af19cee81120a30a79b8463a34f6458919091d95531636f9c4251b7c0c4b25542855f718481960610d3d94d41691d0216c2ccac9b29cde
|
7
|
+
data.tar.gz: a5c32f698bd91486f7100b936e3eafd2333656de8bc2e1ddbcdf56351b9248aad1dd4934da8736d9c072c6bcac901af9d9043c6e9014bcd9beb3b700a28c3284
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -623,6 +623,69 @@ You will need to build scaffolding with the same name for the related object as
|
|
623
623
|
On the list view, the object you are currently building will be built with a sub-view list of the objects related from the given line.
|
624
624
|
|
625
625
|
|
626
|
+
### `--alt-controller-name`
|
627
|
+
|
628
|
+
Normally a controller a has a natural name based on the model (the Thing model produces a `ThingsController`).
|
629
|
+
|
630
|
+
Within any given namespace, you can have only one natural controller for that model, of course, because all the controllers exist at the namespace directory even when they are nested.
|
631
|
+
|
632
|
+
For example, let's say you have an Admin dashboard with User has_many :invoices
|
633
|
+
|
634
|
+
Your routes file will nest your invoices within your users (for whatever namespace you are building)
|
635
|
+
|
636
|
+
```
|
637
|
+
namespace :admin do
|
638
|
+
resources :users do
|
639
|
+
resources :invoices
|
640
|
+
end
|
641
|
+
end
|
642
|
+
```
|
643
|
+
|
644
|
+
Therefore, your namespace can typically only view that model in one context. If that context is nested (using `--nest` exists at a nested route), it can only be used in the context of that nest (which probably requires one or more parent objects to be in the nested route of your URL).
|
645
|
+
|
646
|
+
You should preserve this naming convention, and stay within those guides so your nested routes work when this object is nested within another object's view. (For the context of that or any namespace.)
|
647
|
+
|
648
|
+
Alternative controller names let you specify a controller name that is nameed _something else_ but still edits the given object/table.
|
649
|
+
|
650
|
+
In the example above, you'd add another top-level route in the same namespace called "all_X".
|
651
|
+
|
652
|
+
For example,
|
653
|
+
|
654
|
+
**config/routes.rb**
|
655
|
+
```
|
656
|
+
namespace :admin do
|
657
|
+
resources :users do
|
658
|
+
resources :invoices
|
659
|
+
end
|
660
|
+
resources :all_invoices
|
661
|
+
end
|
662
|
+
```
|
663
|
+
|
664
|
+
Then you'd build normal nested scaffold like so:
|
665
|
+
|
666
|
+
```
|
667
|
+
rails generate hot_glue:scaffold User --namespace=admin --gd
|
668
|
+
|
669
|
+
rails generate hot_glue:scaffold Invoice --namespace=admin --nest=users --gd
|
670
|
+
|
671
|
+
```
|
672
|
+
You'd build another Invoices controller like this:
|
673
|
+
|
674
|
+
```
|
675
|
+
rails generate hot_glue:scaffold Invoice --namespace=admin --alt-controller-name=AllInvoices --gd
|
676
|
+
```
|
677
|
+
|
678
|
+
Note that all three builds here are in the `admin` namespace (so build controllers at `app/controllers/admin/`) and ALSO use Gd mode.
|
679
|
+
|
680
|
+
If you extend the example conceptually you build things like "UnpaidInvoices" or "RecentInvoices" which would, for example, build contextual views for the admin user.
|
681
|
+
|
682
|
+
The difference between the one kind of Invoices controller and the other is that, in this example, the InvoicesController (the natural one) is always nested to the user. So if you ever want to know about invoices in the context of a user, that's exactly what you use.
|
683
|
+
|
684
|
+
The other one, `AllInvoicesController` or `UnpaidInvoicesController` will provide the admin a view of invoices **out of the context** of the user object.
|
685
|
+
|
686
|
+
|
687
|
+
|
688
|
+
|
626
689
|
|
627
690
|
|
628
691
|
## FLAGS (Options with no values)
|
@@ -661,6 +724,11 @@ Omits pagination. (All list views have pagination by default.)
|
|
661
724
|
|
662
725
|
Omits list action. Only makes sense to use this if you are create a view where you only want the create button you want to navigate to the update screen alternative ways.
|
663
726
|
|
727
|
+
|
728
|
+
### `--no-list-labels`
|
729
|
+
|
730
|
+
Omits list labels. (note that in the form the labels are rendered again anyway)
|
731
|
+
|
664
732
|
### `--no-create`
|
665
733
|
|
666
734
|
Omits create action.
|
@@ -711,6 +779,8 @@ Obviously, the created controller will always have this base controller as its s
|
|
711
779
|
|
712
780
|
# VERSION HISTORY
|
713
781
|
|
782
|
+
#### 2022-01-11 - v0.4.5 - buttons on smarty layouts take up 1 bootstrap column each; fixes confirmation alert for delete buttons
|
783
|
+
|
714
784
|
#### 2022-01-01 - v0.4.3 and 0.4.4 - adding fully email based license; no activation codes required
|
715
785
|
|
716
786
|
#### 2022-12-30 - v0.4.2 -- Smart layouts introduced
|
@@ -78,10 +78,10 @@ module HotGlue
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# input control
|
81
|
-
user_layout_columns =
|
81
|
+
user_layout_columns = @include_setting .split(":")
|
82
82
|
|
83
83
|
if user_layout_columns.size > available_columns
|
84
|
-
raise "Your include statement #{
|
84
|
+
raise "Your include statement #{@include_setting } has #{user_layout_columns.size} columns, but I can only construct up to #{available_columns}"
|
85
85
|
end
|
86
86
|
user_layout_columns.each_with_index do |column,i|
|
87
87
|
layout_object[:columns][:container][i] = column.split(",")
|
@@ -18,7 +18,7 @@ module HotGlue
|
|
18
18
|
small_buttons = args[0][:small_buttons]
|
19
19
|
|
20
20
|
magic_buttons.collect{ |button_name|
|
21
|
-
"<%= form_with model: #{singular}, url: #{path_helper_singular}(#{path_helper_args}), html: {style: 'display: inline',
|
21
|
+
"<%= form_with model: #{singular}, url: #{path_helper_singular}(#{path_helper_args}), html: {style: 'display: inline', data: {\"turbo-confirm\": 'Are you sure you want to #{button_name} this #{singular}?'}} do |f| %>
|
22
22
|
<%= f.hidden_field :#{button_name}, value: \"#{button_name}\" %>
|
23
23
|
<%= f.submit '#{button_name.titleize}'.html_safe, disabled: (#{singular}.respond_to?(:#{button_name}able?) && ! #{singular}.#{button_name}able? ), class: '#{singular}-button btn btn-primary #{"btn-sm" if small_buttons}' %>
|
24
24
|
<% end %>"
|
@@ -69,7 +69,8 @@ module HotGlue
|
|
69
69
|
class_option :smart_layout, type: :boolean, default: false
|
70
70
|
class_option :markup, type: :string, default: nil # deprecated -- use in app config instead
|
71
71
|
class_option :layout, type: :string, default: nil # if used here it will override what is in the config
|
72
|
-
|
72
|
+
class_option :no_list_labels, type: :boolean, default: false
|
73
|
+
class_option :alt_controller_name, type: :string, default: nil
|
73
74
|
|
74
75
|
def initialize(*meta_args)
|
75
76
|
super
|
@@ -140,14 +141,34 @@ module HotGlue
|
|
140
141
|
end
|
141
142
|
|
142
143
|
args = meta_args[0]
|
144
|
+
|
145
|
+
|
143
146
|
@singular = args.first.tableize.singularize # should be in form hello_world
|
144
147
|
@plural = options['plural'] || @singular + "s" # supply to override; leave blank to use default
|
148
|
+
@namespace = options['namespace'] || nil
|
149
|
+
|
150
|
+
|
151
|
+
@alt_controller_name = options['alt_controller_name']
|
152
|
+
use_controller_name = @alt_controller_name || plural.titleize.gsub(" ", "")
|
153
|
+
|
154
|
+
@controller_build_name = (( @namespace.titleize + "::" if @namespace) || "") + use_controller_name + "Controller"
|
155
|
+
@controller_build_folder = use_controller_name.underscore
|
156
|
+
|
157
|
+
if ! @controller_build_folder.ends_with?("s")
|
158
|
+
raise "can't build with controller name #{@controller_build_folder} because it doesn't end with an 's'"
|
159
|
+
end
|
160
|
+
|
161
|
+
if @alt_controller_name
|
162
|
+
@controller_build_folder_singular = @controller_build_folder.gsub(/s$/,'')
|
163
|
+
else
|
164
|
+
@controller_build_folder_singular = singular
|
165
|
+
end
|
166
|
+
|
145
167
|
@auth = options['auth'] || "current_user"
|
146
168
|
@auth_identifier = options['auth_identifier'] || (! @god && @auth.gsub("current_", "")) || nil
|
147
169
|
|
148
170
|
|
149
171
|
@nest = (!options['nest'].empty? && options['nest']) || nil
|
150
|
-
@namespace = options['namespace'] || nil
|
151
172
|
|
152
173
|
@singular_class = @singular.titleize.gsub(" ", "")
|
153
174
|
@exclude_fields = []
|
@@ -166,7 +187,6 @@ module HotGlue
|
|
166
187
|
@show_only += options['show_only'].split(",").collect(&:to_sym)
|
167
188
|
end
|
168
189
|
|
169
|
-
|
170
190
|
@god = options['god'] || options['gd'] || false
|
171
191
|
@specs_only = options['specs_only'] || false
|
172
192
|
|
@@ -179,13 +199,13 @@ module HotGlue
|
|
179
199
|
|
180
200
|
@no_edit = options['no_edit'] || false
|
181
201
|
@no_list = options['no_list'] || false
|
182
|
-
|
202
|
+
@no_list_labels = options['no_list_labels'] || false
|
183
203
|
@display_list_after_update = options['display_list_after_update'] || false
|
184
204
|
@smart_layout = options['smart_layout']
|
185
205
|
|
186
206
|
|
187
|
-
@container_name = @layout == "hotglue" ? "scaffold-container" : "container-fluid"
|
188
207
|
|
208
|
+
@container_name = @layout == "hotglue" ? "scaffold-container" : "container-fluid"
|
189
209
|
@downnest = options['downnest'] || false
|
190
210
|
|
191
211
|
@downnest_children = []
|
@@ -243,6 +263,7 @@ module HotGlue
|
|
243
263
|
|
244
264
|
|
245
265
|
@ujs_syntax = options['ujs_syntax']
|
266
|
+
|
246
267
|
if !@ujs_syntax
|
247
268
|
@ujs_syntax = !defined?(Turbo::Engine)
|
248
269
|
puts "You did not specify ujs_syntax and so I default it to #{@ujs_syntax}"
|
@@ -273,23 +294,33 @@ module HotGlue
|
|
273
294
|
auth_assoc_field = auth_assoc + "_id" unless @god
|
274
295
|
assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
|
275
296
|
|
297
|
+
|
276
298
|
if assoc
|
277
299
|
@ownership_field = assoc.name.to_s + "_id"
|
278
300
|
elsif !@nest
|
279
301
|
exit_message = "*** Oops: It looks like is no association from current_#{@object_owner_sym} to a class called #{@singular_class}. If your user is called something else, pass with flag auth=current_X where X is the model for your users as lowercase. Also, be sure to implement current_X as a method on your controller. (If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for auth_identifier.) To make a controller that can read all records, specify with --god."
|
280
302
|
|
281
303
|
else
|
304
|
+
exit_message = "*** Oops: Missing relationship from class #{singular_class} to :#{@object_owner_sym} \n
|
305
|
+
maybe add `belongs_to :#{@object_owner_sym}` to #{singular_class}\n
|
306
|
+
(If your user is called something else, pass with flag auth=current_X where X is the model for your auth object as lowercase.
|
307
|
+
Also, be sure to implement current_X as a method on your controller. If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for --auth-identifier flag)
|
308
|
+
|
309
|
+
To make a controller that can read all records, specify with --god."
|
310
|
+
|
282
311
|
if @god
|
283
|
-
exit_message
|
312
|
+
exit_message << "does #{singular_class} have a relOops: Gd mode could not find the association(#{@object_owner_sym}). Something is wrong."
|
284
313
|
else
|
314
|
+
|
285
315
|
@auth_check = eval(@auth_identifier.titleize)
|
286
316
|
@nested_args.each do |arg|
|
317
|
+
|
287
318
|
if ! @auth_check.reflect_on_association("#{arg}s".to_sym)
|
288
|
-
exit_message
|
319
|
+
exit_message << "... your nesting chain does not have a association for #{arg}s on #{@auth_check} something is wrong."
|
289
320
|
end
|
290
321
|
end
|
291
322
|
end
|
292
|
-
puts exit_message
|
323
|
+
puts "\n" + exit_message
|
293
324
|
raise(HotGlue::Error, exit_message)
|
294
325
|
end
|
295
326
|
end
|
@@ -369,7 +400,7 @@ module HotGlue
|
|
369
400
|
def copy_controller_and_spec_files
|
370
401
|
@default_colspan = @columns.size
|
371
402
|
unless @specs_only
|
372
|
-
template "controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "#{
|
403
|
+
template "controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "#{@controller_build_folder}_controller.rb")
|
373
404
|
if @namespace
|
374
405
|
begin
|
375
406
|
eval(controller_descends_from)
|
@@ -473,10 +504,7 @@ module HotGlue
|
|
473
504
|
|
474
505
|
|
475
506
|
def controller_class_name
|
476
|
-
|
477
|
-
res << @namespace.titleize + "::" if @namespace
|
478
|
-
res << plural.titleize.gsub(" ", "") + "Controller"
|
479
|
-
res
|
507
|
+
@controller_build_name
|
480
508
|
end
|
481
509
|
|
482
510
|
def singular_name
|
@@ -501,15 +529,15 @@ module HotGlue
|
|
501
529
|
|
502
530
|
def path_helper_singular
|
503
531
|
if @nest
|
504
|
-
"#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{
|
532
|
+
"#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{@controller_build_folder_singular}_path"
|
505
533
|
else
|
506
|
-
"#{@namespace+"_" if @namespace}#{
|
534
|
+
"#{@namespace+"_" if @namespace}#{@controller_build_folder_singular}_path"
|
507
535
|
end
|
508
536
|
end
|
509
537
|
|
510
538
|
def path_helper_plural
|
511
539
|
if ! @nest
|
512
|
-
"#{@namespace+"_" if @namespace}#{
|
540
|
+
"#{@namespace+"_" if @namespace}#{@controller_build_folder}_path"
|
513
541
|
else
|
514
542
|
"#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{plural}_path"
|
515
543
|
end
|
@@ -524,19 +552,19 @@ module HotGlue
|
|
524
552
|
end
|
525
553
|
|
526
554
|
def line_path_partial
|
527
|
-
"#{@namespace+"/" if @namespace}#{
|
555
|
+
"#{@namespace+"/" if @namespace}#{@controller_build_folder}/line"
|
528
556
|
end
|
529
557
|
|
530
558
|
def show_path_partial
|
531
|
-
"#{@namespace+"/" if @namespace}#{
|
559
|
+
"#{@namespace+"/" if @namespace}#{@controller_build_folder}/show"
|
532
560
|
end
|
533
561
|
|
534
562
|
def list_path_partial
|
535
|
-
"#{@namespace+"/" if @namespace}#{
|
563
|
+
"#{@namespace+"/" if @namespace}#{@controller_build_folder}/list"
|
536
564
|
end
|
537
565
|
|
538
566
|
def new_path_name
|
539
|
-
base = "new_#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_") if @nested_args.any?}#{
|
567
|
+
base = "new_#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_") if @nested_args.any?}#{@controller_build_folder_singular}_path"
|
540
568
|
if @nested_args.any?
|
541
569
|
base += "(" + @nested_args.collect { |arg|
|
542
570
|
"#{arg}.id"
|
@@ -643,7 +671,7 @@ module HotGlue
|
|
643
671
|
|
644
672
|
|
645
673
|
dest_filepath = File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}",
|
646
|
-
|
674
|
+
@controller_build_folder, dest_filename)
|
647
675
|
|
648
676
|
|
649
677
|
template source_filename, dest_filepath
|
@@ -657,7 +685,7 @@ module HotGlue
|
|
657
685
|
source_filename = cc_filename_with_extensions( "#{@markup}/#{view}.turbo_stream.#{@markup}")
|
658
686
|
dest_filename = cc_filename_with_extensions("#{view}", "turbo_stream.#{@markup}")
|
659
687
|
dest_filepath = File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}",
|
660
|
-
|
688
|
+
@controller_build_folder, dest_filename)
|
661
689
|
|
662
690
|
|
663
691
|
template source_filename, dest_filepath
|
@@ -665,6 +693,15 @@ module HotGlue
|
|
665
693
|
|
666
694
|
end
|
667
695
|
end
|
696
|
+
|
697
|
+
# menu_file = "app/views#{namespace_with_dash}/menu.erb"
|
698
|
+
#
|
699
|
+
# if File.exists?(menu_file)
|
700
|
+
# # TODO: can I insert the new menu item into the menu programatically here?
|
701
|
+
# # not sure how i would acheive this without nokogiri
|
702
|
+
#
|
703
|
+
# end
|
704
|
+
|
668
705
|
end
|
669
706
|
|
670
707
|
def namespace_with_dash
|
@@ -2,30 +2,33 @@
|
|
2
2
|
<div class="<%= @container_name %> scaffold-list">
|
3
3
|
<% unless @no_list || @nested_args.any? %><h4><%= plural.gsub("_", " ").upcase %></h4><% end %>
|
4
4
|
|
5
|
-
<% unless @no_create %><%= '<%= render partial: "' + ((@namespace+"/" if @namespace) || "") +
|
5
|
+
<% unless @no_create %><%= '<%= render partial: "' + ((@namespace+"/" if @namespace) || "") + @controller_build_folder + '/new_button", locals: {' + nested_assignments + '}' + '%\>'.gsub('\\',"") %><br /><% end %>
|
6
6
|
|
7
|
-
<% unless @no_list
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
<% unless @no_list %>
|
8
|
+
<% unless @no_list_labels %>
|
9
|
+
<div class="row scaffold-heading-row">
|
10
|
+
<%= list_column_headings %>
|
11
|
+
<% if @downnest_children.any? %>
|
12
|
+
<% each_downnest_width = @downnest_children.count == 1 ? 40 : (60/@downnest_children.count).floor %>
|
13
|
+
<% downnest_column_style = @layout == "hotglue" ? 'style="flex-basis: ' + each_downnest_width.to_s + '%;' : "" %>
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
<% @downnest_children.each_with_index do |downnest,i| %>
|
16
|
+
<div class=" scaffold-col-heading<%= " col-sm-#{ @layout_object[:portals][downnest][:size] }" if @layout=="bootstrap" %>" <%= downnest_column_style %>>
|
17
|
+
<strong>
|
18
|
+
<%= downnest.titleize %>
|
19
|
+
</strong>
|
20
|
+
</div>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
22
23
|
|
23
|
-
|
24
|
+
<% button_column_style = @layout == "hotglue" ? 'style="flex-basis: 150px' : "" %>
|
24
25
|
|
25
|
-
|
26
|
+
<div class=' scaffold-col-heading scaffold-col-heading-buttons<%= " col-md-#{ @layout_object[:buttons][:size] }" if @layout=="bootstrap" %>' <%= button_column_style %>>
|
27
|
+
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<% end %>
|
26
31
|
|
27
|
-
</div>
|
28
|
-
</div>
|
29
32
|
<\% if <%= plural %>.empty? %>
|
30
33
|
<div>
|
31
34
|
None
|
@@ -3,6 +3,6 @@
|
|
3
3
|
New <%= singular.titlecase %>
|
4
4
|
</h3>
|
5
5
|
<\%= form_with model: <%= singular %>, url: <%= path_helper_plural %>(<%= nested_objects_arity %>), method: "post" do |f| %>
|
6
|
-
<\%= render partial: "<%= namespace_with_slash +
|
6
|
+
<\%= render partial: "<%= namespace_with_slash + @controller_build_folder %>/form", locals: { <%= singular %>: <%= singular %>, f: f} %>
|
7
7
|
<\% end %>
|
8
8
|
<\% end %>
|
data/lib/hotglue/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hot-glue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Fleetwood-Boldt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-01-
|
11
|
+
date: 2022-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|