hobo 0.6 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/bin/hobo +2 -3
  2. data/hobo_files/plugin/CHANGES.txt +139 -0
  3. data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -8
  4. data/hobo_files/plugin/generators/hobo_front_controller/templates/controller.rb +1 -39
  5. data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +2 -2
  6. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +27 -7
  7. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.js +1 -2
  8. data/hobo_files/plugin/generators/hobo_user_controller/USAGE +34 -0
  9. data/hobo_files/plugin/generators/hobo_user_controller/hobo_user_controller_generator.rb +43 -0
  10. data/hobo_files/plugin/generators/hobo_user_controller/templates/controller.rb +5 -0
  11. data/hobo_files/plugin/generators/hobo_user_controller/templates/functional_test.rb +18 -0
  12. data/hobo_files/plugin/generators/hobo_user_controller/templates/helper.rb +2 -0
  13. data/hobo_files/plugin/generators/hobo_user_controller/templates/view.rhtml +2 -0
  14. data/hobo_files/plugin/init.rb +6 -2
  15. data/hobo_files/plugin/lib/extensions.rb +28 -41
  16. data/hobo_files/plugin/lib/hobo.rb +37 -17
  17. data/hobo_files/plugin/lib/hobo/authentication_support.rb +25 -10
  18. data/hobo_files/plugin/lib/hobo/composite_model.rb +2 -2
  19. data/hobo_files/plugin/lib/hobo/controller.rb +8 -34
  20. data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +1 -1
  21. data/hobo_files/plugin/lib/hobo/dryml/part_context.rb +103 -0
  22. data/hobo_files/plugin/lib/hobo/dryml/template.rb +10 -11
  23. data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +29 -72
  24. data/hobo_files/plugin/lib/hobo/hobo_helper.rb +11 -10
  25. data/hobo_files/plugin/lib/hobo/migrations.rb +12 -0
  26. data/hobo_files/plugin/lib/hobo/model.rb +3 -3
  27. data/hobo_files/plugin/lib/hobo/model_controller.rb +3 -3
  28. data/hobo_files/plugin/lib/hobo/rapid_helper.rb +3 -3
  29. data/hobo_files/plugin/lib/hobo/user_controller.rb +80 -0
  30. data/hobo_files/plugin/tags/rapid.dryml +36 -20
  31. data/hobo_files/plugin/tags/rapid_editing.dryml +4 -5
  32. data/hobo_files/plugin/tags/rapid_forms.dryml +6 -6
  33. data/hobo_files/plugin/tags/rapid_navigation.dryml +7 -5
  34. data/hobo_files/plugin/tags/rapid_pages.dryml +116 -10
  35. data/hobo_files/plugin/tags/rapid_support.dryml +23 -0
  36. metadata +13 -5
  37. data/hobo_files/plugin/generators/hobo_front_controller/templates/login.dryml +0 -42
  38. data/hobo_files/plugin/generators/hobo_front_controller/templates/signup.dryml +0 -43
  39. data/hobo_files/plugin/lib/hobo/mapping_tags.rb +0 -262
@@ -8,7 +8,7 @@
8
8
  has_many_editor(attributes)
9
9
  end
10
10
  else
11
- attrs = add_classes(attributes, "#{type_and_field}", "#{type_name}", "editor")
11
+ attrs = add_classes(attributes, "#{type_and_field}", "#{type_id}", "editor")
12
12
  call_polymorphic_tag("editor", attrs) or
13
13
  raise HoboError.new("<editor> not implemented for #{this.class.name}\##{this_field} " +
14
14
  "(#{this.inspect}:#{this_type})")
@@ -86,10 +86,9 @@
86
86
  this_type.primary_key_name => Hobo.raw_js('this.value')
87
87
  } })
88
88
  %>
89
- <select onchange="<%= f %>">
89
+ <select onchange="#{f}">
90
90
  <%= options_for_select(select_options.sort, this ? this.id : "") %>
91
- </select>
92
- <a if="&this">View</a>
91
+ </select>&nbsp;<a if="&this">View</a>
93
92
  </span>
94
93
  </def>
95
94
 
@@ -173,7 +172,7 @@
173
172
  <tagbody/>
174
173
  </if>
175
174
  <else>
176
- <%= options_for_select(base_class.send(:subclasses).omap{[name.titleize, name]}, this.class.name) %>
175
+ <%= options_for_select(base_class.send(:subclasses).map{|x| [x.name.titleize, x.name]}, this.class.name) %>
177
176
  </else>
178
177
  </select>
179
178
  </def>
@@ -47,9 +47,9 @@
47
47
  body = [http_method_hidden, hiddens, body].join
48
48
 
49
49
  if web_method
50
- add_classes!(html_attrs, "#{type_name}_#{web_method}_form")
50
+ add_classes!(html_attrs, "#{type_id}_#{web_method}_form")
51
51
  else
52
- add_classes!(html_attrs, "#{'new_' if new_record}#{type_name}")
52
+ add_classes!(html_attrs, "#{'new_' if new_record}#{type_id}")
53
53
  end
54
54
 
55
55
  content_tag("form", body, html_attrs)
@@ -69,7 +69,7 @@
69
69
  has_many_input(attributes)
70
70
  end
71
71
  else
72
- attrs = {}.update(attributes)
72
+ attrs = add_classes(attributes, "#{type_and_field}", "#{type_id}")
73
73
  attrs[:name] ||= param_name_for_this
74
74
  the_input = call_polymorphic_tag('input', attrs) or
75
75
  raise HoboError, ("No input tag for #{this_field}:#{this_type} (this=#{this.inspect})")
@@ -207,7 +207,7 @@
207
207
  }
208
208
  select_options.insert(0, ["(No #{this_type.name.to_s.titleize})", ""]) if this.nil? || include_none
209
209
  %>
210
- <select name="<%= param_name_for_this(true) %>">
210
+ <select name="#{param_name_for_this(true)}">
211
211
  <%= options_for_select(select_options.sort, this ? this.id : "") %>
212
212
  </select>
213
213
  </def>
@@ -229,8 +229,8 @@
229
229
 
230
230
 
231
231
  <def tag="sti_type_input">
232
- <select name="<%= param_name_for(form_this, form_field_path + ['type']) %>">
233
- <%= options_for_select(this.class.send(:subclasses).omap{[name.titleize, name]}, this.class.name) %>
232
+ <select name="#{param_name_for(form_this, form_field_path + ['type'])}">
233
+ <%= options_for_select(this.class.send(:subclasses).map{|x| [x.name.titleize, x.name]}, this.class.name) %>
234
234
  </select>
235
235
  </def>
236
236
 
@@ -40,11 +40,13 @@
40
40
  <!--- Pagination Navigation -->
41
41
 
42
42
  <def tag="page_nav" attrs="params">
43
- <page_n_of_count/> -
44
- <first_page_link params="&params">|&lt;</first_page_link>
45
- <previous_page_link params="&params">Previous</previous_page_link>
46
- <next_page_link params="&params">Next</next_page_link>
47
- <last_page_link params="&params">&gt|</last_page_link>
43
+ <if test="&@pages.length > 1">
44
+ <page_n_of_count/> -
45
+ <first_page_link params="&params">|&lt;</first_page_link>
46
+ <previous_page_link params="&params">Previous</previous_page_link>
47
+ <next_page_link params="&params">Next</next_page_link>
48
+ <last_page_link params="&params">&gt|</last_page_link>
49
+ </if>
48
50
  </def>
49
51
 
50
52
 
@@ -49,6 +49,7 @@
49
49
  <def tag="PageForIndex"><Page merge/></def>
50
50
  <def tag="PageForNew"><Page merge/></def>
51
51
  <def tag="PageForShow"><Page merge/></def>
52
+ <def tag="PageForEdit"><Page merge/></def>
52
53
  <def tag="PageForNewInCollection"><Page merge/></def>
53
54
  <def tag="PageForShowCollection"><Page merge/></def>
54
55
 
@@ -83,11 +84,11 @@
83
84
 
84
85
 
85
86
  <def tag="NewPage">
86
- <PageForNew title="New #{human_type}" merge>
87
+ <PageForNew title="New #{type_name}" merge>
87
88
  <body class="rapid_generic_page"/>
88
89
  <main>
89
90
  <header>
90
- <heading>New <human_type/></heading>
91
+ <heading>New <type_name title/></heading>
91
92
  </header>
92
93
 
93
94
  <panel param="main" class="main">
@@ -115,8 +116,8 @@
115
116
  <body class="rapid_generic_page"/>
116
117
  <main>
117
118
  <header>
118
- <heading><human_type/><if test="&this.respond_to? :name">: <editor:name/></if></heading>
119
- <p><delete_button in_place="&false"/></p>
119
+ <heading><type_name/><if test="&this.respond_to? :name">: <editor:name/></if></heading>
120
+ <delete_button in_place="&false"/>
120
121
  </header>
121
122
 
122
123
  <panel param="main_panel">
@@ -125,23 +126,56 @@
125
126
  <FieldList skip="name" tag="editor" param/>
126
127
  </section>
127
128
 
129
+ <nav param="new_links">
130
+ <UL with="&has_many_assocs">
131
+ <li><a action="new"/></li>
132
+ </UL>
133
+ </nav>
134
+ </panel>
135
+ </main>
136
+ </PageForShow>
137
+ </def>
138
+
139
+
140
+ <def tag="EditPage">
141
+ <% has_many_assocs = this.class.reflections.values.map do |refl|
142
+ this.send(refl.name) if Hobo.simple_has_many_association?(refl)
143
+ end.compact
144
+ %>
145
+ <PageForEdit merge>
146
+ <body class="rapid_generic_page"/>
147
+ <main>
148
+ <header>
149
+ <heading><type_name/><if test="&this.respond_to? :name">: <name/></if></heading>
150
+ <delete_button in_place="&false"/>
151
+ </header>
152
+
153
+ <panel param="main_panel">
154
+ <header param="main_header"><h2>Details</h2></header>
155
+ <section>
156
+ <form>
157
+ <FieldList skip="name" tag="input" param/>
158
+ <submit label="Save"/>
159
+ </form>
160
+ </section>
161
+
128
162
  <section param="new_links">
129
- <repeat with="&has_many_assocs">
130
- <p><a action="new"/></p>
131
- </repeat>
163
+ <UL with="&has_many_assocs">
164
+ <li><a action="new"/></li>
165
+ </UL>
132
166
  </section>
133
167
  </panel>
134
168
  </main>
135
- </PageForShow>
169
+ </PageForEdit>
136
170
  </def>
137
171
 
138
172
 
139
173
  <def tag="NewInCollectionPage">
140
- <PageForNewInCollection title="New #{human_type}" merge>
174
+ <PageForNewInCollection title="New #{type_name}" merge>
141
175
  <body class="rapid_generic_page"/>
142
176
  <main>
143
177
  <header>
144
- <h1>New <human_type/></h1>
178
+ <h1>New <type_name/></h1>
145
179
  <h2>For: <a with="&@owner" /></h2>
146
180
  </header>
147
181
 
@@ -203,6 +237,78 @@
203
237
  </PageForShowCollection>
204
238
  </def>
205
239
 
240
+
241
+ <def tag="LoginPage" attrs="remember_me">
242
+ <Page title="Login">
243
+ <main>
244
+ <h1>Log In</h1>
245
+
246
+ <panel>
247
+ <section>
248
+ <form action="&request.request_uri">
249
+ <table class="login_table">
250
+ <tr>
251
+ <td class="field_label"><label for="login">Login</label></td>
252
+ <td><input type="text" name="login" id="login"/></td>
253
+ </tr>
254
+
255
+ <tr>
256
+ <td class="field_label"><label for="password">Password</label></td>
257
+ <td><input type="password" name="password" id="password"/></td>
258
+ </tr>
259
+
260
+ <tr if="&remember_me">
261
+ <td class="field_label"><label for="remember_me">Remember me:</label></td>
262
+ <td><input type="checkbox" name="remember_me" id="remember_me"/></td>
263
+ </tr>
264
+ </table>
265
+
266
+ <p><submit label='Log in'/></p>
267
+ </form>
268
+ </section>
269
+ </panel>
270
+ </main>
271
+ </Page>
272
+ </def>
273
+
274
+
275
+ <def tag="SignupPage">
276
+ <Page title="Sign Up">
277
+
278
+ <main>
279
+ <h1>Sign Up</h1>
280
+
281
+ <panel>
282
+ <section>
283
+ <error_messages/>
284
+ <form action="&request.request_uri">
285
+ <table class="signup_table">
286
+ <tr>
287
+ <td class="field_label"><label for="login">Login</label></td>
288
+ <td><input type="text" name="user[login]"/></td>
289
+ </tr>
290
+
291
+ <tr>
292
+ <td class="field_label"><label for="password">Password</label></td>
293
+ <td><input type="password" name="user[password]"/></td>
294
+ </tr>
295
+
296
+ <tr>
297
+ <td class="field_label"><label for="password">Confirm Password</label></td>
298
+ <td><input type="password" name="user[password_confirmation]"/></td>
299
+ </tr>
300
+ </table>
301
+
302
+ <p><submit label='Sign Up'/></p>
303
+ </form>
304
+ </section>
305
+ </panel>
306
+ </main>
307
+
308
+ </Page>
309
+ </def>
310
+
311
+
206
312
  <def tag="doctype" attrs="version"><%=
207
313
  case version.upcase
208
314
  when "HTML 4.01 STRICT"
@@ -21,3 +21,26 @@
21
21
  field_names.each do |field| %><with field="&field"><tagbody/></with><% end
22
22
  %></def>
23
23
 
24
+ <def tag="with_field_names" attrs="fields, skip, skip_associations, include_timestamps"><%
25
+ field_names = if fields.nil?
26
+ columns = this.content_columns.every(:name)
27
+ columns -= %w{created_at updated_at created_on updated_on} unless include_timestamps
28
+
29
+ if skip_associations == "has_many"
30
+ assocs = this.reflections.values.reject {|r| r.macro == :has_many }.every(:name)
31
+ columns - assocs
32
+ elsif skip_associations
33
+ columns
34
+ else
35
+ assocs = this.reflections.values.every(:name)
36
+ columns + assocs
37
+ end
38
+ else
39
+ comma_split(fields)
40
+ end
41
+
42
+ field_names -= comma_split(skip) if skip
43
+ %>
44
+ <repeat with="&field_names"><tagbody/></repeat>
45
+ </def>
46
+
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: hobo
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.6"
7
- date: 2007-08-22 00:00:00 +01:00
6
+ version: 0.6.1
7
+ date: 2007-08-25 00:00:00 +01:00
8
8
  summary: The web app builder for Rails
9
9
  require_paths:
10
10
  - lib
@@ -47,6 +47,7 @@ files:
47
47
  - hobo_files/plugin/generators/hobo_model
48
48
  - hobo_files/plugin/generators/hobo_model_controller
49
49
  - hobo_files/plugin/generators/hobo_rapid
50
+ - hobo_files/plugin/generators/hobo_user_controller
50
51
  - hobo_files/plugin/generators/hobo_user_model
51
52
  - hobo_files/plugin/generators/hobo/hobo_generator.rb
52
53
  - hobo_files/plugin/generators/hobo/templates
@@ -59,9 +60,7 @@ files:
59
60
  - hobo_files/plugin/generators/hobo_front_controller/templates/functional_test.rb
60
61
  - hobo_files/plugin/generators/hobo_front_controller/templates/helper.rb
61
62
  - hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml
62
- - hobo_files/plugin/generators/hobo_front_controller/templates/login.dryml
63
63
  - hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml
64
- - hobo_files/plugin/generators/hobo_front_controller/templates/signup.dryml
65
64
  - hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb
66
65
  - hobo_files/plugin/generators/hobo_migration/templates
67
66
  - hobo_files/plugin/generators/hobo_migration/templates/migration.rb
@@ -121,6 +120,13 @@ files:
121
120
  - hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_top.gif
122
121
  - hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css
123
122
  - hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml
123
+ - hobo_files/plugin/generators/hobo_user_controller/hobo_user_controller_generator.rb
124
+ - hobo_files/plugin/generators/hobo_user_controller/templates
125
+ - hobo_files/plugin/generators/hobo_user_controller/USAGE
126
+ - hobo_files/plugin/generators/hobo_user_controller/templates/controller.rb
127
+ - hobo_files/plugin/generators/hobo_user_controller/templates/functional_test.rb
128
+ - hobo_files/plugin/generators/hobo_user_controller/templates/helper.rb
129
+ - hobo_files/plugin/generators/hobo_user_controller/templates/view.rhtml
124
130
  - hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb
125
131
  - hobo_files/plugin/generators/hobo_user_model/templates
126
132
  - hobo_files/plugin/generators/hobo_user_model/USAGE
@@ -152,8 +158,8 @@ files:
152
158
  - hobo_files/plugin/lib/hobo/hobo_helper.rb
153
159
  - hobo_files/plugin/lib/hobo/html_string.rb
154
160
  - hobo_files/plugin/lib/hobo/lazy_hash.rb
155
- - hobo_files/plugin/lib/hobo/mapping_tags.rb
156
161
  - hobo_files/plugin/lib/hobo/markdown_string.rb
162
+ - hobo_files/plugin/lib/hobo/migrations.rb
157
163
  - hobo_files/plugin/lib/hobo/model.rb
158
164
  - hobo_files/plugin/lib/hobo/model_controller.rb
159
165
  - hobo_files/plugin/lib/hobo/model_queries.rb
@@ -168,8 +174,10 @@ files:
168
174
  - hobo_files/plugin/lib/hobo/textile_string.rb
169
175
  - hobo_files/plugin/lib/hobo/undefined.rb
170
176
  - hobo_files/plugin/lib/hobo/undefined_access_error.rb
177
+ - hobo_files/plugin/lib/hobo/user_controller.rb
171
178
  - hobo_files/plugin/lib/hobo/where_fragment.rb
172
179
  - hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb
180
+ - hobo_files/plugin/lib/hobo/dryml/part_context.rb
173
181
  - hobo_files/plugin/lib/hobo/dryml/scoped_variables.rb
174
182
  - hobo_files/plugin/lib/hobo/dryml/tag_module.rb
175
183
  - hobo_files/plugin/lib/hobo/dryml/taglib.rb
@@ -1,42 +0,0 @@
1
- <Page title="<%= app_name %>">
2
-
3
- <main>
4
- <h1 class="front_page_title"><%= app_name %></h1>
5
-
6
- <panel>
7
- <h2>Login to <%= app_name %></h2>
8
- <section>
9
- <%% form_tag do %>
10
- <table class="login_table">
11
- <tr>
12
- <td class="field_label"><label for="login">Username</label></td>
13
- <td><%%= text_field_tag 'login' %></td>
14
- </tr>
15
-
16
- <tr>
17
- <td class="field_label"><label for="password">Password</label></td>
18
- <td><%%= password_field_tag 'password' %></td>
19
- </tr>
20
-
21
- <!-- Uncomment if required. You will also need to
22
- add "before_filter :login_from_cookie" to ApplicationController
23
- <tr>
24
- <td class="field_label"><label for="remember_me">Remember me:</label></td>
25
- <td><%%= check_box_tag 'remember_me' %></td>
26
- </tr>
27
- -->
28
- </table>
29
-
30
- <p><submit label='Log in'/></p>
31
- <%% end %>
32
- </section>
33
- </panel>
34
-
35
- <panel>
36
- <div style="padding: 5px; text-align: center; font-style: italic;">
37
- Edit app/views/<%= full_class_path %>/login.dryml to customise this page
38
- </div>
39
- </panel>
40
- </main>
41
-
42
- </Page>
@@ -1,43 +0,0 @@
1
- <Page title="<%= app_name %>">
2
-
3
- <main>
4
- <h1 class="front_page_title"><%= app_name %></h1>
5
-
6
- <panel>
7
- <h2>Sign Up</h2>
8
- <section>
9
- <%%= error_messages_for :user %>
10
-
11
- <%% form_for :user do |f| %>
12
- <table class="login_table">
13
- <tr>
14
- <td class="field_label"><label for="login">Login</label></td>
15
- <td><%%= f.text_field 'login' %></td>
16
- </tr>
17
-
18
- <tr>
19
- <td class="field_label"><label for="password">Password</label></td>
20
- <td><%%= f.password_field 'password' %></td>
21
- </tr>
22
-
23
- <tr>
24
- <td class="field_label"><label for="password">Confirm Password</label></td>
25
- <td><%%= f.password_field 'password_confirmation' %></td>
26
- </tr>
27
-
28
- </table>
29
-
30
- <p><submit label='Sign Up'/></p>
31
- <%% end %>
32
- </section>
33
- </panel>
34
-
35
- <panel>
36
- <div style="padding: 5px; text-align: center; font-style: italic;">
37
- Edit app/views/<%= full_class_path %>/signup.dryml to customise this page
38
- </div>
39
- </panel>
40
- </main>
41
-
42
- </Page>
43
-
@@ -1,262 +0,0 @@
1
- module Hobo
2
- module MappingTags
3
-
4
- class InvalidMappingError < RuntimeError; end
5
-
6
- class TagOrSelector
7
-
8
- def initialize(name, all_mappings)
9
- @_name = name
10
- @_dot_names = []
11
- @_selectors = []
12
-
13
- # Keep a reference to the set of mappings for the whole
14
- # mapping_tags do ... end, so we can remove self if it turns out
15
- # to be an AttributeValueSelector
16
- @all_mappings = all_mappings
17
- end
18
-
19
- attr_accessor :_name, :_selectors, :_dot_names
20
-
21
- def method_missing(name)
22
- raise NoMethodError.new("undefined method: #{name}") if name.to_s =~ /^_|[!?=]$/
23
- _dot_names << name
24
- self
25
- end
26
-
27
-
28
- def [](*selectors)
29
- raise InvalidMappingError.new unless _selectors.empty?
30
-
31
- @_selectors = selectors.omap {_to_selector}
32
- self
33
- end
34
-
35
-
36
- def _to_selector
37
- raise InvalidMappingError.new unless _dot_names.empty? and _selectors.empty?
38
- AttributeSelector.new(_name)
39
- end
40
-
41
-
42
- def ==(rhs)
43
- raise InvalidMappingError.new unless _selectors.empty? and _dot_names.empty?
44
- AttributeValueSelector.new(_name, rhs)
45
- end
46
-
47
-
48
- def >>(rhs)
49
- @all_mappings << Mapping.new(self, rhs)
50
- nil
51
- end
52
-
53
- end
54
-
55
- class AttributeSelector
56
-
57
- def initialize(attribute)
58
- @attribute = attribute
59
- end
60
-
61
-
62
- def compile
63
- "options[:#{@attribute}]"
64
- end
65
- end
66
-
67
- class AttributeValueSelector
68
-
69
- def initialize(name, value)
70
- @name = name
71
- @value = value
72
- end
73
-
74
- attr_reader :name, :value
75
-
76
- def compile
77
- "(options[:#{@name}] == #{@value.inspect})"
78
- end
79
-
80
- def _to_selector
81
- self
82
- end
83
-
84
- end
85
-
86
-
87
- class Mapping
88
-
89
- def initialize(pattern, result)
90
- raise InvalidMappingError.new unless result._selectors.empty? and pattern._dot_names.length <= 1
91
- @pattern = pattern
92
- @result = result
93
- end
94
-
95
- attr_reader :pattern, :result
96
-
97
-
98
- def pattern_tag_name
99
- pattern._name
100
- end
101
-
102
-
103
- def pattern_predicate
104
- clauses = (pattern._selectors || []).omap{compile}
105
- type_name = pattern._dot_names.first
106
- clauses << "selector_type && (#{type_name.to_s.camelize} <= selector_type)" if type_name
107
- !clauses.empty? && "proc {|options| #{clauses.join(' and ')}}"
108
- end
109
-
110
-
111
- def result_tag_name
112
- result._name
113
- end
114
-
115
-
116
- def result_css_classes
117
- result._dot_names
118
- end
119
-
120
-
121
- end
122
-
123
-
124
- class MappingDSL
125
-
126
- def initialize
127
- @_mappings = []
128
- end
129
-
130
- attr_reader :_mappings
131
-
132
- def standard_mappings
133
- instance_eval do
134
- intro >> div.intro
135
- maincol >> div.maincol
136
- sidecol >> div.sidecol
137
- panel >> div.panel
138
- section >> div.section.foo
139
-
140
- fields >> table.fields
141
- field >> tr.field
142
- fl >> td.field_label
143
- fd >> td.field_data
144
- end
145
- end
146
-
147
- def method_missing(name, &b)
148
- raise NoMethodError.new("undefined method: #{name}") if name.to_s =~ /^_|[!?=]$/
149
- TagOrSelector.new(name, @_mappings)
150
- end
151
-
152
- end
153
-
154
- (Object.instance_methods +
155
- Object.private_instance_methods +
156
- Object.protected_instance_methods).each do |m|
157
- MappingDSL.send(:undef_method, m) unless
158
- %w{initialize method_missing instance_eval standard_mappings}.include?(m) || m.starts_with?('_')
159
- end
160
-
161
-
162
- def self.define_mapping_tag(mapping, mod)
163
- def_name = mapping.pattern_tag_name
164
- pred = mapping.pattern_predicate
165
- result_tag_name = mapping.result_tag_name
166
- result_css_classes = mapping.result_css_classes
167
-
168
- static_tag_name = result_tag_name if result_tag_name.to_s.in?(Hobo.static_tags)
169
-
170
- if def_name == result_tag_name
171
- result_tag_name = "#{def_name}_unmapped"
172
- if def_name.to_s.in?(mod.instance_methods) and result_tag_name.not_in?(mod.instance_methods)
173
- mod.send(:alias_method, result_tag_name, def_name)
174
- end
175
-
176
- if pred and !mod.predicate_has_default?(def_name)
177
- # Make sure the old tag method is called when the predicate is false
178
- mod.module_eval "defp(:#{def_name}) { |options, block| #{result_tag_name}(options, &block) }"
179
- end
180
- end
181
-
182
- # puts "map: #{def_name}[#{pred}] -> #{result_tag_name} (#{result_css_classes * ' '}) #{static_tag_name}"
183
-
184
- def_line = if !pred.blank?
185
- "defp :#{def_name}, (#{pred}) do |options, block|"
186
- elsif mod.predicate_method?(def_name)
187
- # be sure not to overwrite the predicate dispatch method
188
- "defp :#{def_name} do |options, block|"
189
- else
190
- "def #{def_name}(options={}, &block)"
191
- end
192
-
193
- add_classes = if result_css_classes.empty?
194
- ""
195
- else
196
- "options = add_classes(options, *#{result_css_classes.inspect})"
197
- end
198
-
199
- no_method_fallback = if static_tag_name
200
- "content_tag('#{static_tag_name}', tagbody && tagbody.call, options)"
201
- else
202
- "raise NoMethodError.new('undefined method: #{result_tag_name}')"
203
- end
204
-
205
- mod.module_eval(x = <<-END, __FILE__, __LINE__+1)
206
- #{def_line}
207
- _tag_context(options, block) do |tagbody|
208
- #{add_classes}
209
- if respond_to?('#{result_tag_name}')
210
- #{result_tag_name}(options, &block)
211
- else
212
- #{no_method_fallback}
213
- end
214
- end
215
- end
216
- END
217
- end
218
-
219
-
220
- def self.make_mappings(&b)
221
- d = MappingDSL.new
222
- d.instance_eval(&b)
223
- d._mappings
224
- end
225
-
226
-
227
- def self.map(&b)
228
- @mappings = make_mappings(&b)
229
- end
230
-
231
-
232
- def self.apply_mappings(mod)
233
- mod.send(:include, PredicateDispatch) unless PredicateDispatch.in?(mod.included_modules)
234
- @mappings.each {|m| define_mapping_tag(m, mod) }
235
- end
236
-
237
-
238
- def self.apply_standard_mappings(mod)
239
- mod.send(:include, PredicateDispatch) unless PredicateDispatch.in?(mod.included_modules)
240
- standard_mappings = make_mappings do
241
- intro >> div.intro
242
- main >> div.main
243
- maincol >> div.maincol
244
- sidecol >> div.sidecol
245
- panel >> div.panel
246
- section >> div.section
247
-
248
- fields >> table.fields
249
- field >> tr.field
250
- fl >> td.field_label
251
- fd >> td.field_data
252
- end
253
-
254
- for mapping in standard_mappings
255
- define_mapping_tag(mapping, mod) unless mapping.pattern_tag_name.to_s.in?(mod.instance_methods)
256
- end
257
-
258
- end
259
-
260
- end
261
-
262
- end