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,82 @@
|
|
|
1
|
+
# Sequel plugin: AuraHierarchy
|
|
2
|
+
# Used on models that have children and parents.
|
|
3
|
+
#
|
|
4
|
+
# ## Description
|
|
5
|
+
# This automatically gives models parent/child support.
|
|
6
|
+
#
|
|
7
|
+
# #### How to use
|
|
8
|
+
# Use `plugin :aura_hierarchy` in your model.
|
|
9
|
+
#
|
|
10
|
+
# class Book < Sequel::Model
|
|
11
|
+
# plugin :aura_hierarchy
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# #### Database setup
|
|
15
|
+
# Add `:parent_id` to your schema.
|
|
16
|
+
#
|
|
17
|
+
# database.create_table :books do
|
|
18
|
+
# foreign_key :parent_id
|
|
19
|
+
# # ...
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# #### Example
|
|
23
|
+
# Our `Book` class can now have parents and children.
|
|
24
|
+
#
|
|
25
|
+
# book = Book[2]
|
|
26
|
+
#
|
|
27
|
+
# # Traversion
|
|
28
|
+
# book.parent
|
|
29
|
+
# book.children
|
|
30
|
+
# book.siblings
|
|
31
|
+
#
|
|
32
|
+
module Sequel::Plugins::AuraHierarchy
|
|
33
|
+
def self.configure(model, options={})
|
|
34
|
+
model.many_to_one :parent, :class => model
|
|
35
|
+
model.one_to_many :children, :key => :parent_id, :class => model
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
module InstanceMethods
|
|
39
|
+
def parentable?
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def siblings
|
|
44
|
+
if parent.nil?
|
|
45
|
+
self.class.filter(:parent_id => nil)
|
|
46
|
+
else
|
|
47
|
+
parent.children
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def prev_sibling
|
|
52
|
+
siblings.each_cons(2) { |(other, item)| return item if other.id == self.id }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def next_sibling
|
|
56
|
+
siblings.each_cons(2) { |(item, other)| return item if other.id == self.id }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def nearest
|
|
60
|
+
children.any? ? children : siblings
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def nearest_parent
|
|
64
|
+
children.any? ? self : parent
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def crumbs
|
|
68
|
+
return [self] if parent.nil?
|
|
69
|
+
parent.crumbs + [self]
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
module ClassMethods
|
|
74
|
+
def parentable?
|
|
75
|
+
true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def roots
|
|
79
|
+
filter(:parent_id => nil)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# Sequel plugin: AuraModel
|
|
2
|
+
# The base plugin for a model.
|
|
3
|
+
#
|
|
4
|
+
# ## Description
|
|
5
|
+
# All models use this plugin, and all methods it provides are available
|
|
6
|
+
# to all Aura/Sequel models.
|
|
7
|
+
#
|
|
8
|
+
module Sequel::Plugins::AuraModel
|
|
9
|
+
def self.configure(model)
|
|
10
|
+
model.plugin :validation_helpers
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module InstanceMethods
|
|
14
|
+
# Method: parent (AuraModel)
|
|
15
|
+
# Returns the parent.
|
|
16
|
+
#
|
|
17
|
+
def parent
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_s
|
|
22
|
+
begin
|
|
23
|
+
title
|
|
24
|
+
rescue NoMethodError
|
|
25
|
+
@values[:title] || self.class.to_s.split('::').last
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def validate!
|
|
30
|
+
raise Sequel::ValidationFailed(errors) unless valid?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Method: shown_in_menu? (AuraModel)
|
|
34
|
+
# Determines if the record should be shown to visitors in the site menus.
|
|
35
|
+
#
|
|
36
|
+
# ## Description
|
|
37
|
+
# This only affects the front-facing site, and has to influence as
|
|
38
|
+
# to whether it will be shown in the admin area.
|
|
39
|
+
#
|
|
40
|
+
# Override this.
|
|
41
|
+
#
|
|
42
|
+
def shown_in_menu?
|
|
43
|
+
false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def <=>(other)
|
|
47
|
+
self.sort_index <=> other.sort_index
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Method: sort_index (AuraModel)
|
|
51
|
+
# This is what they'll be sorted by.
|
|
52
|
+
#
|
|
53
|
+
# To enable sorting, implement a `position` field.
|
|
54
|
+
#
|
|
55
|
+
# You can reimplement this. Make sure it returns a tuple of an int and an int.
|
|
56
|
+
#
|
|
57
|
+
def sort_index
|
|
58
|
+
pos = nil
|
|
59
|
+
pos ||= self.position if self.respond_to?(:position)
|
|
60
|
+
[pos || 9999, self.id]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Method: set_fields (AuraModel)
|
|
64
|
+
# Sets the fields to the values in the hash.
|
|
65
|
+
#
|
|
66
|
+
# Overriding `set_fields` to make the 2nd param optional.
|
|
67
|
+
#
|
|
68
|
+
def set_fields(hash, keys=hash.keys)
|
|
69
|
+
super hash, keys
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def templates_for(template)
|
|
73
|
+
self.class.templates_for template
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Method: menu_title (AuraModel)
|
|
77
|
+
# Returns the name of the record as it should appear on the menu.
|
|
78
|
+
#
|
|
79
|
+
# This defaults to whatever the title of the record is (`#to_s`).
|
|
80
|
+
# Have your model override this if you need to.
|
|
81
|
+
#
|
|
82
|
+
def menu_title
|
|
83
|
+
to_s
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Method: path (AuraModel)
|
|
87
|
+
# Returns the URL path for the record.
|
|
88
|
+
#
|
|
89
|
+
# ## Example
|
|
90
|
+
#
|
|
91
|
+
# Page[1].path #=> '/products/cx-300'
|
|
92
|
+
# User[1].path #=> '/user/1' (because user is not sluggable.)
|
|
93
|
+
#
|
|
94
|
+
# Page[1].path(:edit) # => '/products/cx-300/edit'
|
|
95
|
+
#
|
|
96
|
+
def path(*a)
|
|
97
|
+
ret = "/#{self.class.class_name}/#{self.id}"
|
|
98
|
+
ret += "/#{a.shift.to_s}" if a.first.is_a?(String) || a.first.is_a?(Symbol)
|
|
99
|
+
ret += "?" + Aura::Utils.query_string(a.shift) if a.first.is_a?(Hash)
|
|
100
|
+
ret
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Method: parentable? (AuraModel)
|
|
104
|
+
# Determines if the record can have children.
|
|
105
|
+
#
|
|
106
|
+
# This is reimplemented by {AuraHierarchy}.
|
|
107
|
+
#
|
|
108
|
+
def parentable?
|
|
109
|
+
false
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Method: parent? (AuraModel)
|
|
113
|
+
# Determines if the record has a parent.
|
|
114
|
+
#
|
|
115
|
+
def parent?
|
|
116
|
+
! parent.nil?
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Method: children (AuraModel)
|
|
120
|
+
# Returns the children of the record.
|
|
121
|
+
def children
|
|
122
|
+
Array.new
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Method: submenu (AuraModel)
|
|
126
|
+
# Returns a list of items for the submenu.
|
|
127
|
+
#
|
|
128
|
+
# ## Example
|
|
129
|
+
#
|
|
130
|
+
# <% item.submenu.each do %>
|
|
131
|
+
# <li><% item.to_s %></li>
|
|
132
|
+
# <% end %>
|
|
133
|
+
#
|
|
134
|
+
def submenu
|
|
135
|
+
children.select { |item| item.shown_in_menu? }.sort
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Method: crumbs (AuraModel)
|
|
139
|
+
# Returns an array of records of breadcrumb path of the record, starting from the root.
|
|
140
|
+
#
|
|
141
|
+
def crumbs
|
|
142
|
+
[self]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Determines how far removed the record is from the root.
|
|
146
|
+
#
|
|
147
|
+
# ## Example
|
|
148
|
+
#
|
|
149
|
+
# p = Page[1]
|
|
150
|
+
# p.parent? #=> false
|
|
151
|
+
# p.depth #=> 1
|
|
152
|
+
#
|
|
153
|
+
def depth
|
|
154
|
+
crumbs.size
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def is_parent_of?(target)
|
|
158
|
+
target.crumbs.include?(self)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
module ClassMethods
|
|
163
|
+
# Class method: content? (AuraModel)
|
|
164
|
+
# Returns if the model data is considered to be site content.
|
|
165
|
+
#
|
|
166
|
+
# ## Description
|
|
167
|
+
# The site is considered empty if all models that are content?
|
|
168
|
+
# are empty.
|
|
169
|
+
#
|
|
170
|
+
def content?
|
|
171
|
+
false
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Class method: roots (AuraModel)
|
|
175
|
+
# Returns a set of results of all records that don't have parents.
|
|
176
|
+
#
|
|
177
|
+
# Returns a Sequel dataset.
|
|
178
|
+
def roots
|
|
179
|
+
select
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Class method: seed (AuraModel)
|
|
183
|
+
# Ensures that the model has some bare essentials in it.
|
|
184
|
+
#
|
|
185
|
+
# This is called every time the application initializes.
|
|
186
|
+
# Override this if you need certain records to exist, like as
|
|
187
|
+
# how there is always one user.
|
|
188
|
+
#
|
|
189
|
+
# As this is called every application load, if you override this,
|
|
190
|
+
# it is your responsibility to check if the model is #empty? before
|
|
191
|
+
# writing anything.
|
|
192
|
+
#
|
|
193
|
+
# A parameter `type` may be given. If this is set to `:sample`, then
|
|
194
|
+
# load up some sample data.
|
|
195
|
+
#
|
|
196
|
+
def seed(type=nil, &b)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Class method: seed! (AuraModel)
|
|
200
|
+
# Like `seed`, but empties the table first.
|
|
201
|
+
#
|
|
202
|
+
def seed!(type=nil, &b)
|
|
203
|
+
delete
|
|
204
|
+
seed type, &b
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Class method: parentable (AuraModel)
|
|
208
|
+
# Determines if the model can have children.
|
|
209
|
+
#
|
|
210
|
+
# Reimplemented by aura_hierarchy.
|
|
211
|
+
#
|
|
212
|
+
def parentable?
|
|
213
|
+
false
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def templates_for(template)
|
|
217
|
+
[ :"#{class_name}/#{template}",
|
|
218
|
+
:"base/#{template}"
|
|
219
|
+
]
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Class method: class_name (AuraModel)
|
|
223
|
+
# Returns a string of the model's name for use in URLs.
|
|
224
|
+
#
|
|
225
|
+
# ## Example
|
|
226
|
+
#
|
|
227
|
+
# BlogPost.class_name #=> "blog_post"
|
|
228
|
+
#
|
|
229
|
+
def class_name
|
|
230
|
+
self.to_s.demodulize.underscore
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Class method: title (AuraModel)
|
|
234
|
+
# Returns a string of the model's name to appear on pages.
|
|
235
|
+
#
|
|
236
|
+
# ## Example
|
|
237
|
+
#
|
|
238
|
+
# BlogPost.title #=> "Blog post"
|
|
239
|
+
#
|
|
240
|
+
def title
|
|
241
|
+
self.class_name.humanize
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Class method: title_plural (AuraModel)
|
|
245
|
+
# Returns a string of the model's name, pluralized, to appear on pages.
|
|
246
|
+
#
|
|
247
|
+
# ## Example
|
|
248
|
+
#
|
|
249
|
+
# BlogPost.title_plural #=> "Blog posts"
|
|
250
|
+
#
|
|
251
|
+
def title_plural
|
|
252
|
+
self.title.pluralize
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Class method: path (AuraModel)
|
|
256
|
+
# Returns a URL path for an action for the model.
|
|
257
|
+
#
|
|
258
|
+
# ## Example
|
|
259
|
+
#
|
|
260
|
+
# BlogPost.path #=> /blog_post
|
|
261
|
+
# BlogPost.path(:list) #=> /blog_post/list
|
|
262
|
+
# BlogPost.path(:list, :all) #=> /blog_post/list/all
|
|
263
|
+
#
|
|
264
|
+
def path(*a)
|
|
265
|
+
ret = "/#{class_name}"
|
|
266
|
+
ret += "/#{a.shift}" if a.first.is_a?(String) || a.first.is_a?(Symbol)
|
|
267
|
+
ret += "?" + Aura::Utils.query_string(a.shift) if a.first.is_a?(Hash)
|
|
268
|
+
ret
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Models that can be viewed by a URL.
|
|
2
|
+
# Supports templating and stuff.
|
|
3
|
+
#
|
|
4
|
+
# Assumptions:
|
|
5
|
+
#
|
|
6
|
+
# - Your data table must have `String :template`. (optional;
|
|
7
|
+
# Aura guesses the template name if it's not available.)
|
|
8
|
+
#
|
|
9
|
+
module Sequel
|
|
10
|
+
module Plugins
|
|
11
|
+
module AuraRenderable
|
|
12
|
+
module InstanceMethods
|
|
13
|
+
# Returns the templates to be tried for the item, listed
|
|
14
|
+
# in order of priority.
|
|
15
|
+
#
|
|
16
|
+
# Example:
|
|
17
|
+
#
|
|
18
|
+
# [ "product/mofo", "base/mofo", "product/default", "base/default" ]
|
|
19
|
+
#
|
|
20
|
+
def page_templates
|
|
21
|
+
klass = self.class.class_name # blog_post
|
|
22
|
+
|
|
23
|
+
[ :"#{klass}/#{template}",
|
|
24
|
+
:"base/#{template}",
|
|
25
|
+
:"#{klass}/show",
|
|
26
|
+
:"base/show"
|
|
27
|
+
].map { |s| s.to_sym }.uniq
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns the template to be used when it's displayed.
|
|
31
|
+
# Overridden by AuraSubtyped.
|
|
32
|
+
def template
|
|
33
|
+
'show'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def renderable?
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Sequel plugin: AuraSluggable
|
|
2
|
+
# Implemented for models that are to be accessible via a slug URL.
|
|
3
|
+
#
|
|
4
|
+
# ## Description
|
|
5
|
+
# This automatically gives models the ability to be accessed via a
|
|
6
|
+
# slug URL (like `/products/boots`).
|
|
7
|
+
#
|
|
8
|
+
# #### How to use
|
|
9
|
+
# Use `plugin :aura_sluggable`.
|
|
10
|
+
#
|
|
11
|
+
# class Book < Sequel::Model
|
|
12
|
+
# plugin :aura_sluggable
|
|
13
|
+
#
|
|
14
|
+
# # ...
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# #### Database setup
|
|
18
|
+
# Add `String :slug` to your schema.
|
|
19
|
+
#
|
|
20
|
+
# database.create_table :books do
|
|
21
|
+
# String :slug
|
|
22
|
+
# # ...
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
module Sequel
|
|
26
|
+
module Plugins
|
|
27
|
+
module AuraSluggable
|
|
28
|
+
def self.configure(model, opts={})
|
|
29
|
+
Aura.slugs.register(model)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module InstanceMethods
|
|
33
|
+
def sluggable?
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Method: path (AuraSluggable)
|
|
38
|
+
# Returns the URL path.
|
|
39
|
+
#
|
|
40
|
+
def path(*a)
|
|
41
|
+
return super if slug.nil?
|
|
42
|
+
ret = '/' + (slug.to_s)
|
|
43
|
+
ret = "#{parent.path}#{ret}" if respond_to?(:parent) && parent.respond_to?(:path)
|
|
44
|
+
ret += "/#{a.shift.to_s}" if a.first.is_a?(String) || a.first.is_a?(Symbol)
|
|
45
|
+
ret += "?" + Aura::Utils.query_string(a.shift) if a.first.is_a?(Hash)
|
|
46
|
+
ret
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Method: slugify (AuraSluggable)
|
|
50
|
+
# Returns a unique slug for the item.
|
|
51
|
+
#
|
|
52
|
+
# ## Example
|
|
53
|
+
# b = Book.new
|
|
54
|
+
# b.title = 'Darkly Dreaming Dexter'
|
|
55
|
+
#
|
|
56
|
+
# b.slugify #=> "darkly-dreaming-dexter"
|
|
57
|
+
# b.slugify("Dexter by Design") #=> "dexter-by-design"
|
|
58
|
+
#
|
|
59
|
+
def slugify(str=title)
|
|
60
|
+
str = str.to_s
|
|
61
|
+
str = str.scan(/[A-Za-z0-9]+/).join('-').downcase
|
|
62
|
+
i = 1
|
|
63
|
+
|
|
64
|
+
loop do
|
|
65
|
+
slug = str
|
|
66
|
+
slug = "#{str}-#{i}" if i>1
|
|
67
|
+
|
|
68
|
+
item = self.class.find(:slug => slug)
|
|
69
|
+
return slug if item.nil? || item == self
|
|
70
|
+
i += 1
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def validate
|
|
75
|
+
self.slug = self.slugify if self.slug.nil? or self.slug.empty?
|
|
76
|
+
super
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
module ClassMethods
|
|
81
|
+
def sluggable?
|
|
82
|
+
true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Class method: get_by_slug (AuraSluggable)
|
|
86
|
+
# Finds an item by a given slug.
|
|
87
|
+
#
|
|
88
|
+
# ## Example
|
|
89
|
+
# b = Book.get_by_slug('darkly-dreaming-dexter')
|
|
90
|
+
#
|
|
91
|
+
def get_by_slug(slug, parent=nil)
|
|
92
|
+
pid = parent.nil? ? nil : parent.id
|
|
93
|
+
|
|
94
|
+
if columns.include?(:parent_id)
|
|
95
|
+
find(:slug => slug, :parent_id => pid)
|
|
96
|
+
else
|
|
97
|
+
find(:slug => slug)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|