aura 0.0.1.pre10

Sign up to get free protection for your applications and to get access to all the features.
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