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.
- data/.gitignore +6 -0
- data/.travis.yml +3 -0
- data/Gemfile +2 -0
- data/HISTORY.md +95 -0
- data/README.md +53 -0
- data/Rakefile +27 -0
- data/Scribefile +8 -0
- data/app/css/_utilities.scss +88 -0
- data/app/css/admin.scss +21 -0
- data/app/css/admin/_settings.scss +136 -0
- data/app/css/admin/chrome.scss +208 -0
- data/app/css/admin/common.scss +78 -0
- data/app/css/admin/forms.scss +342 -0
- data/app/css/admin/jquery_wysiwyg.scss +96 -0
- data/app/css/admin/loading.scss +18 -0
- data/app/css/admin/meta.scss +42 -0
- data/app/css/admin/reset.scss +46 -0
- data/app/css/admin/sections.scss +79 -0
- data/app/css/admin/setup.scss +22 -0
- data/app/css/admin/sidebar.scss +136 -0
- data/app/css/admin/slug.scss +78 -0
- data/app/css/admin/uiscreen.scss +22 -0
- data/app/css/admin/wysiwyg_field.scss +11 -0
- data/app/css/admin_watermark.scss +23 -0
- data/app/css/default_home_page.scss +13 -0
- data/app/css/login.scss +47 -0
- data/app/helpers/admin_helpers.rb +59 -0
- data/app/helpers/flash_helpers.rb +86 -0
- data/app/helpers/form_builder_helpers.rb +9 -0
- data/app/helpers/html_helpers.rb +27 -0
- data/app/helpers/jquery_helpers.rb +26 -0
- data/app/helpers/main_helpers.rb +67 -0
- data/app/helpers/page_helpers.rb +92 -0
- data/app/helpers/template_helpers.rb +94 -0
- data/app/helpers/user_helpers.rb +45 -0
- data/app/init/admin.rb +34 -0
- data/app/init/extensions.rb +18 -0
- data/app/init/pistol.rb +11 -0
- data/app/init/sequel.rb +11 -0
- data/app/main.rb +106 -0
- data/app/migrations/page.rb +29 -0
- data/app/migrations/settings.rb +11 -0
- data/app/migrations/user.rb +13 -0
- data/app/models/page.rb +116 -0
- data/app/models/page_seed.rb +47 -0
- data/app/models/settings.rb +59 -0
- data/app/models/user.rb +60 -0
- data/app/routes/admin.rb +44 -0
- data/app/routes/css_js.rb +53 -0
- data/app/routes/design_tests.rb +15 -0
- data/app/routes/editor.rb +152 -0
- data/app/routes/site.rb +33 -0
- data/app/routes/user.rb +48 -0
- data/app/views/admin/_back_to_dashboard.haml +3 -0
- data/app/views/admin/dashboard.haml +46 -0
- data/app/views/admin/layout.haml +73 -0
- data/app/views/admin/settings.haml +40 -0
- data/app/views/admin/settings/database.haml +42 -0
- data/app/views/base/crumbs.haml +50 -0
- data/app/views/base/delete.haml +19 -0
- data/app/views/base/edit.haml +61 -0
- data/app/views/base/errors.haml +10 -0
- data/app/views/base/form.haml +11 -0
- data/app/views/base/list.haml +14 -0
- data/app/views/base/list_actions.haml +4 -0
- data/app/views/base/list_item.haml +7 -0
- data/app/views/base/nav.haml +36 -0
- data/app/views/base/new.haml +36 -0
- data/app/views/base/preview.haml +28 -0
- data/app/views/base/tabs.haml +12 -0
- data/app/views/default_home_page.haml +15 -0
- data/app/views/design_tests/admin_styles.haml +58 -0
- data/app/views/form_builder/builder.haml +29 -0
- data/app/views/page/edit.haml +29 -0
- data/app/views/page/form.haml +22 -0
- data/app/views/page/meta_form.haml +22 -0
- data/app/views/page/new.haml +26 -0
- data/app/views/user/edit.haml +52 -0
- data/app/views/user/form.haml +43 -0
- data/app/views/user/list.haml +11 -0
- data/app/views/user/login.haml +33 -0
- data/app/views/user/new.haml +25 -0
- data/app/views/user/welcome.haml +29 -0
- data/app/views/watermark/watermark.haml +16 -0
- data/aura.gemspec +36 -0
- data/bin/aura +8 -0
- data/config/database.rb +12 -0
- data/config/extensions.rb +5 -0
- data/config/scss.rb +14 -0
- data/config/user.rb +10 -0
- data/default/.gitignore +6 -0
- data/default/Gemfile +11 -0
- data/default/README.md +24 -0
- data/default/Rakefile +8 -0
- data/default/app/README +3 -0
- data/default/app/css/.gitignore +0 -0
- data/default/app/helpers/helpers.rb.example +9 -0
- data/default/app/js/.gitignore +0 -0
- data/default/app/migrations/model.rb.example +20 -0
- data/default/app/models/model.rb.example +11 -0
- data/default/app/models/page-ext.rb.example +17 -0
- data/default/app/routes/site.rb.example +5 -0
- data/default/app/views/hello.haml.example +1 -0
- data/default/config.ru +3 -0
- data/default/config/.gitignore +0 -0
- data/default/config/database.rb.example +30 -0
- data/default/config/extensions.rb +5 -0
- data/default/config/user.rb.example +10 -0
- data/default/db/.gitignore +0 -0
- data/default/init.rb +15 -0
- data/default/public/.gitignore +0 -0
- data/extensions/contact_form/migrations/contact_form.rb +13 -0
- data/extensions/contact_form/models/contact_form.rb +13 -0
- data/extensions/contact_form/routes/contact_form.rb +11 -0
- data/extensions/contact_form/views/contact_form/edit.haml +8 -0
- data/extensions/contact_form/views/contact_form/form.haml +3 -0
- data/extensions/contact_form/views/contact_form/nav.haml +42 -0
- data/extensions/contact_form/views/contact_form/responses.haml +20 -0
- data/extensions/contact_form/views/contact_form/tabs.haml +8 -0
- data/extensions/default_theme/css/theme/_settings.scss +3 -0
- data/extensions/default_theme/css/theme/chrome.scss +66 -0
- data/extensions/default_theme/css/theme/reset.scss +34 -0
- data/extensions/default_theme/css/theme/style.scss +3 -0
- data/extensions/default_theme/info.yml +2 -0
- data/extensions/default_theme/public/browse.png +0 -0
- data/extensions/default_theme/views/base/id_portfolio.haml +32 -0
- data/extensions/default_theme/views/base/show.haml +31 -0
- data/extensions/default_theme/views/errors/error.haml +9 -0
- data/extensions/default_theme/views/errors/not_found.haml +11 -0
- data/extensions/default_theme/views/layout.haml +33 -0
- data/lib/aura.rb +315 -0
- data/lib/aura/admin.rb +41 -0
- data/lib/aura/app.rb +4 -0
- data/lib/aura/cli.rb +19 -0
- data/lib/aura/cli/base.rb +89 -0
- data/lib/aura/cli/helpers.rb +32 -0
- data/lib/aura/editor.rb +30 -0
- data/lib/aura/extension.rb +189 -0
- data/lib/aura/files.rb +38 -0
- data/lib/aura/menu.rb +142 -0
- data/lib/aura/models.rb +80 -0
- data/lib/aura/public.rb +68 -0
- data/lib/aura/rendering.rb +134 -0
- data/lib/aura/seeder.rb +38 -0
- data/lib/aura/slugs.rb +87 -0
- data/lib/aura/subtype.rb +48 -0
- data/lib/aura/tasks.rb +24 -0
- data/lib/aura/tasks/common.rb +17 -0
- data/lib/aura/tasks/db.rake +54 -0
- data/lib/aura/utils.rb +81 -0
- data/lib/aura/version.rb +25 -0
- data/lib/core/hasharray.rb +65 -0
- data/lib/core/object_ext.rb +9 -0
- data/lib/sequel/plugins/aura_custom.rb +16 -0
- data/lib/sequel/plugins/aura_editable.rb +39 -0
- data/lib/sequel/plugins/aura_hierarchy.rb +82 -0
- data/lib/sequel/plugins/aura_model.rb +271 -0
- data/lib/sequel/plugins/aura_renderable.rb +42 -0
- data/lib/sequel/plugins/aura_sluggable.rb +103 -0
- data/lib/sequel/plugins/aura_subtyped.rb +83 -0
- data/lib/terra.rb +185 -0
- data/lib/terra/ext.rb +16 -0
- data/lib/terra/field.rb +98 -0
- data/lib/terra/fields.rb +122 -0
- data/lib/terra/fieldset.rb +93 -0
- data/lib/terra/form.rb +111 -0
- data/manual/configuration.md +42 -0
- data/manual/extensions.md +45 -0
- data/manual/files.md +70 -0
- data/manual/helpers.md +39 -0
- data/manual/index.md +65 -0
- data/manual/models.md +58 -0
- data/manual/recipes.md +38 -0
- data/manual/recipes/bundling_sample_data.md +30 -0
- data/manual/recipes/creating_themes.md +10 -0
- data/manual/recipes/using_markdown_or_textile.md +24 -0
- data/manual/routes.md +39 -0
- data/manual/theming.md +55 -0
- data/manual/views.md +128 -0
- data/public/hi.html +0 -0
- data/public/images/admin/back.png +0 -0
- data/public/images/admin/browse.png +0 -0
- data/public/images/admin/mock-bg.png +0 -0
- data/public/images/admin/top-loader.gif +0 -0
- data/public/images/admin/uiscreen-loader.gif +0 -0
- data/public/images/admin_icons/add.png +0 -0
- data/public/images/admin_icons/contact.png +0 -0
- data/public/images/admin_icons/dashboard.png +0 -0
- data/public/images/admin_icons/generic.png +0 -0
- data/public/images/admin_icons/home-12.png +0 -0
- data/public/images/admin_icons/page.png +0 -0
- data/public/images/admin_icons/settings.png +0 -0
- data/public/images/jquery.wysiwyg.gif +0 -0
- data/public/js/admin.form_builder.js +15 -0
- data/public/js/admin.js +62 -0
- data/public/js/admin.layout.js +53 -0
- data/public/js/admin.nav.js +241 -0
- data/public/js/admin.slug.js +46 -0
- data/public/js/admin.subpage.js +15 -0
- data/public/js/jquery.hashlisten.js +85 -0
- data/public/js/jquery.js +166 -0
- data/public/js/jquery.livenavigate.js +58 -0
- data/public/js/jquery.livequery.js +226 -0
- data/public/js/jquery.quickvalidate.js +164 -0
- data/public/js/jquery.tmpl.js +486 -0
- data/public/js/jquery.uiscreen.js +150 -0
- data/public/js/jquery.wysiwyg.js +2339 -0
- data/public/js/jqueryui.js +766 -0
- data/public/js/lib.dirty.js +11 -0
- data/public/js/lib.loading.js +23 -0
- data/public/js/lib.wysiwyg.js +155 -0
- data/public/js/underscore-1.1.7.js +27 -0
- data/test/app/app/css/test_raw.css +1 -0
- data/test/app/app/css/test_sass.sass +3 -0
- data/test/app/app/damogram.txt +1 -0
- data/test/app/app/js/test_coffee.coffee +4 -0
- data/test/app/app/js/test_javascript.js +4 -0
- data/test/app/init.rb +5 -0
- data/test/stories/admin_css_story.rb +18 -0
- data/test/stories/css_js_story.rb +29 -0
- data/test/stories/first_login_story.rb +29 -0
- data/test/stories/visit_story.rb +39 -0
- data/test/stories_helper.rb +58 -0
- data/test/test_cli_helper.rb +31 -0
- data/test/test_helper.rb +111 -0
- data/test/test_temp_helper.rb +9 -0
- data/test/unit/cli_test.rb +38 -0
- data/test/unit/dump_test.rb +14 -0
- data/test/unit/extensions_test.rb +18 -0
- data/test/unit/files_test.rb +14 -0
- data/test/unit/flash_helper_test.rb +36 -0
- data/test/unit/html_helper_test.rb +29 -0
- data/test/unit/jquery_helper_test.rb +18 -0
- data/test/unit/model_test.rb +34 -0
- data/test/unit/page_helpers_test.rb +36 -0
- data/test/unit/seeder_test.rb +15 -0
- data/test/unit/settings_test.rb +29 -0
- data/test/unit/slug_test.rb +39 -0
- data/test/unit/ss_migration_test.rb +14 -0
- data/test/unit/terra_test.rb +125 -0
- data/test/unit/utils_test.rb +11 -0
- data/vendor/sinatra-sequel/.gitignore +3 -0
- data/vendor/sinatra-sequel/COPYING +18 -0
- data/vendor/sinatra-sequel/README.md +84 -0
- data/vendor/sinatra-sequel/Rakefile +67 -0
- data/vendor/sinatra-sequel/lib/sinatra/sequel.rb +73 -0
- data/vendor/sinatra-sequel/sinatra-sequel.gemspec +39 -0
- data/vendor/sinatra-sequel/spec/spec_sinatra_sequel.rb +70 -0
- 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
|
data/lib/terra.rb
ADDED
|
@@ -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
|
+
|
data/lib/terra/ext.rb
ADDED
|
@@ -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
|
data/lib/terra/field.rb
ADDED
|
@@ -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
|
+
|
data/lib/terra/fields.rb
ADDED
|
@@ -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
|