hobo 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. data/hobo_files/plugin/CHANGES.txt +84 -0
  2. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +10 -10
  3. data/hobo_files/plugin/generators/hobo_model/templates/unit_test.rb +1 -3
  4. data/hobo_files/plugin/generators/hobo_model_controller/templates/functional_test.rb +1 -11
  5. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +5 -1
  6. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +80 -35
  7. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +1 -9
  8. data/hobo_files/plugin/generators/hobo_user_controller/templates/functional_test.rb +1 -11
  9. data/hobo_files/plugin/generators/hobo_user_model/templates/fixtures.yml +16 -2
  10. data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +1 -1
  11. data/hobo_files/plugin/generators/hobo_user_model/templates/unit_test.rb +1 -3
  12. data/hobo_files/plugin/lib/hobo/dryml.rb +5 -4
  13. data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +3 -3
  14. data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +9 -11
  15. data/hobo_files/plugin/lib/hobo/dryml/template.rb +1 -1
  16. data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +23 -15
  17. data/hobo_files/plugin/lib/hobo/field_spec.rb +7 -3
  18. data/hobo_files/plugin/lib/hobo/model.rb +1 -0
  19. data/hobo_files/plugin/lib/hobo/model_controller.rb +6 -3
  20. data/hobo_files/plugin/lib/hobo/user_controller.rb +1 -1
  21. data/hobo_files/plugin/taglibs/rapid.dryml +14 -3
  22. data/hobo_files/plugin/taglibs/rapid_forms.dryml +1 -1
  23. data/hobo_files/plugin/taglibs/rapid_pages.dryml +50 -44
  24. metadata +2 -4
  25. data/hobo_files/plugin/generators/hobo_model_controller/templates/view.rhtml +0 -2
  26. data/hobo_files/plugin/generators/hobo_user_controller/templates/view.rhtml +0 -2
@@ -1,3 +1,87 @@
1
+ === Release 0.7.2 ===
2
+
3
+ Migration generator
4
+
5
+ Fixed "no such method table_name" bug
6
+
7
+ Fixed various problems with specific column types, in particular
8
+ decimal colums were problematic.
9
+
10
+
11
+ Model and controller generators:
12
+
13
+ Brought test related files up to date with latest Rails
14
+
15
+
16
+ Model controller
17
+
18
+ Fix: now correctly renders pages with validation errors for tag
19
+ pages (pages with no dryml file)
20
+
21
+ index_action and show_action can now be passed options for Hobo's
22
+ default actions rather than giving a block. e.g.
23
+
24
+ index_action :foo
25
+ hobo_index :page_size => 10
26
+ end
27
+
28
+ Can now be written
29
+
30
+ index_action :foo, :page_size => 10
31
+
32
+
33
+ Hobo user model generator
34
+
35
+ Added :default => false to administrator field
36
+
37
+
38
+ DRYML
39
+
40
+ Polymorphic tags -- looking up the polymorphic tag for an array will
41
+ now use the 'member_class' of the array if available.
42
+
43
+
44
+ Rapid
45
+
46
+ New generic tag <collection>. Used to create type-specific
47
+ renderings of collections. E.g. you can
48
+
49
+ <def tag="collection" for="Comment">
50
+
51
+ To customise how an array of comments are displayed. This will get
52
+ picked up by the default pages.
53
+
54
+
55
+ Rapid pages
56
+
57
+ Removed <default-layout/> -- dryml has built in facilities for
58
+ setting and overriding defaults so this was not needed.
59
+
60
+ Login and signup pages now specify "simple" layout, so e.g. if you
61
+ redefine <page> to use "aside" layout, then login and signup will
62
+ still use the simple layout.
63
+
64
+ Various improvements to the default pages
65
+
66
+ <index-page> new params
67
+
68
+
69
+ Plugins
70
+
71
+ Changing from hobo_* naming convention to rapid_*
72
+
73
+
74
+
75
+ Clean theme
76
+
77
+ Many small style improvements
78
+
79
+ Support for aside layout
80
+
81
+
82
+
83
+
84
+
1
85
  === Release 0.7.1 ===
2
86
 
3
87
  Hobo 0.7 is tested against Rails 2.0.1
@@ -71,8 +71,8 @@ class HoboMigrationGenerator < Rails::Generator::Base
71
71
  end
72
72
  end
73
73
 
74
- up = [renames, drops, creates, changes].flatten.select{|s|!s.blank?} * "\n\n"
75
- down = [undo_changes, undo_renames, undo_drops, undo_creates].flatten.select{|s|!s.blank?} * "\n\n"
74
+ up = [renames, drops, creates, changes].flatten.reject(&:blank?) * "\n\n"
75
+ down = [undo_changes, undo_renames, undo_drops, undo_creates].flatten.reject(&:blank?) * "\n\n"
76
76
 
77
77
  if up.blank?
78
78
  puts "Database and models match -- nothing to change"
@@ -188,7 +188,7 @@ class HoboMigrationGenerator < Rails::Generator::Base
188
188
  "remove_column :#{new_table_name}, :#{c}"
189
189
  end
190
190
  undo_removes = to_remove.map do |c|
191
- revert_column(table_name, c)
191
+ revert_column(new_table_name, c)
192
192
  end
193
193
 
194
194
  old_names = to_rename.invert
@@ -200,15 +200,15 @@ class HoboMigrationGenerator < Rails::Generator::Base
200
200
  spec = model.field_specs[c]
201
201
  if spec.different_to?(col)
202
202
  change_spec = {}
203
- change_spec[:limit] = spec.limit if !spec.limit.nil?
204
- change_spec[:precision] = spec.precision if !spec.precision.nil?
205
- change_spec[:scale] = spec.scale if !spec.scale.nil?
206
- change_spec[:null] = false unless spec.null
207
- change_spec[:default] = spec.default
203
+ change_spec[:limit] = spec.limit unless spec.limit.nil?
204
+ change_spec[:precision] = spec.precision unless spec.precision.nil?
205
+ change_spec[:scale] = spec.scale unless spec.scale.nil?
206
+ change_spec[:null] = false unless spec.null
207
+ change_spec[:default] = spec.default unless spec.default.nil? && col.default.nil?
208
208
 
209
- changes << "change_column :#{table_name}, :#{c}, " +
209
+ changes << "change_column :#{new_table_name}, :#{c}, " +
210
210
  ([":#{spec.sql_type}"] + format_options(change_spec, spec.sql_type)).join(", ")
211
- back = change_column_back(table_name, c)
211
+ back = change_column_back(new_table_name, c)
212
212
  undo_changes << back unless back.blank?
213
213
  else
214
214
  nil
@@ -1,8 +1,6 @@
1
1
  require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
2
 
3
- class <%= class_name %>Test < Test::Unit::TestCase
4
- fixtures :<%= table_name %>
5
-
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
6
4
  # Replace this with your real tests.
7
5
  def test_truth
8
6
  assert true
@@ -1,16 +1,6 @@
1
1
  require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
- require '<%= file_path %>_controller'
3
-
4
- # Re-raise errors caught by the controller.
5
- class <%= class_name %>Controller; def rescue_action(e) raise e end; end
6
-
7
- class <%= class_name %>ControllerTest < Test::Unit::TestCase
8
- def setup
9
- @controller = <%= class_name %>Controller.new
10
- @request = ActionController::TestRequest.new
11
- @response = ActionController::TestResponse.new
12
- end
13
2
 
3
+ class <%= class_name %>ControllerTest < ActionController::TestCase
14
4
  # Replace this with your real tests.
15
5
  def test_truth
16
6
  assert true
@@ -523,5 +523,9 @@ HasManyThroughInput = Behavior.create({
523
523
  })
524
524
 
525
525
  Event.addBehavior({
526
- 'div.has-many-through.input' : HasManyThroughInput()
526
+ 'div.has-many-through.input' : HasManyThroughInput(),
527
+ '.dependent-collection-count:click' : function(e) {
528
+ new Effect.ScrollTo('dependent-collection', {duration: 1.0, offset: -10, transition: Effect.Transitions.sinoidal});
529
+ Event.stop(e);
530
+ }
527
531
  });
@@ -1,13 +1,13 @@
1
1
  html {background: #666;}
2
2
  body {
3
- width: 800px; margin: 0 auto; background: white; color: #222;
3
+ width: 760px; margin: 0 auto; background: white; color: #222;
4
4
  font: 12px "Lucida Grande", Arial, sans-serif;
5
- line-height: 18px; padding-bottom: 10px; margin-bottom: 20px;
5
+ line-height: 18px; margin-bottom: 20px;
6
6
  }
7
- h1, h2, h3 {font-family: "Rockwell", "Trebuchet MS", "Arial", sans-serif;}
8
- h1 {font-size: 32px; line-height: 32px; margin: 20px 0 10px;}
9
- h2 {font-size: 24px; line-height: 24px; margin: 15px 0 10px;}
10
- h3 {font-size: 18px; line-height: 18px; margin: 10px 0 5px;}
7
+ h1, h2, h3 {font-family: "Lucida Grande", "Trebuchet MS", "Arial", sans-serif; font-weight: normal;}
8
+ h1 {font-size: 22px; line-height: 22px; margin: 20px 0 10px;}
9
+ h2 {font-size: 18px; line-height: 18px; margin: 15px 0 10px;}
10
+ h3 {font-size: 16px; line-height: 16px; margin: 10px 0 5px;}
11
11
  h4 {font-size: 14px; line-height: 14px; margin: 10px 0 5px;}
12
12
  h5 {font-size: 12px; line-height: 12px; margin: 10px 0 5px;}
13
13
  h6 {font-size: 10px; line-height: 10px; margin: 10px 0 5px;}
@@ -17,17 +17,14 @@ li {margin-left: 20px;}
17
17
  a {
18
18
  text-decoration: none; color: #222;
19
19
  border-bottom: 1px dotted #ccc;
20
- background: #f8f8f8;
20
+ background: #fafafa;
21
21
  }
22
22
  a:hover {
23
- border-bottom: 1px dotted #aaa; background: #f0f0f0; color: black;
23
+ border-bottom: 1px dotted #aaa; background: #f2f2f2; color: black;
24
24
  }
25
25
  h1 a, h2 a, h3 a {background: none; border: none;}
26
26
 
27
- /*input.text, input.string, input.email_address, input.password, textarea {
28
- border: 2px solid #444; padding: 1px;
29
- }*/
30
- input.text, input.string, input.email_address, input.password, input.search, textarea {
27
+ input.text, input.string, input.email_address, input.password, input.search, input.integer, input.float, textarea {
31
28
  font-size:1.1em;
32
29
  line-height:1.3em;
33
30
  border-top:1px solid #7c7c7c;
@@ -43,7 +40,6 @@ input.file_upload {
43
40
 
44
41
  .button {
45
42
  padding: 6px 10px;
46
- /* color: white; background: black; border: 1px solid #666;*/
47
43
  font: bold 11px "Lucida Grande", Arial, sans-serif;
48
44
  border-top:1px solid #ddd;
49
45
  border-left:1px solid #c3c3c3;
@@ -67,24 +63,46 @@ input.file_upload {
67
63
  padding: 0 20px 20px; background: #f2f2f2; border: 1px solid #ddd; color: black;
68
64
  }
69
65
  #search-results-panel .card.linkable a {
70
- /* background: #333; border-color: #444;*/ color: black;
66
+ color: black;
71
67
  }
72
68
 
73
- .content-header, .content-body, .content-footer {margin: 10px 60px; padding: 0 0 10px;}
74
- .flash {margin-left: 60px; margin-right: 60px; text-shadow: #728852 2px 2px 0;}
69
+ .content-header, .content-body, .content-footer {margin: 10px 45px 15px; padding: 0;}
70
+
71
+ .flash {
72
+ margin: 20px 40px; padding: 10px 30px;
73
+ border-width: 2px 0;
74
+ color: white;
75
+ }
76
+ .flash.notice {background: #92ab6e; border: 1px solid #829862; text-shadow: #728852 2px 2px 0;}
77
+ .flash.error {background: #BC1C3D; border: 1px solid #900024; text-shadow: #900024 2px 2px 0;}
75
78
  .article { margin: 20px 0; border-top: 1px dotted #ccc;}
76
79
 
80
+ .content-header, .content-body {padding-bottom: 15px;}
81
+ .content-footer {padding-bottom: 20px;}
82
+
83
+
84
+ /* aside layout */
85
+ body.aside-layout {width: 960px;}
86
+ .aside-layout .page-content {overflow: hidden; height: 100%;}
87
+ .main-content {float: left; width: 670px;}
88
+ .aside {float: right; width: 220px; padding: 20px 30px; background: #E5E5E5;}
89
+ .aside-content {
90
+ font-size: 11px; color: #444;
91
+ }
92
+ /* trick to produce equal height columns */
93
+ .aside, .main-content {padding-bottom: 10000px; margin-bottom: -10000px;}
94
+
95
+
77
96
  /***********/
78
97
 
79
- .page-header {color: white; background: black; padding: 20px 0 0; position: relative;}
80
- .page-header h1 {margin: 0; padding: 0 40px 30px; font-family: "Trebuchet MS", Tahoma, Arial, sans-serif; font-size: 48px; letter-spacing: -2.5pt;}
81
- .page-header .nav {margin: 0 30px; overflow: hidden; height: 100%;}
98
+ .page-header {color: white; background: black; margin-top: 20px; padding: 20px 0 0; position: relative;}
99
+ .page-header h1 {margin: 0; padding: 0 30px 30px; font-family: "Arial Black", Tahoma, Arial, sans-serif; font-size: 36px; letter-spacing: -1.5pt;}
100
+ .page-header .nav {margin: 0 20px; overflow: hidden; height: 100%;}
82
101
  .page-header .nav li {float: left; list-style: none; margin-left: 0;}
83
- .page-header a {color: white; border: none; background: none;}
102
+ .page-header a, .page-header a:hover {color: white; border: none; background: none;}
84
103
 
85
104
  .page-header div.search {
86
- position: absolute; top: 0; right: 25px; padding: 6px 30px 8px 15px;
87
- background: #282828; border: 1px solid #313131; border-width: 0 1px 1px;
105
+ position: absolute; top: 10px; right: 5px; padding: 6px 30px 8px 15px;
88
106
  }
89
107
  .page-header div.search label {
90
108
  padding-right: 10px;
@@ -96,37 +114,47 @@ input.file_upload {
96
114
  #search-spinner {position: absolute; top: 6px; right: 7px;}
97
115
 
98
116
  .account-nav {
99
- position: absolute; top: 38px; right: 40px;
100
- /* font: normal 12px Arial, sans-serif;*/
101
- font-size: 11px;
117
+ position: absolute; top: -20px; right: 35px; font-size: 11px;
102
118
  }
103
119
 
104
120
  ul.main-nav {float: left; margin: 0 10px;}
105
121
  .main-nav li {background: black; margin-right: 10px;}
106
122
  .main-nav a {
107
123
  background: #282828;
108
- display: block; padding: 7px 15px; border: 1px solid #313131; border-width: 1px 1px 0;
109
- font: bold 16px "Myriad Pro", Arial, sans-serif; text-shadow: black 2px 2px 2px;
124
+ display: block; padding: 5px 15px 7px; border: 1px solid #313131; border-width: 1px 1px 0;
125
+ font: bold 13px "Lucida Grande", Arial, sans-serif; text-shadow: black 2px 2px 2px;
110
126
  }
111
127
  .main-nav a:hover {background: #444; border: 1px solid #555; border-width: 1px 1px 0;}
112
- .account-nav li {padding-left: 20px;}
113
- .account-nav a {border-bottom: 1px solid black; font-weight: bold;}
128
+ .account-nav li {
129
+ padding-left: 20px; float: left; list-style: none; margin-left: 0; color: #ddd; text-shadow: #444 2px 2px 0;}
130
+ .account-nav a {font-weight: bold;}
114
131
  .account-nav a:hover {border-bottom: 1px dotted #ddd;}
115
132
 
116
133
 
117
- .page-content {padding-top: 10px;}
134
+ /* pagination nav, needs a more specific class on the wrapper */
135
+ .content-body .nav {font-size: 11px; margin-bottom: 10px;}
136
+ .content-body .nav a {margin-right: 5px;}
137
+
138
+ .field-list th {width: 120px;}
139
+ .field-list td {width: auto;}
118
140
 
119
141
  .login-page, .signup-page {width: 50%; margin-top: 40px;}
142
+ .login-page .content-header, .signup-page .content-header {padding-bottom: 0;}
120
143
  .login-page .field-list, .signup-page .field-list {width: 300px;}
121
144
  .login-page .field-list td, .signup-page .field-list td {width: auto;}
122
145
  .login-page .field-list th, .signup-page .field-list th {width: 120px;}
123
- .login-page .submit-button, .signup-page .submit-button {margin: 10px 130px;}
146
+ .login-page .actions, .signup-page .actions {text-align: left; margin-left: 128px; margin-top: 20px;}
147
+ /*.login-page .submit-button, .signup-page .submit-button {margin: 10px 130px;}*/
124
148
 
125
149
  .edit-page .delete-button {margin-top: 25px;}
126
150
 
127
- .show-page .content-header {position: relative; border-bottom: 1px dotted #ddd;}
128
- .show-page .content-header h1, .new-in-collection-page .content-header h1 {margin-bottom: 4px; margin-right: 70px;}
151
+ .show-page .content-header {position: relative; border-bottom: 1px dotted black;}
152
+ .show-page .content-header h1, .new-in-collection-page .content-header h1 {margin-bottom: 2px; margin-right: 70px;}
129
153
  .show-page .content-header a.edit {position: absolute; top: 0; right: 0;}
154
+ .content-header .creation-details, .content-header .dependent-collection-count {font-size: 11px; line-height: 11px;}
155
+ .content-header .creator {margin-right: 5px;}
156
+ .content-header .created-at {color: #444;}
157
+ .content-header .dependent-collection-count {font-weight: bold; margin-left: 15px;}
130
158
 
131
159
  .new-in-collection-page .content-header h2 {margin-top: 6px; font: bold 16px "Lucida Grande", Arial, sans-serif;}
132
160
  .new-in-collection-page .content-header h2, .new-in-collection-page .content-header h2 a {color: #222;}
@@ -135,14 +163,19 @@ ul.main-nav {float: left; margin: 0 10px;}
135
163
  padding: 0 30px;
136
164
  border-top: 1px dotted #ddd; margin-top: 20px; background: #f5f5f5;
137
165
  }
138
- .show-page .create-new form .submit-button {margin: 20px 155px;}
166
+ .show-page .create-new form .submit-button {margin: 20px 130px;}
167
+ .show-page .create-new h2 {margin: 20px 0; padding: 0; border-bottom: none;}
139
168
 
169
+ /* styling of generic elements */
170
+ .creator {font-weight: bold;}
140
171
  .card {
141
172
  background: #f5f5f5;
142
173
  border: 1px solid #e8e8e8;
143
174
  padding:10px 20px;
144
175
  margin-bottom: 5px;
176
+ height: 100%; overflow: hidden; clear: both;
145
177
  }
178
+ .card a {background: #f5f5f5;}
146
179
  .card .creation-details {
147
180
  font-size: 11px; color: #333; display: block;
148
181
  }
@@ -150,8 +183,16 @@ ul.main-nav {float: left; margin: 0 10px;}
150
183
 
151
184
  .card.content {
152
185
  font-size: 11px;
153
- border: none; background: none; padding: 0; margin: 10px 0;
186
+ border: none; background: none; padding: 0; margin: 10px 0 30px;
154
187
  }
188
+ .card.content .creation-details {
189
+ float: left; width: 155px; line-height: 14px;
190
+ }
191
+ .card.content .creation-details .created-at {display: block;}
192
+ .card.content .content {
193
+ float: right; width: 420px;
194
+ }
195
+ ul.collection li {list-style: none; margin-left: 0;}
155
196
 
156
197
  .new-links {margin-top: 20px;}
157
198
  .new-links ul li {list-style: none; margin-left: 0;}
@@ -159,6 +200,10 @@ ul.main-nav {float: left; margin: 0 10px;}
159
200
  .dependent-collection ul li {
160
201
  list-style: none; margin-left: 0;
161
202
  }
203
+ .dependent-collection h2 {
204
+ padding: 15px 0; margin-bottom: 20px;
205
+ border-bottom: 1px dotted black;
206
+ }
162
207
 
163
208
  /*******************************************************/
164
209
  /* these styles are for the generated front index page */
@@ -1,13 +1,5 @@
1
1
  .hidden {display: none;}
2
2
 
3
- .flash {
4
- background: #92ab6e;
5
- padding: 10px 30px; margin-top: 5px;
6
- border: 1px solid #829862;
7
- /* border-width: 2px 0;*/
8
- color: white;
9
- }
10
-
11
3
  .in-place-textfield-bhv, .in-place-textarea-bhv, .in-place-html-textarea-bhv {
12
4
  border: 1px dotted #666;
13
5
  padding: 0 3px; padding-right: 20px;
@@ -125,7 +117,7 @@ div.completions-popup ul li {
125
117
 
126
118
 
127
119
  .field-list {width:100%;}
128
- .field-list td {vertical-align: middle; width: 75%;}
120
+ .field-list td {vertical-align: middle;}
129
121
  .field-list th {font-weight: bold;}
130
122
  .field-list th, .field-list td {padding: 5px 0;}
131
123
  .field-list th {padding-right: 10px;}
@@ -1,16 +1,6 @@
1
1
  require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
- require '<%= file_path %>_controller'
3
-
4
- # Re-raise errors caught by the controller.
5
- class <%= class_name %>Controller; def rescue_action(e) raise e end; end
6
-
7
- class <%= class_name %>ControllerTest < Test::Unit::TestCase
8
- def setup
9
- @controller = <%= class_name %>Controller.new
10
- @request = ActionController::TestRequest.new
11
- @response = ActionController::TestResponse.new
12
- end
13
2
 
3
+ class <%= class_name %>ControllerTest < ActionController::TestCase
14
4
  # Replace this with your real tests.
15
5
  def test_truth
16
6
  assert true
@@ -1,5 +1,19 @@
1
1
  # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+
3
+ <% unless attributes.empty? -%>
2
4
  one:
3
- id: 1
5
+ <% for attribute in attributes -%>
6
+ <%= attribute.name %>: <%= attribute.default %>
7
+ <% end -%>
8
+
4
9
  two:
5
- id: 2
10
+ <% for attribute in attributes -%>
11
+ <%= attribute.name %>: <%= attribute.default %>
12
+ <% end -%>
13
+ <% else -%>
14
+ # one:
15
+ # column: value
16
+ #
17
+ # two:
18
+ # column: value
19
+ <% end -%>
@@ -4,7 +4,7 @@ class <%= class_name %> < ActiveRecord::Base
4
4
 
5
5
  fields do
6
6
  username :string, :login => true, :name => true
7
- administrator :boolean
7
+ administrator :boolean, :default => false
8
8
  timestamps
9
9
  end
10
10
 
@@ -1,8 +1,6 @@
1
1
  require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
2
 
3
- class <%= class_name %>Test < Test::Unit::TestCase
4
- fixtures :<%= table_name %>
5
-
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
6
4
  # Replace this with your real tests.
7
5
  def test_truth
8
6
  assert true
@@ -71,16 +71,17 @@ module Hobo
71
71
  @tag_page_renderer_classes[controller_class.name].new(page, view)
72
72
  else
73
73
  template_path = "app/views/" + page + ".dryml"
74
- src_file = File.new(File.join(RAILS_ROOT, template_path))
74
+ src_file = File.join(RAILS_ROOT, template_path)
75
+ mtime = File.mtime(src_file)
75
76
  renderer_class = @renderer_classes[page]
76
77
 
77
78
  # do we need to recompile?
78
79
  if (!renderer_class or # nothing cached?
79
80
  (local_names - renderer_class.compiled_local_names).any? or # any new local names?
80
- renderer_class.load_time < src_file.mtime) # cache out of date?
81
- renderer_class = make_renderer_class(src_file.read, template_path, local_names,
81
+ renderer_class.load_time < mtime) # cache out of date?
82
+ renderer_class = make_renderer_class(File.read(src_file), template_path, local_names,
82
83
  DEFAULT_IMPORTS, included_taglibs)
83
- renderer_class.load_time = src_file.mtime
84
+ renderer_class.load_time = mtime
84
85
  @renderer_classes[page] = renderer_class
85
86
  end
86
87
  renderer_class.new(page, view)
@@ -17,7 +17,7 @@ module Hobo::Dryml
17
17
 
18
18
 
19
19
  def ready?(mtime)
20
- !(@build_instructions.empty? || @last_build_time.nil? || mtime > @last_build_time)
20
+ !@build_instructions.empty? && @last_build_mtime && @last_build_mtime >= mtime
21
21
  end
22
22
 
23
23
 
@@ -62,7 +62,7 @@ module Hobo::Dryml
62
62
  end
63
63
 
64
64
 
65
- def build(local_names, auto_taglibs)
65
+ def build(local_names, auto_taglibs, src_mtime)
66
66
 
67
67
  auto_taglibs.each { |t| import_taglib(t) }
68
68
 
@@ -98,7 +98,7 @@ module Hobo::Dryml
98
98
  "building #{template_path}")
99
99
  end
100
100
  end
101
- @last_build_time = Time.now
101
+ @last_build_mtime = src_mtime
102
102
  end
103
103
 
104
104
 
@@ -9,16 +9,15 @@ module Hobo
9
9
  class << self
10
10
 
11
11
  def get(options)
12
- file = taglib_file(options)
13
-
14
12
  taglib = @cache[options]
15
13
  if taglib
16
14
  taglib.reload
17
15
  else
16
+ src_file = taglib_filename(options)
18
17
  renames = (bundle = options[:bundle] and
19
18
  Bundle.bundles[bundle]._?.renames)
20
19
 
21
- taglib = Taglib.new(file, renames)
20
+ taglib = Taglib.new(src_file, renames)
22
21
  @cache[options] = taglib
23
22
  end
24
23
  taglib
@@ -30,7 +29,7 @@ module Hobo
30
29
 
31
30
  private
32
31
 
33
- def taglib_file(options)
32
+ def taglib_filename(options)
34
33
  base = if (plugin = options[:plugin])
35
34
  "vendor/plugins/#{plugin}/taglibs"
36
35
  elsif (bundle_name = options[:bundle])
@@ -44,19 +43,19 @@ module Hobo
44
43
 
45
44
  filename = "#{RAILS_ROOT}/#{base}/#{options[:src]}.dryml"
46
45
  raise DrymlException, "No such taglib: #{options.inspect} #{filename}" unless File.exists?(filename)
47
- File.new(filename)
46
+ filename
48
47
  end
49
48
 
50
49
  end
51
50
 
52
- def initialize(file, renames)
53
- @file = file
51
+ def initialize(src_file, renames)
52
+ @src_file = src_file
54
53
  @renames = renames
55
54
  load
56
55
  end
57
56
 
58
57
  def reload
59
- load if @file.mtime > @last_load_time
58
+ load if File.mtime(@src_file) > @last_load_time
60
59
  end
61
60
 
62
61
  def load
@@ -85,10 +84,9 @@ module Hobo
85
84
  end
86
85
 
87
86
  end
88
- @file.rewind
89
- template = Template.new(@file.read, @module, @file.path, @renames)
87
+ template = Template.new(File.read(@src_file), @module, @src_file, @renames)
90
88
  template.compile([], [])
91
- @last_load_time = @file.mtime
89
+ @last_load_time = File.mtime(@src_file)
92
90
  end
93
91
 
94
92
  def import_into(class_or_module, as)
@@ -65,7 +65,7 @@ module Hobo::Dryml
65
65
  end
66
66
 
67
67
  # compile the build instructions
68
- @builder.build(local_names, auto_taglibs)
68
+ @builder.build(local_names, auto_taglibs, mtime)
69
69
 
70
70
  from_cache = (parsed ? '' : ' (from cache)')
71
71
  logger.info(" DRYML: Compiled#{from_cache} #{template_path} in %.2fs" % (Time.now - now))
@@ -133,13 +133,13 @@ module Hobo::Dryml
133
133
  res
134
134
  end
135
135
 
136
- def call_polymorphic_tag(*args, &b)
137
- attributes = extract_options_from_args!(args)
138
- name, type = args
136
+ def call_polymorphic_tag(name, *args)
137
+ type = args.first.is_a?(Class) ? args.shift : nil
138
+ attributes, parameters = args
139
139
 
140
140
  tag = find_polymorphic_tag(name, type)
141
141
  if tag != name
142
- send(tag, attributes, &b)
142
+ send(tag, attributes, parameters || {})
143
143
  else
144
144
  nil
145
145
  end
@@ -147,8 +147,17 @@ module Hobo::Dryml
147
147
 
148
148
 
149
149
  def find_polymorphic_tag(name, call_type=nil)
150
- call_type ||= this_type
151
- return name if call_type.is_a?(ActiveRecord::Reflection::AssociationReflection)
150
+ call_type ||= case this_type
151
+ when ActiveRecord::Reflection::AssociationReflection
152
+ # Don't blow up with non-existent polymorphic types
153
+ return name if this_type.options[:polymorphic] && !Object.const_defined?(this_type.class_name)
154
+ this_type.klass
155
+ when Array
156
+ this.member_class
157
+ else
158
+ this_type
159
+ end
160
+
152
161
  call_type = TrueClass if call_type == FalseClass
153
162
 
154
163
  while true
@@ -186,8 +195,7 @@ module Hobo::Dryml
186
195
  @_form_field_path]
187
196
  @_erb_output = ""
188
197
  res = yield
189
- @_erb_output, @_this, @_this_parent, @_this_field, @_this_type,
190
- @_form_field_path = ctx
198
+ @_erb_output, @_this, @_this_parent, @_this_field, @_this_type, @_form_field_path = ctx
191
199
  res.to_s
192
200
  end
193
201
 
@@ -210,13 +218,13 @@ module Hobo::Dryml
210
218
 
211
219
  def new_field_context(field_path, tag_this=nil)
212
220
  new_context do
213
- path = if field_path.is_a? Array
214
- field_path
215
- elsif field_path.is_a? String
216
- field_path.split('.')
217
- else
218
- [field_path]
219
- end
221
+ path = if field_path.is_a? Array
222
+ field_path
223
+ elsif field_path.is_a? String
224
+ field_path.split('.')
225
+ else
226
+ [field_path]
227
+ end
220
228
  parent, field, obj = Hobo.get_field_path(tag_this || this, path)
221
229
 
222
230
  type = if parent.class.respond_to?(:field_type) && field_type = parent.class.field_type(field)
@@ -48,9 +48,13 @@ module Hobo
48
48
  end
49
49
 
50
50
  def different_to?(col_spec)
51
- [:limit, :precision, :scale, :null, :default].any? do |k|
52
- col_spec.send(k) != self.send(k)
53
- end || sql_type != col_spec.type
51
+ sql_type != col_spec.type ||
52
+ begin
53
+ check_cols = [:null, :default]
54
+ check_cols += [:precision, :scale] if sql_type == :decimal
55
+ check_cols << :limit if sql_type.in?([:string, :text, :binary, :integer])
56
+ check_cols.any? { |k| col_spec.send(k) != self.send(k) }
57
+ end
54
58
  end
55
59
 
56
60
  private
@@ -354,6 +354,7 @@ module Hobo
354
354
 
355
355
 
356
356
  class ScopedProxy
357
+
357
358
  def initialize(klass, scope)
358
359
  @klass = klass
359
360
 
@@ -140,23 +140,25 @@ module Hobo
140
140
 
141
141
 
142
142
  def show_action(*names, &block)
143
+ options = names.extract_options!
143
144
  show_actions.concat(names)
144
145
  for name in names
145
146
  if block
146
147
  define_method(name, &block)
147
148
  else
148
- define_method(name) { hobo_show }
149
+ define_method(name) { hobo_show options }
149
150
  end
150
151
  end
151
152
  end
152
153
 
153
154
  def index_action(*names, &block)
155
+ options = names.extract_options!
154
156
  index_actions.concat(names)
155
157
  for name in names
156
158
  if block
157
159
  define_method(name, &block)
158
160
  else
159
- define_method(name) { hobo_index }
161
+ define_method(name) { hobo_index options }
160
162
  end
161
163
  end
162
164
  end
@@ -358,6 +360,7 @@ module Hobo
358
360
  def re_render_form(default_action)
359
361
  if params[:page_path]
360
362
  controller, view = Controller.controller_and_view_for(params[:page_path])
363
+ view = default_action if view == Dryml::EMPTY_PAGE
361
364
  hobo_render(view, model_for(controller))
362
365
  else
363
366
  hobo_render(default_action)
@@ -531,7 +534,7 @@ module Hobo
531
534
  end
532
535
  elsif invalid?
533
536
  respond_to do |wants|
534
- wants.html { re_render_form(:edit) }
537
+ wants.html { re_render_form(:edit) }
535
538
  wants.js { render(:status => 500,
536
539
  :text => ("There was a problem with that change.\n" +
537
540
  @this.errors.full_messages.join("\n"))) }
@@ -29,7 +29,7 @@ module Hobo
29
29
  if request.post?
30
30
  user = model.authenticate(params[:login], params[:password])
31
31
  if user.nil?
32
- flash[:notice] = options[:failure_notice]
32
+ flash[:error] = options[:failure_notice]
33
33
  else
34
34
  old_user = current_user
35
35
  self.current_user = user
@@ -104,7 +104,7 @@
104
104
 
105
105
  <def tag="card">
106
106
  <if test="&can_view?">
107
- <%= poly = call_polymorphic_tag('card', attributes) %>
107
+ <%= poly = call_polymorphic_tag('card', attributes, parameters) %>
108
108
  <div class="card #{linkable? ? 'linkable' : 'content'} #{type_name :dasherize => true}" unless="&poly">
109
109
  <a if="&linkable?"/>
110
110
  <div class="content" param="content">
@@ -117,6 +117,17 @@
117
117
  </def>
118
118
 
119
119
 
120
+ <def tag="collection">
121
+ <%= poly = call_polymorphic_tag('collection', attributes, parameters) %>
122
+ <ul class="collection" merge-attrs unless="&poly">
123
+ <li:><card param/></li:>
124
+ </ul>
125
+ <p class="empty-collection-message" if="&this.empty?" param="empty-message">
126
+ There are no <type-name plural/>
127
+ </p>
128
+ </def>
129
+
130
+
120
131
  <def tag="hobo-rapid-javascripts" attrs="tiny-mce"><%=
121
132
  res = '<script type="text/javascript">var hoboParts = {};'
122
133
  unless Hobo.all_models.empty?
@@ -464,10 +475,10 @@ in the future - use at your own risk. -->
464
475
 
465
476
 
466
477
  <def tag="a-or-an" attrs="word"><%=
467
- (word =~ /^[aeiouh]/ ? "an " : "a ") + word
478
+ (word =~ /^[aeiouh]/i ? "an " : "a ") + word
468
479
  %></def>
469
480
 
470
481
 
471
482
  <def tag="A-or-An" attrs="word"><%=
472
- (word =~ /^[aeiouh]/ ? "An " : "A ") + word
483
+ (word =~ /^[aeiouh]/i ? "An " : "A ") + word
473
484
  %></def>
@@ -308,7 +308,7 @@
308
308
 
309
309
  <def tag="error-messages">
310
310
  <section class="error-messages" merge-attrs if="&this.errors.length > 0">
311
- <h2 param="heading">In order to proceed please correct the following:</h2>
311
+ <h2 param="heading">To proceed please correct the following:</h2>
312
312
  <ul:errors.full_messages param>
313
313
  <li: param><%= this %></li:>
314
314
  </ul>
@@ -20,21 +20,23 @@
20
20
  </html>
21
21
  </def>
22
22
 
23
+
23
24
  <def tag="simple-layout">
24
25
  <base-page merge>
25
26
  <body: param>
26
27
  <ajax-progress/>
27
28
  <header class="page-header" param>
28
29
  <heading param="app-name"><a href="/#{base_url}"><app-name/></a></heading>
29
- <live-search param/>
30
+ <live-search param if="&defined_route? :search"/>
30
31
  <nav param>
31
32
  <account-nav if="&Hobo::UserController.user_models.first" param/>
32
33
  <magic-nav class="main-nav" param="main-nav"/>
33
34
  </nav>
34
35
  </header>
35
36
  <section class="page-content" param="content">
36
- <header class="content-header" param="content-header"/>
37
37
  <flash-message param/>
38
+ <flash-message type="error" param/>
39
+ <header class="content-header" param="content-header"/>
38
40
  <section class="content-body" param="content-body"/>
39
41
  <footer class="content-footer" param="content-footer"/>
40
42
  </section>
@@ -57,15 +59,12 @@
57
59
  </def>
58
60
 
59
61
 
60
- <def tag="default-layout" alias-of="simple-layout"/>
62
+ <def tag="page" attrs="layout"><call-tag tag="#{layout || 'simple'}-layout" merge/></def>
61
63
 
62
64
 
63
- <def tag="page" attrs="layout"><% layout ||= "default" %><call-tag tag="#{layout}-layout" merge/></def>
64
-
65
-
66
- <def tag="index-page" attrs="layout">
65
+ <def tag="index-page">
67
66
  <% model_name = @model.name.titleize %>
68
- <page layout="&layout" title="All #{model_name.pluralize}" merge>
67
+ <page title="All #{model_name.pluralize}" merge>
69
68
  <body: class="index-page #{@model.name.underscore}" param/>
70
69
  <content-header: param>
71
70
  <heading param><%= model_name.pluralize %></heading>
@@ -75,7 +74,7 @@
75
74
  <content-body: param>
76
75
  <nav param="top-pagination-nav"><page-nav/></nav>
77
76
 
78
- <card repeat/>
77
+ <collection param/>
79
78
 
80
79
  <nav param="bottom-pagination-nav"><page-nav/></nav>
81
80
  </content-body>
@@ -95,8 +94,8 @@
95
94
  </def>
96
95
 
97
96
 
98
- <def tag="new-page" attrs="layout">
99
- <page layout="&layout" title="New #{type_name}" merge>
97
+ <def tag="new-page">
98
+ <page title="New #{type_name}" merge>
100
99
  <body: class="new-page #{type_name.underscore}" param/>
101
100
  <content-header: param>
102
101
  <heading param>New <type-name title/></heading>
@@ -116,13 +115,13 @@
116
115
  </def>
117
116
 
118
117
 
119
- <def tag="show-page" attrs="layout">
118
+ <def tag="show-page">
120
119
  <% has_many_assocs = this.class.reflections.values.map do |refl|
121
120
  this.send(refl.name) if Hobo.simple_has_many_association?(refl)
122
121
  end.compact
123
- show_all_cards = this.class.dependent_collections.first if this.class.dependent_collections.length == 1
122
+ dependent_collection = this.class.dependent_collections.first if this.class.dependent_collections.length == 1
124
123
  %>
125
- <page layout="&layout" merge title="#{name :no_wrapper => true}">
124
+ <page merge title="#{name :no_wrapper => true}">
126
125
  <body: class="show-page #{type_name.underscore}" param/>
127
126
  <content-header: param>
128
127
  <if with="&this.dependent_on.reject{|x| x.is_a?(Hobo::User)}.first">
@@ -130,8 +129,8 @@
130
129
  </if>
131
130
 
132
131
  <heading param><%= this %></heading>
133
- <creation-details/>
134
- <a class="dependent-collection-count" href="##{show_all_cards.to_s.underscore}" if="&show_all_cards"><count-dependents/></a>
132
+ <creation-details param/>
133
+ <do param="dependent-collection-count"><a class="dependent-collection-count" href="##{dependent_collection.to_s.underscore}" part="dependent-collection-count" part-locals="dependent_collection" if="&dependent_collection"><count-dependents/></a></do>
135
134
  <a action="edit" if="&can_edit?" class="edit">Edit <type-name/></a>
136
135
  </content-header>
137
136
 
@@ -141,22 +140,24 @@
141
140
  <field-list skip="&[this.class.name_attribute, this.class.primary_content_attribute, this.class.creator_attribute, this.class.dependent_on.first].compact "
142
141
  skip-associations="has_many" param/>
143
142
 
144
- <if test="&show_all_cards">
145
- <section class="dependent-collection" field="&show_all_cards">
146
- <a name="#{show_all_cards.to_s.underscore}"/>
147
- <h2><%= show_all_cards.to_s.titleize %></h2>
148
- <do part="dependent-collection" part-locals="show_all_cards">
149
- <ul><li:><card/></li:></ul>
150
- <else>No <%= show_all_cards.to_s %> have been added yet.</else>
143
+ <if test="&dependent_collection">
144
+ <section class="dependent-collection" field="&dependent_collection">
145
+ <a name="#{dependent_collection.to_s.underscore}"/>
146
+ <h2 param="dependent-collection-title"><%= dependent_collection.to_s.titleize %></h2>
147
+
148
+ <do param="collection">
149
+ <collection part="dependent-collection" part-locals="dependent_collection">
150
+ <empty-message:>No <%= dependent_collection.to_s %> have been added yet.</empty-message>
151
+ </collection>
151
152
  </do>
152
153
 
153
154
  <do with="&new_for_current_user">
154
155
  <section class="create-new" if="&!linkable?(:new) && can_create?">
155
- <h2>Add <A-or-An word="&show_all_cards.to_s.singularize.titleize"/></h2>
156
- <form update="dependent-collection" message="Adding #{show_all_cards.to_s.singularize.titleize}..." reset-form>
157
- <field-list skip="#{@this.class.reverse_reflection(@this.send(show_all_cards).proxy_reflection.name).name}"
158
- skip-associations="has_many" param/>
159
- <submit label="Create #{show_all_cards.to_s.singularize.titleize}"/>
156
+ <h2>Add <A-or-An word="&dependent_collection.to_s.singularize.titleize"/></h2>
157
+ <form update="dependent-collection, dependent-collection-count" message="Adding #{dependent_collection.to_s.singularize.titleize}..." reset-form>
158
+ <field-list skip="#{@this.class.reverse_reflection(@this.send(dependent_collection).proxy_reflection.name).name}"
159
+ skip-associations="has_many" param="dependent-collection-field-list"/>
160
+ <submit label="Create #{dependent_collection.to_s.singularize.titleize}"/>
160
161
  </form>
161
162
  </section>
162
163
  </do>
@@ -167,7 +168,7 @@
167
168
  <with-fields associations="has_many">
168
169
  <section class="#{this_field.dasherize}">
169
170
  <h2>Recent <this-field.titleize/></h2>
170
- <card repeat="&this.recent.all"/>
171
+ <collection with="&this.recent"/>
171
172
  <a class="more">More... (<count/>)</a>
172
173
  </section>
173
174
  </with-fields>
@@ -185,8 +186,8 @@
185
186
  </def>
186
187
 
187
188
 
188
- <def tag="edit-page" attrs="layout">
189
- <page layout="&layout" merge>
189
+ <def tag="edit-page">
190
+ <page merge>
190
191
  <body: class="edit-page #{this.class.name.underscore}" param/>
191
192
  <content-header: param>
192
193
  <heading><if test="&this.respond_to? :name"><name/></if><else><type-name/></else></heading>
@@ -207,9 +208,9 @@
207
208
  </def>
208
209
 
209
210
 
210
- <def tag="new-in-collection-page" attrs="layout">
211
+ <def tag="new-in-collection-page">
211
212
  <set association-name="&@association.proxy_reflection.name.to_s.singularize.titleize"/>
212
- <page layout="&layout" title="New #{type_name}" merge>
213
+ <page title="New #{type_name}" merge>
213
214
  <body: class="new-in-collection-page #{type_name(:with => @owner)} #{type_name}" param/>
214
215
  <content-header: param>
215
216
  <heading param>New <association-name/></heading>
@@ -231,9 +232,9 @@
231
232
  </def>
232
233
 
233
234
 
234
- <def tag="show-collection-page" attrs="layout">
235
+ <def tag="show-collection-page">
235
236
  <% title = "#{@reflection.name.to_s.titleize} for #{name(:with => @owner)}" %>
236
- <page layout="&layout" title="&title" merge>
237
+ <page title="&title" merge>
237
238
  <body: class="show-collection-page #{type_name(:with => @owner)} #{type_name(:pluralize => true)}"
238
239
  param/>
239
240
  <content-header: param>
@@ -257,8 +258,8 @@
257
258
  </def>
258
259
 
259
260
 
260
- <def tag="signup-page" attrs="layout">
261
- <page layout="&layout" title="Sign up to #{app_name}" merge>
261
+ <def tag="signup-page">
262
+ <page layout="simple" title="Sign up to #{app_name}" merge>
262
263
  <body: class="signup-page" param/>
263
264
 
264
265
  <live-search: replace/>
@@ -275,7 +276,9 @@
275
276
  <password-confirmation-label:>Confirm Password</password-confirmation-label>
276
277
  </field-list>
277
278
 
278
- <submit label='Sign Up'/>
279
+ <div class="actions" param="actions">
280
+ <submit label='Sign Up'/>
281
+ </div>
279
282
  </form>
280
283
  </content-body>
281
284
 
@@ -283,8 +286,8 @@
283
286
  </def>
284
287
 
285
288
 
286
- <def tag="login-page" attrs="remember-me, layout">
287
- <page layout="&layout" title="Log in to #{app_name}" merge>
289
+ <def tag="login-page" attrs="remember-me">
290
+ <page layout="simple" title="Log in to #{app_name}" merge>
288
291
 
289
292
  <body: class="login-page" param/>
290
293
 
@@ -313,20 +316,23 @@
313
316
  <item-value><input type="checkbox" name="remember_me" id="remember-me" param="remember-me-input"/></item-value>
314
317
  </labelled-item>
315
318
  </labelled-item-list>
316
- <submit label='Log in' param/>
319
+ <set user="&Hobo::UserController.user_models.first"/>
320
+ <div class="actions" param="actions">
321
+ <submit label='Log in' param/><if test="&signup_url(user)" class='nav-item'> or <a href="&signup_url(user)">Sign up</a></if>
322
+ </div>
317
323
  </form>
318
324
  </content-body>
319
325
  </page>
320
326
  </def>
321
327
 
322
328
 
323
- <def tag="account-disabled-page" attrs="layout">
329
+ <def tag="account-disabled-page">
324
330
 
325
- <page layout="&layout" title="#{app_name} - account not available" merge>
331
+ <page layout="simple" title="#{app_name} - account not available" merge>
326
332
 
327
333
  <body: class="account-disabled-page" param/>
328
334
 
329
- <content-header: param><heading param>Account is not availble</heading></content>
335
+ <content-header: param><heading param>Account is not available</heading></content>
330
336
 
331
337
  <content-body: param>
332
338
  <p>Your account is not available at this time.</p>
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: hobo
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.7.1
7
- date: 2007-12-23 00:00:00 +00:00
6
+ version: 0.7.2
7
+ date: 2008-01-04 00:00:00 +00:00
8
8
  summary: The web app builder for Rails
9
9
  require_paths:
10
10
  - lib
@@ -63,7 +63,6 @@ files:
63
63
  - hobo_files/plugin/generators/hobo_model_controller/templates/controller.rb
64
64
  - hobo_files/plugin/generators/hobo_model_controller/templates/functional_test.rb
65
65
  - hobo_files/plugin/generators/hobo_model_controller/templates/helper.rb
66
- - hobo_files/plugin/generators/hobo_model_controller/templates/view.rhtml
67
66
  - hobo_files/plugin/generators/hobo_model_controller/USAGE
68
67
  - hobo_files/plugin/generators/hobo_rapid
69
68
  - hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb
@@ -128,7 +127,6 @@ files:
128
127
  - hobo_files/plugin/generators/hobo_user_controller/templates/controller.rb
129
128
  - hobo_files/plugin/generators/hobo_user_controller/templates/functional_test.rb
130
129
  - hobo_files/plugin/generators/hobo_user_controller/templates/helper.rb
131
- - hobo_files/plugin/generators/hobo_user_controller/templates/view.rhtml
132
130
  - hobo_files/plugin/generators/hobo_user_controller/USAGE
133
131
  - hobo_files/plugin/generators/hobo_user_model
134
132
  - hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb
@@ -1,2 +0,0 @@
1
- <h1><%= class_name %>#<%= action %></h1>
2
- <p>Find me in <%= path %></p>
@@ -1,2 +0,0 @@
1
- <h1><%= class_name %>#<%= action %></h1>
2
- <p>Find me in <%= path %></p>