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