hobo 0.6 → 0.6.1

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 (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