aura 0.0.1.pre10

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 (249) hide show
  1. data/.gitignore +6 -0
  2. data/.travis.yml +3 -0
  3. data/Gemfile +2 -0
  4. data/HISTORY.md +95 -0
  5. data/README.md +53 -0
  6. data/Rakefile +27 -0
  7. data/Scribefile +8 -0
  8. data/app/css/_utilities.scss +88 -0
  9. data/app/css/admin.scss +21 -0
  10. data/app/css/admin/_settings.scss +136 -0
  11. data/app/css/admin/chrome.scss +208 -0
  12. data/app/css/admin/common.scss +78 -0
  13. data/app/css/admin/forms.scss +342 -0
  14. data/app/css/admin/jquery_wysiwyg.scss +96 -0
  15. data/app/css/admin/loading.scss +18 -0
  16. data/app/css/admin/meta.scss +42 -0
  17. data/app/css/admin/reset.scss +46 -0
  18. data/app/css/admin/sections.scss +79 -0
  19. data/app/css/admin/setup.scss +22 -0
  20. data/app/css/admin/sidebar.scss +136 -0
  21. data/app/css/admin/slug.scss +78 -0
  22. data/app/css/admin/uiscreen.scss +22 -0
  23. data/app/css/admin/wysiwyg_field.scss +11 -0
  24. data/app/css/admin_watermark.scss +23 -0
  25. data/app/css/default_home_page.scss +13 -0
  26. data/app/css/login.scss +47 -0
  27. data/app/helpers/admin_helpers.rb +59 -0
  28. data/app/helpers/flash_helpers.rb +86 -0
  29. data/app/helpers/form_builder_helpers.rb +9 -0
  30. data/app/helpers/html_helpers.rb +27 -0
  31. data/app/helpers/jquery_helpers.rb +26 -0
  32. data/app/helpers/main_helpers.rb +67 -0
  33. data/app/helpers/page_helpers.rb +92 -0
  34. data/app/helpers/template_helpers.rb +94 -0
  35. data/app/helpers/user_helpers.rb +45 -0
  36. data/app/init/admin.rb +34 -0
  37. data/app/init/extensions.rb +18 -0
  38. data/app/init/pistol.rb +11 -0
  39. data/app/init/sequel.rb +11 -0
  40. data/app/main.rb +106 -0
  41. data/app/migrations/page.rb +29 -0
  42. data/app/migrations/settings.rb +11 -0
  43. data/app/migrations/user.rb +13 -0
  44. data/app/models/page.rb +116 -0
  45. data/app/models/page_seed.rb +47 -0
  46. data/app/models/settings.rb +59 -0
  47. data/app/models/user.rb +60 -0
  48. data/app/routes/admin.rb +44 -0
  49. data/app/routes/css_js.rb +53 -0
  50. data/app/routes/design_tests.rb +15 -0
  51. data/app/routes/editor.rb +152 -0
  52. data/app/routes/site.rb +33 -0
  53. data/app/routes/user.rb +48 -0
  54. data/app/views/admin/_back_to_dashboard.haml +3 -0
  55. data/app/views/admin/dashboard.haml +46 -0
  56. data/app/views/admin/layout.haml +73 -0
  57. data/app/views/admin/settings.haml +40 -0
  58. data/app/views/admin/settings/database.haml +42 -0
  59. data/app/views/base/crumbs.haml +50 -0
  60. data/app/views/base/delete.haml +19 -0
  61. data/app/views/base/edit.haml +61 -0
  62. data/app/views/base/errors.haml +10 -0
  63. data/app/views/base/form.haml +11 -0
  64. data/app/views/base/list.haml +14 -0
  65. data/app/views/base/list_actions.haml +4 -0
  66. data/app/views/base/list_item.haml +7 -0
  67. data/app/views/base/nav.haml +36 -0
  68. data/app/views/base/new.haml +36 -0
  69. data/app/views/base/preview.haml +28 -0
  70. data/app/views/base/tabs.haml +12 -0
  71. data/app/views/default_home_page.haml +15 -0
  72. data/app/views/design_tests/admin_styles.haml +58 -0
  73. data/app/views/form_builder/builder.haml +29 -0
  74. data/app/views/page/edit.haml +29 -0
  75. data/app/views/page/form.haml +22 -0
  76. data/app/views/page/meta_form.haml +22 -0
  77. data/app/views/page/new.haml +26 -0
  78. data/app/views/user/edit.haml +52 -0
  79. data/app/views/user/form.haml +43 -0
  80. data/app/views/user/list.haml +11 -0
  81. data/app/views/user/login.haml +33 -0
  82. data/app/views/user/new.haml +25 -0
  83. data/app/views/user/welcome.haml +29 -0
  84. data/app/views/watermark/watermark.haml +16 -0
  85. data/aura.gemspec +36 -0
  86. data/bin/aura +8 -0
  87. data/config/database.rb +12 -0
  88. data/config/extensions.rb +5 -0
  89. data/config/scss.rb +14 -0
  90. data/config/user.rb +10 -0
  91. data/default/.gitignore +6 -0
  92. data/default/Gemfile +11 -0
  93. data/default/README.md +24 -0
  94. data/default/Rakefile +8 -0
  95. data/default/app/README +3 -0
  96. data/default/app/css/.gitignore +0 -0
  97. data/default/app/helpers/helpers.rb.example +9 -0
  98. data/default/app/js/.gitignore +0 -0
  99. data/default/app/migrations/model.rb.example +20 -0
  100. data/default/app/models/model.rb.example +11 -0
  101. data/default/app/models/page-ext.rb.example +17 -0
  102. data/default/app/routes/site.rb.example +5 -0
  103. data/default/app/views/hello.haml.example +1 -0
  104. data/default/config.ru +3 -0
  105. data/default/config/.gitignore +0 -0
  106. data/default/config/database.rb.example +30 -0
  107. data/default/config/extensions.rb +5 -0
  108. data/default/config/user.rb.example +10 -0
  109. data/default/db/.gitignore +0 -0
  110. data/default/init.rb +15 -0
  111. data/default/public/.gitignore +0 -0
  112. data/extensions/contact_form/migrations/contact_form.rb +13 -0
  113. data/extensions/contact_form/models/contact_form.rb +13 -0
  114. data/extensions/contact_form/routes/contact_form.rb +11 -0
  115. data/extensions/contact_form/views/contact_form/edit.haml +8 -0
  116. data/extensions/contact_form/views/contact_form/form.haml +3 -0
  117. data/extensions/contact_form/views/contact_form/nav.haml +42 -0
  118. data/extensions/contact_form/views/contact_form/responses.haml +20 -0
  119. data/extensions/contact_form/views/contact_form/tabs.haml +8 -0
  120. data/extensions/default_theme/css/theme/_settings.scss +3 -0
  121. data/extensions/default_theme/css/theme/chrome.scss +66 -0
  122. data/extensions/default_theme/css/theme/reset.scss +34 -0
  123. data/extensions/default_theme/css/theme/style.scss +3 -0
  124. data/extensions/default_theme/info.yml +2 -0
  125. data/extensions/default_theme/public/browse.png +0 -0
  126. data/extensions/default_theme/views/base/id_portfolio.haml +32 -0
  127. data/extensions/default_theme/views/base/show.haml +31 -0
  128. data/extensions/default_theme/views/errors/error.haml +9 -0
  129. data/extensions/default_theme/views/errors/not_found.haml +11 -0
  130. data/extensions/default_theme/views/layout.haml +33 -0
  131. data/lib/aura.rb +315 -0
  132. data/lib/aura/admin.rb +41 -0
  133. data/lib/aura/app.rb +4 -0
  134. data/lib/aura/cli.rb +19 -0
  135. data/lib/aura/cli/base.rb +89 -0
  136. data/lib/aura/cli/helpers.rb +32 -0
  137. data/lib/aura/editor.rb +30 -0
  138. data/lib/aura/extension.rb +189 -0
  139. data/lib/aura/files.rb +38 -0
  140. data/lib/aura/menu.rb +142 -0
  141. data/lib/aura/models.rb +80 -0
  142. data/lib/aura/public.rb +68 -0
  143. data/lib/aura/rendering.rb +134 -0
  144. data/lib/aura/seeder.rb +38 -0
  145. data/lib/aura/slugs.rb +87 -0
  146. data/lib/aura/subtype.rb +48 -0
  147. data/lib/aura/tasks.rb +24 -0
  148. data/lib/aura/tasks/common.rb +17 -0
  149. data/lib/aura/tasks/db.rake +54 -0
  150. data/lib/aura/utils.rb +81 -0
  151. data/lib/aura/version.rb +25 -0
  152. data/lib/core/hasharray.rb +65 -0
  153. data/lib/core/object_ext.rb +9 -0
  154. data/lib/sequel/plugins/aura_custom.rb +16 -0
  155. data/lib/sequel/plugins/aura_editable.rb +39 -0
  156. data/lib/sequel/plugins/aura_hierarchy.rb +82 -0
  157. data/lib/sequel/plugins/aura_model.rb +271 -0
  158. data/lib/sequel/plugins/aura_renderable.rb +42 -0
  159. data/lib/sequel/plugins/aura_sluggable.rb +103 -0
  160. data/lib/sequel/plugins/aura_subtyped.rb +83 -0
  161. data/lib/terra.rb +185 -0
  162. data/lib/terra/ext.rb +16 -0
  163. data/lib/terra/field.rb +98 -0
  164. data/lib/terra/fields.rb +122 -0
  165. data/lib/terra/fieldset.rb +93 -0
  166. data/lib/terra/form.rb +111 -0
  167. data/manual/configuration.md +42 -0
  168. data/manual/extensions.md +45 -0
  169. data/manual/files.md +70 -0
  170. data/manual/helpers.md +39 -0
  171. data/manual/index.md +65 -0
  172. data/manual/models.md +58 -0
  173. data/manual/recipes.md +38 -0
  174. data/manual/recipes/bundling_sample_data.md +30 -0
  175. data/manual/recipes/creating_themes.md +10 -0
  176. data/manual/recipes/using_markdown_or_textile.md +24 -0
  177. data/manual/routes.md +39 -0
  178. data/manual/theming.md +55 -0
  179. data/manual/views.md +128 -0
  180. data/public/hi.html +0 -0
  181. data/public/images/admin/back.png +0 -0
  182. data/public/images/admin/browse.png +0 -0
  183. data/public/images/admin/mock-bg.png +0 -0
  184. data/public/images/admin/top-loader.gif +0 -0
  185. data/public/images/admin/uiscreen-loader.gif +0 -0
  186. data/public/images/admin_icons/add.png +0 -0
  187. data/public/images/admin_icons/contact.png +0 -0
  188. data/public/images/admin_icons/dashboard.png +0 -0
  189. data/public/images/admin_icons/generic.png +0 -0
  190. data/public/images/admin_icons/home-12.png +0 -0
  191. data/public/images/admin_icons/page.png +0 -0
  192. data/public/images/admin_icons/settings.png +0 -0
  193. data/public/images/jquery.wysiwyg.gif +0 -0
  194. data/public/js/admin.form_builder.js +15 -0
  195. data/public/js/admin.js +62 -0
  196. data/public/js/admin.layout.js +53 -0
  197. data/public/js/admin.nav.js +241 -0
  198. data/public/js/admin.slug.js +46 -0
  199. data/public/js/admin.subpage.js +15 -0
  200. data/public/js/jquery.hashlisten.js +85 -0
  201. data/public/js/jquery.js +166 -0
  202. data/public/js/jquery.livenavigate.js +58 -0
  203. data/public/js/jquery.livequery.js +226 -0
  204. data/public/js/jquery.quickvalidate.js +164 -0
  205. data/public/js/jquery.tmpl.js +486 -0
  206. data/public/js/jquery.uiscreen.js +150 -0
  207. data/public/js/jquery.wysiwyg.js +2339 -0
  208. data/public/js/jqueryui.js +766 -0
  209. data/public/js/lib.dirty.js +11 -0
  210. data/public/js/lib.loading.js +23 -0
  211. data/public/js/lib.wysiwyg.js +155 -0
  212. data/public/js/underscore-1.1.7.js +27 -0
  213. data/test/app/app/css/test_raw.css +1 -0
  214. data/test/app/app/css/test_sass.sass +3 -0
  215. data/test/app/app/damogram.txt +1 -0
  216. data/test/app/app/js/test_coffee.coffee +4 -0
  217. data/test/app/app/js/test_javascript.js +4 -0
  218. data/test/app/init.rb +5 -0
  219. data/test/stories/admin_css_story.rb +18 -0
  220. data/test/stories/css_js_story.rb +29 -0
  221. data/test/stories/first_login_story.rb +29 -0
  222. data/test/stories/visit_story.rb +39 -0
  223. data/test/stories_helper.rb +58 -0
  224. data/test/test_cli_helper.rb +31 -0
  225. data/test/test_helper.rb +111 -0
  226. data/test/test_temp_helper.rb +9 -0
  227. data/test/unit/cli_test.rb +38 -0
  228. data/test/unit/dump_test.rb +14 -0
  229. data/test/unit/extensions_test.rb +18 -0
  230. data/test/unit/files_test.rb +14 -0
  231. data/test/unit/flash_helper_test.rb +36 -0
  232. data/test/unit/html_helper_test.rb +29 -0
  233. data/test/unit/jquery_helper_test.rb +18 -0
  234. data/test/unit/model_test.rb +34 -0
  235. data/test/unit/page_helpers_test.rb +36 -0
  236. data/test/unit/seeder_test.rb +15 -0
  237. data/test/unit/settings_test.rb +29 -0
  238. data/test/unit/slug_test.rb +39 -0
  239. data/test/unit/ss_migration_test.rb +14 -0
  240. data/test/unit/terra_test.rb +125 -0
  241. data/test/unit/utils_test.rb +11 -0
  242. data/vendor/sinatra-sequel/.gitignore +3 -0
  243. data/vendor/sinatra-sequel/COPYING +18 -0
  244. data/vendor/sinatra-sequel/README.md +84 -0
  245. data/vendor/sinatra-sequel/Rakefile +67 -0
  246. data/vendor/sinatra-sequel/lib/sinatra/sequel.rb +73 -0
  247. data/vendor/sinatra-sequel/sinatra-sequel.gemspec +39 -0
  248. data/vendor/sinatra-sequel/spec/spec_sinatra_sequel.rb +70 -0
  249. metadata +536 -0
@@ -0,0 +1,83 @@
1
+ # Sequel plugin: AuraSubtyped
2
+ # Ensures a model has subtypes.
3
+ #
4
+ module Sequel
5
+ module Plugins
6
+ module AuraSubtyped
7
+ module InstanceMethods
8
+ def template
9
+ subtype.try(:template) || 'show'
10
+ end
11
+
12
+ # Method: subtype (AuraSubtyped)
13
+ # Returns the subtype for the given page.
14
+ #
15
+ # ## Description
16
+ # Returns an {Aura::Subtype}, or nil.
17
+ #
18
+ def subtype
19
+ re = nil
20
+ re ||= @values[:subtype]
21
+
22
+ if parent && parent.subtype && parent.subtype.allowed_subtypes
23
+ re ||= parent.subtype.allowed_subtypes.first
24
+ end
25
+
26
+ self.class.subtype re.to_sym if re
27
+ end
28
+ end
29
+
30
+ module ClassMethods
31
+ def subtyped?
32
+ true
33
+ end
34
+
35
+ # Class method: subtype_ (AuraSubtyped)
36
+ # Returns the definition for a given subtype.
37
+ #
38
+ # ## Description
39
+ # If options are given, sets the options for the given subtype.
40
+ #
41
+ # This can also be called as an instance method.
42
+ #
43
+ # ## Usage
44
+ # class Page
45
+ # subtype NAME,
46
+ # :name => FULL_NAME,
47
+ # :template => TEMPLATE
48
+ # end
49
+ #
50
+ # ## Example
51
+ #
52
+ # #### Subtype example
53
+ # This example defines a subtype called 'portfolio'.
54
+ # The template it will use is `:page/portfolio`.
55
+ #
56
+ # class Page
57
+ # subtype :portfolio,
58
+ # :name => "Portfolio page",
59
+ # :template => "portfolio"
60
+ # end
61
+ #
62
+ def subtype(name, options=nil)
63
+ @@subtypes ||= Hash.new
64
+
65
+ return @@subtypes[name] if options.nil?
66
+ raise ArgumentError unless options.is_a? Hash
67
+
68
+ @@subtypes[name] = Aura::Subtype.new(options.merge({:id => name }))
69
+ end
70
+
71
+ def subtypes
72
+ @@subtypes ||= Hash.new
73
+
74
+ @@subtypes[:default] ||= Aura::Subtype.new :id => :default,
75
+ :name => 'Default',
76
+ :template => 'show'
77
+
78
+ @@subtypes.values.sort_by { |st| st._id.to_s }
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,185 @@
1
+ # Module: Terra
2
+ # Terra is a form builder.
3
+ #
4
+ # #### Form DSL
5
+ # Configure your form with a Ruby DSL like so.
6
+ #
7
+ # form = Terra::Form.new
8
+ # form.configure do
9
+ # text :name, "Name"
10
+ # text :email, "Email address"
11
+ #
12
+ # fieldset :options, "Options" {
13
+ # textarea :body, "Body", :class => "hello"
14
+ # options :type, "Type",
15
+ # :options => {
16
+ # :red => "Red",
17
+ # :blue => "Blue"
18
+ # }
19
+ # }
20
+ # end
21
+ #
22
+ # ## Using in Aura models
23
+ #
24
+ # #### Using in Aura models
25
+ # In your models, simply use the `form` method to enclose
26
+ # the Terra form DSL in.
27
+ #
28
+ # class BlogPost < Sequel::Model
29
+ # form {
30
+ # text :title, "Title"
31
+ # text :body, "Body"
32
+ # }
33
+ # end
34
+ #
35
+ # #### Accessing
36
+ # You'll then be able to access it like so:
37
+ #
38
+ # BlogPost.form
39
+ # BlogPost.form.fieldsets
40
+ #
41
+ # #### AuraEditable
42
+ # In Aura, by default, if you model uses the {AuraEditable} plugin,
43
+ # simply define a form and you'll have new/edit pages in the admin
44
+ # for your model, automagically.
45
+ #
46
+ # [app/models/book.rb (rb)]
47
+ # class Book < Sequel::Model
48
+ # plugin :aura_editable
49
+ #
50
+ # form {
51
+ # # ...
52
+ # }
53
+ # end
54
+ #
55
+ # ## Info
56
+ #
57
+ # #### Defining fields
58
+ # Where `text` is the type of field, `:id` is the name of the
59
+ # field, `"Field name"` is what's to be displayed, and
60
+ # `{ options_hash }` is an optional list of settings. The field
61
+ # type can be any of `text`|`textarea`|`options`|`checkbox`.
62
+ #
63
+ # form {
64
+ # text :id, "Field name", { options_hash }
65
+ #
66
+ # textarea :body, "Body text"
67
+ # options :category, "Category"
68
+ # }
69
+ #
70
+ # #### View example
71
+ # You'll then be able to use it in your views like so:
72
+ #
73
+ # [app/views/_form.haml (haml)]
74
+ # - form.fieldsets.each do |set|
75
+ #
76
+ # -# The fieldset title
77
+ # %h3= set.to_s
78
+ #
79
+ # -# Form fields (generates <p>..<label>..<input> for each field)
80
+ # - set.fields.each do |field|
81
+ # = field.to_html
82
+ #
83
+ # ## Methods
84
+ #
85
+ # #### Form methods
86
+ # Here are some more useful {Terra::Form} methods.
87
+ #
88
+ # form.fieldsets # Returns an array of fieldsets
89
+ # set = form.fieldset(:default) # Returns a fieldset by name
90
+ #
91
+ # #### Fieldset methods
92
+ # Here are some more useful {Terra::Fieldset} methods.
93
+ #
94
+ # set.fields # Returns a fieldset's fields
95
+ # set.to_html # Returns <fieldset>..</fieldset> HTML
96
+ # set.to_html(object) # Same as above, but tries to get data from `object.field_name`
97
+ # set.name # Returns the name of the field
98
+ # field = set.field(:name) # Returns a field by name
99
+ #
100
+ # #### Field methods
101
+ # Here are some more useful {Terra::Field} methods.
102
+ #
103
+ # field.to_html # <p>..<label>..<input>..</p>
104
+ # field.to_html(val) # Like above, but with a certain value
105
+ # field.input_html # just <input>
106
+ # field.label_html # just <label>
107
+ #
108
+ # No, there's no `form.to_html`. Geez, don't even think about it--
109
+ # just render each of the fields/fieldsets.
110
+ #
111
+ # ## In practice
112
+ #
113
+ # #### HAML example
114
+ # This is how you would render a form in HAML.
115
+ #
116
+ # [app/views/_form.haml (haml)]
117
+ # %form{ :method => 'post', :action => '/save' }
118
+ # - form.fieldsets.each do |set|
119
+ # !~ set.to_html(@object)
120
+ #
121
+ # %p.submit
122
+ # %button{ :type => 'submit' } Save
123
+ #
124
+ # # HAML tip: use !~ instead of = to have your textareas
125
+ # # flow correctly by supressing HAML's extra whitespaces.
126
+ #
127
+ # #### More
128
+ #
129
+ # [app/views/_form.haml (haml)]
130
+ # = form.fieldsets.first.to_html
131
+ # = form.fieldsets.first.fields.first.to_html
132
+ #
133
+ # = form.fieldset(:default).to_html
134
+ # = form.fieldset(:default).field(:name).to_html
135
+ # = form.fieldset(:default).field(:name).to_html("Hello") # value
136
+ #
137
+ # ## Fields
138
+ #
139
+ # #### Text
140
+ # Text fields
141
+ #
142
+ # form.configure {
143
+ # text :name
144
+ # text :name, "First name"
145
+ # text :name, "First name", :class => 'title'
146
+ # }
147
+ #
148
+ # #### Options
149
+ # For dropdowns and radio buttons and such
150
+ #
151
+ # form.configure {
152
+ # options :category, "Category"
153
+ #
154
+ # # Choosing how to render it
155
+ # options :category, "Category", :type => 'radio'
156
+ # options :category, "Category", :type => 'dropdown'
157
+ #
158
+ # # Giving an options hash
159
+ # options :category, "Category", :options =>
160
+ # { 'a' => 'Apple', 'b' => 'Banana' }
161
+ #
162
+ # # Or a hash array
163
+ # options :category, "Category", :options =>
164
+ # [{ 'a' => 'Apple'},
165
+ # { 'b' => 'Banana' }
166
+ # ].to_hash_array
167
+ #
168
+ # # Or lambda
169
+ # options :category, "Category", :options =>
170
+ # lambda { |record|
171
+ # Categories.all.map { |c| { c.id => c.name } }.to_hash_array
172
+ # }
173
+ #
174
+ # # Not implemented yet
175
+ # options :category, "Category", :multi => true
176
+ # }
177
+ #
178
+ module Terra
179
+ PREFIX = File.dirname(__FILE__)
180
+ autoload :Field, "#{PREFIX}/terra/field"
181
+ autoload :Fields, "#{PREFIX}/terra/fields"
182
+ autoload :Fieldset, "#{PREFIX}/terra/fieldset"
183
+ autoload :Form, "#{PREFIX}/terra/form"
184
+ end
185
+
@@ -0,0 +1,16 @@
1
+ # Ensure that Terra is loaded first.
2
+ require File.join(File.dirname(__FILE__), '../terra')
3
+
4
+ module Terra
5
+ module Fields
6
+ # Class: Html (Terra::Fields)
7
+ # Inherits: {Terra::Field}
8
+ # An HTML field.
9
+ #
10
+ class Html < Textarea
11
+ def html_wrap(s)
12
+ "<p class='html #{options[:class] || ''}'>#{s}</p>"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,98 @@
1
+ # Class: Field (Terra)
2
+ # A field.
3
+ #
4
+ # ## Description
5
+ # See {Terra} for information on how to use the form builder.
6
+ #
7
+ module Terra
8
+ class Field
9
+ attr_accessor :name
10
+ attr_accessor :title
11
+ attr_accessor :options
12
+
13
+ def self.create(fieldset, type, name, title, options)
14
+ klass = Fields::get(type) || Fields::Text
15
+ klass.new(fieldset, name, title, options)
16
+ end
17
+
18
+ def initialize(fieldset, name, title, options={})
19
+ @fieldset = fieldset
20
+ @name = name
21
+ @title = title
22
+ @options = options
23
+ end
24
+
25
+ # Attribute: fieldset (Terra::Field)
26
+ # Returns the fieldset parent.
27
+ attr_reader :fieldset
28
+
29
+ # Attribute: form (Terra::Field)
30
+ # Returns the parent Form.
31
+ def form
32
+ fieldset.form
33
+ end
34
+
35
+ def inspect
36
+ "#<Field (#{self.class.to_s.split('::').last}): '#{name}'>"
37
+ end
38
+
39
+ # Method: id (Terra::Field)
40
+ # Returns the HTML ID for the field.
41
+ def id
42
+ "field_#{name}"
43
+ end
44
+
45
+ # Method: label_html (Terra::Field)
46
+ # Returns the HTML code for the <label> tag.
47
+ def label_html
48
+ "<label for='#{id}'>#{title}:</label>"
49
+ end
50
+
51
+ # Method: input_name (Terra::Field)
52
+ # Returns the HTML name attribute for the field's input element.
53
+ def input_name
54
+ form.name_for name
55
+ end
56
+
57
+ # Method: input_html (Terra::Field)
58
+ # Usage: input_html(value='', item=nil)
59
+ # Returns the HTML code for the input value.
60
+ #
61
+ # ## Description
62
+ # If a `value` is supplied, it will be used for the value of the input
63
+ # element.
64
+ #
65
+ def input_html(val='', item=nil)
66
+ "<input id='#{id}' type='text' name='#{input_name}' value='#{h val}' />"
67
+ end
68
+
69
+ # Method: to_html (Terra::Field)
70
+ # Usage: to_html(value='', item=nil)
71
+ # Returns the HTML code.
72
+ #
73
+ # ## Description
74
+ # If a `value` is supplied, it will be used for the value of the input
75
+ # element.
76
+ #
77
+ def to_html(val='', item=nil)
78
+ html_wrap [ label_html, input_html(val, item=nil) ].join("\n")
79
+ end
80
+
81
+ # Method: html_wrap (Terra::Field)
82
+ # Usage: html_wrap(html)
83
+ # Wraps the given HTML code with the field's field wrapper.
84
+ #
85
+ # ## Description
86
+ # If you don't like `<p>` as the field wrapper, reimplement this.
87
+ #
88
+ def html_wrap(s)
89
+ "<p class='#{options[:class] || ''}'>#{s}</p>"
90
+ end
91
+
92
+ protected
93
+ def h(str)
94
+ Rack::Utils.escape_html str.to_s
95
+ end
96
+ end
97
+ end
98
+
@@ -0,0 +1,122 @@
1
+ # Module: Fields (Terra)
2
+ # A module that is the namespace for all types of fields.
3
+ #
4
+ # ## Description
5
+ # See {Terra} for information on how to use the form builder.
6
+ #
7
+ module Terra
8
+ module Fields
9
+ def all
10
+ constants.map { |c| c.to_s.underscore.to_sym }
11
+ end
12
+
13
+ module_function :all
14
+
15
+ def get(klass)
16
+ begin
17
+ const_get(klass.to_s.split('_').map { |s| s.capitalize }.join('').to_sym)
18
+ rescue NameError
19
+ nil
20
+ end
21
+ end
22
+
23
+ module_function :get
24
+ end
25
+ end
26
+
27
+ module Terra
28
+ module Fields
29
+ # Class: Text (Terra::Fields)
30
+ # Inherits: {Terra::Field}
31
+ # A text field.
32
+ class Text < Field
33
+ end
34
+
35
+ # Class: Password (Terra::Fields)
36
+ # Inherits: {Terra::Field}
37
+ # A password field.
38
+ class Password < Field
39
+ def input_html(val='', item=nil)
40
+ "<input id='#{h id}' type='password' name='#{h input_name}' value='#{h val}'>"
41
+ end
42
+ end
43
+
44
+ # Class: Textarea (Terra::Fields)
45
+ # Inherits: {Terra::Field}
46
+ # A text area field.
47
+ class Textarea < Field
48
+ def input_html(val='', item=nil)
49
+ "<textarea id='#{h id}' type='text' name='#{h input_name}'>#{h val}</textarea>"
50
+ end
51
+ end
52
+
53
+ # Class: Checkbox (Terra::Fields)
54
+ # Inherits: {Terra::Field}
55
+ # A checkbox field.
56
+ class Checkbox < Field
57
+ def to_html(val='', item=nil)
58
+ html_wrap [ input_html(val, item), label_html ].join("\n")
59
+ end
60
+
61
+ def input_html(val='', item=nil)
62
+ truthy = val && !val.empty?
63
+
64
+ selected = ''
65
+ selected = " selected='selected'" if truthy
66
+
67
+ inputs = [ "<input type='hidden' name='#{h input_name}' value='0'>" ]
68
+ inputs+= [ "<input id='#{h id}' type='password' name='#{h input_name}' value='1'#{selected}>" ]
69
+
70
+ inputs.join("\n")
71
+ end
72
+ end
73
+
74
+ # Class: Options (Terra::Fields)
75
+ # Inherits: {Terra::Field}
76
+ # A field for radio buttons or dropdowns.
77
+ class Options < Field
78
+ def input_html(val='', item=nil)
79
+ return input_html_radio(val, item) if options[:type].to_s == 'radio'
80
+ input_html_select(val, item)
81
+ end
82
+
83
+ def input_html_select(val='', item=nil)
84
+ opts = @options[:options] || []
85
+ opts = opts.call(item) if opts.respond_to?(:call)
86
+
87
+ select = [ "<select id='#{h id}' name='#{h input_name}'>" ]
88
+ select+= opts.map { |opt|
89
+ opt = opt.flatten if opt.is_a? Hash
90
+ key, text = opt
91
+ text ||= key
92
+
93
+ selected = ''
94
+ selected = " selected='selected'" if val.to_s == key.to_s
95
+
96
+ "<option value='#{h key}'#{selected}>#{h text}</option>"
97
+ }
98
+ select+= [ "</select>" ]
99
+
100
+ select.join("\n")
101
+ end
102
+
103
+ def input_html_radio(val='', item=nil)
104
+ opts = @options[:options] || []
105
+ opts.map do |opt|
106
+ opt = opt.flatten if opt.is_a? Hash
107
+ key, text = opt
108
+ text ||= key
109
+
110
+ selected = ''
111
+ selected = " selected='selected'" if val.to_s == key.to_s
112
+
113
+ [ "<label for='#{h id}'>",
114
+ "<input type='radio' id='#{h id}' name='#{h input_name}' value='#{h key}'#{selected}>",
115
+ "<span>#{h text}</span>",
116
+ "</label>"
117
+ ]
118
+ end.flatten.join("\n")
119
+ end
120
+ end
121
+ end
122
+ end