outpost-cms 0.0.3
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/MIT-LICENSE +20 -0
- data/README.md +295 -0
- data/Rakefile +26 -0
- data/app/assets/images/glyphicons-halflings-red.png +0 -0
- data/app/assets/javascripts/outpost/application.js +1 -0
- data/app/assets/javascripts/outpost/auto_slug_field.js.coffee +53 -0
- data/app/assets/javascripts/outpost/base.js.coffee +1 -0
- data/app/assets/javascripts/outpost/date_time_input.js.coffee +108 -0
- data/app/assets/javascripts/outpost/field_counter.js.coffee +93 -0
- data/app/assets/javascripts/outpost/field_manager.js.coffee +37 -0
- data/app/assets/javascripts/outpost/global_plugins.js.coffee +87 -0
- data/app/assets/javascripts/outpost/index_manager.js.coffee +88 -0
- data/app/assets/javascripts/outpost/notification.js.coffee +46 -0
- data/app/assets/javascripts/outpost/preview.js.coffee +60 -0
- data/app/assets/javascripts/outpost/templates/date_field.jst.eco +3 -0
- data/app/assets/javascripts/outpost/templates/loading.jst.eco +11 -0
- data/app/assets/javascripts/outpost/templates/slug_generate_button.jst.eco +1 -0
- data/app/assets/javascripts/outpost/templates/time_field.jst.eco +3 -0
- data/app/assets/javascripts/outpost/templates.js +1 -0
- data/app/assets/javascripts/outpost.js +32 -0
- data/app/assets/stylesheets/outpost/_base.css.scss +127 -0
- data/app/assets/stylesheets/outpost/_edit.css.scss +13 -0
- data/app/assets/stylesheets/outpost/_forms.css.scss +116 -0
- data/app/assets/stylesheets/outpost/_index.css.scss +68 -0
- data/app/assets/stylesheets/outpost/_utility.css.scss +16 -0
- data/app/assets/stylesheets/outpost/application.css.scss +1 -0
- data/app/assets/stylesheets/outpost/bootstrap/bootstrap.css.scss +49 -0
- data/app/assets/stylesheets/outpost/bootstrap/datepicker.css.scss +301 -0
- data/app/assets/stylesheets/outpost.css.scss +14 -0
- data/app/controllers/outpost/application_controller.rb +40 -0
- data/app/controllers/outpost/base_controller.rb +3 -0
- data/app/controllers/outpost/errors_controller.rb +9 -0
- data/app/controllers/outpost/home_controller.rb +2 -0
- data/app/controllers/outpost/resource_controller.rb +12 -0
- data/app/controllers/outpost/sessions_controller.rb +36 -0
- data/app/helpers/authorization_helper.rb +44 -0
- data/app/helpers/list_helper.rb +243 -0
- data/app/helpers/outpost_helper.rb +49 -0
- data/app/helpers/render_helper.rb +41 -0
- data/app/helpers/utility_helper.rb +136 -0
- data/app/inputs/date_time_input.rb +12 -0
- data/app/models/permission.rb +18 -0
- data/app/models/user_permission.rb +4 -0
- data/app/views/kaminari/bootstrap/_first_page.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_gap.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_last_page.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_next_page.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_page.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_paginator.html.erb +17 -0
- data/app/views/kaminari/bootstrap/_prev_page.html.erb +3 -0
- data/app/views/layouts/outpost/application.html.erb +101 -0
- data/app/views/layouts/outpost/minimal.html.erb +26 -0
- data/app/views/outpost/errors/error_404.html.erb +1 -0
- data/app/views/outpost/errors/error_500.html.erb +8 -0
- data/app/views/outpost/home/dashboard.html.erb +1 -0
- data/app/views/outpost/resource/_errors.html.erb +11 -0
- data/app/views/outpost/resource/_extra_fields.html.erb +1 -0
- data/app/views/outpost/resource/_form_fields.html.erb +9 -0
- data/app/views/outpost/resource/edit.html.erb +44 -0
- data/app/views/outpost/resource/index.html.erb +22 -0
- data/app/views/outpost/resource/new.html.erb +21 -0
- data/app/views/outpost/resource/search.html.erb +1 -0
- data/app/views/outpost/resource/show.html.erb +1 -0
- data/app/views/outpost/sessions/new.html.erb +16 -0
- data/app/views/outpost/shared/_add_link.html.erb +1 -0
- data/app/views/outpost/shared/_breadcrumbs.html.erb +15 -0
- data/app/views/outpost/shared/_cancel_link.html.erb +1 -0
- data/app/views/outpost/shared/_columns.html.erb +5 -0
- data/app/views/outpost/shared/_filters.html.erb +16 -0
- data/app/views/outpost/shared/_flash_messages.html.erb +6 -0
- data/app/views/outpost/shared/_form_block.html.erb +18 -0
- data/app/views/outpost/shared/_form_nav.html.erb +12 -0
- data/app/views/outpost/shared/_headers.html.erb +16 -0
- data/app/views/outpost/shared/_index_header.html.erb +4 -0
- data/app/views/outpost/shared/_list_table.html.erb +7 -0
- data/app/views/outpost/shared/_modal.html.erb +16 -0
- data/app/views/outpost/shared/_navigation.html.erb +31 -0
- data/app/views/outpost/shared/_notice.html.erb +1 -0
- data/app/views/outpost/shared/_pagination.html.erb +2 -0
- data/app/views/outpost/shared/_preview_errors.html.erb +9 -0
- data/app/views/outpost/shared/_submit_row.html.erb +50 -0
- data/config/routes.rb +4 -0
- data/lib/action_view/helpers/form_builder.rb +71 -0
- data/lib/outpost/breadcrumbs.rb +73 -0
- data/lib/outpost/config.rb +63 -0
- data/lib/outpost/controller/actions.rb +72 -0
- data/lib/outpost/controller/authentication.rb +34 -0
- data/lib/outpost/controller/authorization.rb +28 -0
- data/lib/outpost/controller/callbacks.rb +14 -0
- data/lib/outpost/controller/custom_errors.rb +41 -0
- data/lib/outpost/controller/filtering.rb +22 -0
- data/lib/outpost/controller/helpers.rb +52 -0
- data/lib/outpost/controller/ordering.rb +46 -0
- data/lib/outpost/controller/preferences.rb +71 -0
- data/lib/outpost/controller.rb +123 -0
- data/lib/outpost/engine.rb +10 -0
- data/lib/outpost/helpers/naming.rb +22 -0
- data/lib/outpost/helpers.rb +6 -0
- data/lib/outpost/hook.rb +35 -0
- data/lib/outpost/list/base.rb +78 -0
- data/lib/outpost/list/column.rb +24 -0
- data/lib/outpost/list/filter.rb +37 -0
- data/lib/outpost/list.rb +15 -0
- data/lib/outpost/model/authentication.rb +34 -0
- data/lib/outpost/model/authorization.rb +32 -0
- data/lib/outpost/model/identifier.rb +39 -0
- data/lib/outpost/model/methods.rb +23 -0
- data/lib/outpost/model/naming.rb +63 -0
- data/lib/outpost/model/routing.rb +138 -0
- data/lib/outpost/model/serializer.rb +27 -0
- data/lib/outpost/model.rb +22 -0
- data/lib/outpost/test.rb +21 -0
- data/lib/outpost/version.rb +3 -0
- data/lib/outpost-cms.rb +2 -0
- data/lib/outpost.rb +80 -0
- data/lib/tasks/outpost_tasks.rake +7 -0
- data/spec/controllers/authentication_spec.rb +62 -0
- data/spec/controllers/sessions_controller_spec.rb +99 -0
- data/spec/factories.rb +31 -0
- data/spec/helpers/authorization_helper_spec.rb +47 -0
- data/spec/helpers/list_helper_spec.rb +74 -0
- data/spec/helpers/outpost_helper_spec.rb +5 -0
- data/spec/helpers/render_helper_spec.rb +19 -0
- data/spec/helpers/utility_helper_spec.rb +53 -0
- data/spec/internal/app/controllers/application_controller.rb +3 -0
- data/spec/internal/app/controllers/outpost/people_controller.rb +23 -0
- data/spec/internal/app/controllers/outpost/pidgeons_controller.rb +5 -0
- data/spec/internal/app/controllers/people_controller.rb +9 -0
- data/spec/internal/app/controllers/pidgeons_controller.rb +3 -0
- data/spec/internal/app/models/person.rb +10 -0
- data/spec/internal/app/models/pidgeon.rb +3 -0
- data/spec/internal/app/models/post.rb +4 -0
- data/spec/internal/app/models/user.rb +4 -0
- data/spec/internal/app/views/people/index.html.erb +7 -0
- data/spec/internal/app/views/people/show.html.erb +1 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/initializers/configuration.rb +3 -0
- data/spec/internal/config/initializers/outpost.rb +6 -0
- data/spec/internal/config/routes.rb +16 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +44 -0
- data/spec/internal/db/seeds.rb +14 -0
- data/spec/internal/log/test.log +59277 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/breadcrumbs_spec.rb +54 -0
- data/spec/lib/config_spec.rb +76 -0
- data/spec/lib/controller/actions_spec.rb +5 -0
- data/spec/lib/controller/authorization_spec.rb +4 -0
- data/spec/lib/controller/callbacks_spec.rb +31 -0
- data/spec/lib/controller/helpers_spec.rb +33 -0
- data/spec/lib/controller_spec.rb +25 -0
- data/spec/lib/helpers/naming_spec.rb +10 -0
- data/spec/lib/hook_spec.rb +13 -0
- data/spec/lib/list/base_spec.rb +96 -0
- data/spec/lib/list/column_spec.rb +46 -0
- data/spec/lib/list/filter_spec.rb +44 -0
- data/spec/lib/model/authentication_spec.rb +29 -0
- data/spec/lib/model/authorization_spec.rb +66 -0
- data/spec/lib/model/identifier_spec.rb +51 -0
- data/spec/lib/model/methods_spec.rb +8 -0
- data/spec/lib/model/naming_spec.rb +55 -0
- data/spec/lib/model/routing_spec.rb +166 -0
- data/spec/lib/model/serializer_spec.rb +13 -0
- data/spec/lib/outpost_spec.rb +34 -0
- data/spec/models/permission_spec.rb +10 -0
- data/spec/models/user_permission_spec.rb +4 -0
- data/spec/spec_helper.rb +22 -0
- metadata +411 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
module ListHelper
|
|
2
|
+
# Public: Renders the attribute for this column and record
|
|
3
|
+
#
|
|
4
|
+
# column - (Outpost::Column) The column object.
|
|
5
|
+
# record - (Object) The ActiveRecord object being listed.
|
|
6
|
+
#
|
|
7
|
+
# Examples
|
|
8
|
+
#
|
|
9
|
+
# column.attribute # => :published_at
|
|
10
|
+
# <%= render_attribute(column, @post) %>
|
|
11
|
+
# # => 2013-03-13 11:39:37 -0700
|
|
12
|
+
#
|
|
13
|
+
# Returns String of the rendered attribute.
|
|
14
|
+
def render_attribute(column, record)
|
|
15
|
+
if column.display.is_a? Proc
|
|
16
|
+
# If we passed a Proc to :display, use it.
|
|
17
|
+
record.instance_eval(&column.display)
|
|
18
|
+
else
|
|
19
|
+
if column._display_helper.present?
|
|
20
|
+
# If we've already figured out which method to use for
|
|
21
|
+
# this column, then use it. This is to prevent this method
|
|
22
|
+
# from having to fully run hundreds of times on each page.
|
|
23
|
+
display_helper = column._display_helper
|
|
24
|
+
|
|
25
|
+
elsif column.display.is_a? Symbol
|
|
26
|
+
display_helper = column.display
|
|
27
|
+
|
|
28
|
+
elsif self.methods.include? :"display_#{column.attribute}"
|
|
29
|
+
# If we have explicitly defined a helper for this attribute, use it.
|
|
30
|
+
display_helper = :"display_#{column.attribute}"
|
|
31
|
+
|
|
32
|
+
elsif record.class.respond_to?(:reflect_on_association) &&
|
|
33
|
+
record.class.reflect_on_association(column.attribute.to_sym)
|
|
34
|
+
# For associations, display the associated object's #to_title
|
|
35
|
+
display_helper = :display_record
|
|
36
|
+
|
|
37
|
+
elsif record.class.respond_to?(:columns_hash) &&
|
|
38
|
+
(ar_column = record.class.columns_hash[column.attribute]) &&
|
|
39
|
+
self.methods.include?(type_helper = :"display_#{ar_column.type}")
|
|
40
|
+
# display_#{column_type} for generic display
|
|
41
|
+
# Example: display_datetime
|
|
42
|
+
display_helper = type_helper
|
|
43
|
+
|
|
44
|
+
else
|
|
45
|
+
# Fallback to just using attribute.to_s
|
|
46
|
+
display_helper = :display_string
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
value = record.send(column.attribute)
|
|
50
|
+
column._display_helper = display_helper
|
|
51
|
+
send(display_helper, value)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Public: Format a DateTime for displaying in lists
|
|
56
|
+
#
|
|
57
|
+
# date - (DateTime) The date to be formatted
|
|
58
|
+
#
|
|
59
|
+
# Examples
|
|
60
|
+
#
|
|
61
|
+
# display_date(Time.now)
|
|
62
|
+
# # => March 13th, 2012
|
|
63
|
+
#
|
|
64
|
+
# Returns String of formatted date
|
|
65
|
+
def display_date(date)
|
|
66
|
+
format_date(date, format: :full_date)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Public: Display the attribute or "[blank]" if not present
|
|
70
|
+
#
|
|
71
|
+
# attrib - (String) The attribute to display
|
|
72
|
+
# options - (Hash) A hash of options (default: {}).
|
|
73
|
+
# fallback - (String) The string to use as placeholder text
|
|
74
|
+
# (default: "[blank]").
|
|
75
|
+
#
|
|
76
|
+
# Examples
|
|
77
|
+
#
|
|
78
|
+
# display_or_fallback("Foo")
|
|
79
|
+
# # => Foo
|
|
80
|
+
#
|
|
81
|
+
# display_or_fallback("", fallback: "none")
|
|
82
|
+
# # => none
|
|
83
|
+
#
|
|
84
|
+
# Returns String of either the attribute (if present) or "[blank]"
|
|
85
|
+
def display_or_fallback(attrib, options={})
|
|
86
|
+
fallback = options[:fallback] || "[blank]"
|
|
87
|
+
attrib.present? ? attrib.to_s : content_tag(:em, fallback)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Public: Display the attribute as a string.
|
|
91
|
+
#
|
|
92
|
+
# attrib - (String) The attribute to display.
|
|
93
|
+
#
|
|
94
|
+
# Examples
|
|
95
|
+
#
|
|
96
|
+
# display_string("anything")
|
|
97
|
+
# # => "anything"
|
|
98
|
+
#
|
|
99
|
+
# Returns String of the attribute
|
|
100
|
+
def display_string(attrib)
|
|
101
|
+
attrib.to_s
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Public: Displays an String representation of the record using +#to_title+.
|
|
105
|
+
#
|
|
106
|
+
# record - (String) The associated record.
|
|
107
|
+
#
|
|
108
|
+
# Examples
|
|
109
|
+
#
|
|
110
|
+
# user = User.last
|
|
111
|
+
# user.to_title # => "James Earl Jones"
|
|
112
|
+
# display_record(User.last)
|
|
113
|
+
# # => "James Earl Jones"
|
|
114
|
+
#
|
|
115
|
+
# Returns String representation of the passed-in record.
|
|
116
|
+
def display_record(record)
|
|
117
|
+
record.try(:to_title)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Public: Display a formatted DateTime.
|
|
121
|
+
#
|
|
122
|
+
# datetime - (DateTime) The DateTime object to format.
|
|
123
|
+
#
|
|
124
|
+
# Examples
|
|
125
|
+
#
|
|
126
|
+
# display_datetime(Time.now)
|
|
127
|
+
# # => "March 13th, 2013, 4:12pm"
|
|
128
|
+
#
|
|
129
|
+
# Returns String of the formatted date and time.
|
|
130
|
+
def display_datetime(datetime)
|
|
131
|
+
format_date(datetime, format: :full_date, time: true)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Public: Display a boolean attribute as a sweet icon.
|
|
135
|
+
#
|
|
136
|
+
# boolean - (boolean) true or false
|
|
137
|
+
#
|
|
138
|
+
# Examples
|
|
139
|
+
#
|
|
140
|
+
# display_boolean(true)
|
|
141
|
+
# # => <span class="badge badge-important">
|
|
142
|
+
# # => <i class="icon-white icon-ok"></i>
|
|
143
|
+
# # => </span>
|
|
144
|
+
#
|
|
145
|
+
# Returns String of the appropriate icon.
|
|
146
|
+
def display_boolean(boolean)
|
|
147
|
+
content_tag(:span,
|
|
148
|
+
content_tag(:i, "", class: boolean_bootstrap_map[!!boolean][:icon]),
|
|
149
|
+
class: boolean_bootstrap_map[!!boolean][:badge])
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Private: Map for booleans to Bootstrap classes.
|
|
153
|
+
#
|
|
154
|
+
# Returns Hash
|
|
155
|
+
def boolean_bootstrap_map
|
|
156
|
+
{
|
|
157
|
+
true => { icon: "icon-white icon-ok", badge: "badge badge-success"},
|
|
158
|
+
false => { icon: "icon-white icon-remove", badge: "badge badge-important"}
|
|
159
|
+
}
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Public: Maps the passed-in sort mode (asc, desc) to the appropriate
|
|
163
|
+
# Bootstrap Glyphicons (icon-arrow-up, icon-arrow-down respectively)
|
|
164
|
+
#
|
|
165
|
+
# sort_mode - (String) The sort mode ("asc", "desc").
|
|
166
|
+
#
|
|
167
|
+
# Examples
|
|
168
|
+
#
|
|
169
|
+
# <i class="<%= sort_mode_icon('asc') %>">
|
|
170
|
+
# # => <i class="icon-arrow-up">
|
|
171
|
+
#
|
|
172
|
+
# Returns String of the icon class.
|
|
173
|
+
def sort_mode_icon(sort_mode)
|
|
174
|
+
case sort_mode
|
|
175
|
+
when "desc" then "icon-arrow-down"
|
|
176
|
+
when "asc" then "icon-arrow-up"
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Public: Which sort mode to switch to. Useful for creating links to
|
|
181
|
+
# switch the sort mode or change the list order.
|
|
182
|
+
#
|
|
183
|
+
# column - (Outpost::Column) The column on which the sort
|
|
184
|
+
# will be performed.
|
|
185
|
+
# current_order - (String) The attribute that is currently being
|
|
186
|
+
# ordered.
|
|
187
|
+
# current_sort_mode - (String) The current sort mode ("asc", "desc").
|
|
188
|
+
#
|
|
189
|
+
# Examples
|
|
190
|
+
#
|
|
191
|
+
# <%= link_to column.header, request.parameters.merge({
|
|
192
|
+
# :sort_mode => switch_sort_mode(
|
|
193
|
+
# column, current_order, current_sort_mode
|
|
194
|
+
# )
|
|
195
|
+
# }) %>
|
|
196
|
+
#
|
|
197
|
+
# Returns String of the sort mode, "asc" or "desc"
|
|
198
|
+
def switch_sort_mode(column, current_order, current_sort_mode)
|
|
199
|
+
if column.attribute == current_order
|
|
200
|
+
case current_sort_mode
|
|
201
|
+
when "asc" then "desc"
|
|
202
|
+
when "desc" then "asc"
|
|
203
|
+
else column.default_sort_mode
|
|
204
|
+
end
|
|
205
|
+
else
|
|
206
|
+
column.default_sort_mode
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Public: Generate a CSS class for the column. If the column represents
|
|
211
|
+
# an association, the class will be "column-association".
|
|
212
|
+
#
|
|
213
|
+
# model - (Class) The ActiveRecord model.
|
|
214
|
+
# attribute - (String) The attribute for this column.
|
|
215
|
+
#
|
|
216
|
+
# Examples
|
|
217
|
+
#
|
|
218
|
+
# <tr class="<%= column_type_class(BlogEntry, 'created_at') %>">
|
|
219
|
+
# # => <tr class="column-datetime">
|
|
220
|
+
#
|
|
221
|
+
# Returns String to be used as a CSS class.
|
|
222
|
+
def column_type_class(model, attribute)
|
|
223
|
+
if column = model.columns_hash[attribute]
|
|
224
|
+
"column-#{column.type}"
|
|
225
|
+
else
|
|
226
|
+
"column-association"
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Public: Generate a CSS class for this attribute
|
|
231
|
+
#
|
|
232
|
+
# attribute - (String) The attribute.
|
|
233
|
+
#
|
|
234
|
+
# Examples
|
|
235
|
+
#
|
|
236
|
+
# <td class="<%= column_attribute_class('created_at') %>">
|
|
237
|
+
# # => <td class="column-created_at">
|
|
238
|
+
#
|
|
239
|
+
# Returns String to be used as a CSS class.
|
|
240
|
+
def column_attribute_class(attribute)
|
|
241
|
+
"column-#{attribute}".parameterize
|
|
242
|
+
end
|
|
243
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module OutpostHelper
|
|
2
|
+
# Public: Maps the standard Rails flash keys (+notice+, +alert+) to the
|
|
3
|
+
# appropriate Bootstrap alert class (+success+, +error+ respectively).
|
|
4
|
+
# Falls back to just returning the passed-in symbol as a string.
|
|
5
|
+
#
|
|
6
|
+
# name - The flash key as a Symbol.
|
|
7
|
+
#
|
|
8
|
+
# Examples
|
|
9
|
+
#
|
|
10
|
+
# <div class="alert alert-<%= flash_alert_type(:notice) %>">
|
|
11
|
+
# # => <div class="alert alert-success">
|
|
12
|
+
#
|
|
13
|
+
# Returns String of appropriate CSS class for Bootstrap alerts.
|
|
14
|
+
def flash_alert_type(name)
|
|
15
|
+
name_bootstrap_map = {
|
|
16
|
+
notice: "success",
|
|
17
|
+
alert: "error"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
name_bootstrap_map[name.to_sym] || name.to_s
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def render_flash_messages
|
|
24
|
+
if flash.present?
|
|
25
|
+
render '/outpost/shared/flash_messages', flash: flash
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def render_breadcrumbs
|
|
30
|
+
if breadcrumbs.present?
|
|
31
|
+
render '/outpost/shared/breadcrumbs', breadcrumbs: breadcrumbs
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def render_navigation
|
|
36
|
+
render '/outpost/shared/navigation', current_user: current_user
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Public: Place a modal anywhere with a button to toggle it.
|
|
40
|
+
#
|
|
41
|
+
# options - (Hash) Options to pass into the modal template. Useful for
|
|
42
|
+
# CSS ID, and modal title.
|
|
43
|
+
# block - The block that gets captured and rendered inside of the modal.
|
|
44
|
+
#
|
|
45
|
+
# Returns String of rendered modal and toggle button.
|
|
46
|
+
def modal_toggle(options={}, &block)
|
|
47
|
+
render "/outpost/shared/modal", options: options, body: capture(&block)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module RenderHelper
|
|
2
|
+
# Public: Render the table wrapper.
|
|
3
|
+
#
|
|
4
|
+
# records - (Array) Records that are being represented in the table.
|
|
5
|
+
# model - (Class) The ActiveRecord model for this table.
|
|
6
|
+
# block - The rendered table. Should return a String.
|
|
7
|
+
#
|
|
8
|
+
# Examples
|
|
9
|
+
#
|
|
10
|
+
# <%= list_table @posts, Post do %>
|
|
11
|
+
# <table>...</table>
|
|
12
|
+
# <% end %>
|
|
13
|
+
#
|
|
14
|
+
# Returns a String of the table, or a message if no records are present.
|
|
15
|
+
def list_table(records, model, &block)
|
|
16
|
+
render '/outpost/shared/list_table',
|
|
17
|
+
:model => model,
|
|
18
|
+
:records => records,
|
|
19
|
+
:table => capture(&block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Public: Render a fieldset.
|
|
23
|
+
#
|
|
24
|
+
# title - (String) The title of this fieldset. If +nil+ is passed
|
|
25
|
+
# in, then no legend will be rendered, and the fieldset block
|
|
26
|
+
# will not be added to the sidebar sections.
|
|
27
|
+
# block - The body of the fieldset. Should return a String.
|
|
28
|
+
#
|
|
29
|
+
# Examples
|
|
30
|
+
#
|
|
31
|
+
# <%= form_block "Publishing" do %>
|
|
32
|
+
# <input type="text">...
|
|
33
|
+
# <% end %>
|
|
34
|
+
#
|
|
35
|
+
# Returns a String of the fieldset.
|
|
36
|
+
def form_block(title="", &block)
|
|
37
|
+
render "/outpost/shared/form_block",
|
|
38
|
+
:title => title,
|
|
39
|
+
:body => capture(&block)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
module UtilityHelper
|
|
2
|
+
# Public: Format a DateTime by keyword.
|
|
3
|
+
#
|
|
4
|
+
# date - (DateTime) The date to format.
|
|
5
|
+
# options - (Hash) A hash of options (default: {}):
|
|
6
|
+
# :with - (String) The custom strftime string to use to
|
|
7
|
+
# format the date.
|
|
8
|
+
# :format - (String) The format to use. Options are:
|
|
9
|
+
# * "iso" (2012-10-11)
|
|
10
|
+
# * "full_date" (October 11th, 2011)
|
|
11
|
+
# * "event" (Wednesday, October 11)
|
|
12
|
+
# * "short_date" (Oct 11, 2011)
|
|
13
|
+
# :time - (Boolean) Whether or not to show the time.
|
|
14
|
+
#
|
|
15
|
+
# Examples
|
|
16
|
+
#
|
|
17
|
+
# format_date(Time.now, format: "iso", time: true)
|
|
18
|
+
# # => "2013-03-13, 1:10pm"
|
|
19
|
+
#
|
|
20
|
+
# format_date(Time.now, with: "%D")
|
|
21
|
+
# # => "03/13/13"
|
|
22
|
+
#
|
|
23
|
+
# format_date(Time.now)
|
|
24
|
+
# # => "Mar 13, 2013"
|
|
25
|
+
#
|
|
26
|
+
# Returns String of the formatted date
|
|
27
|
+
def format_date(date, options={})
|
|
28
|
+
return nil if !date.respond_to?(:strftime)
|
|
29
|
+
|
|
30
|
+
format_str = options[:with] if options[:with].present?
|
|
31
|
+
|
|
32
|
+
format_str ||= case options[:format].to_s
|
|
33
|
+
when "iso" then "%F"
|
|
34
|
+
when "full_date" then "%B #{date.day.ordinalize}, %Y"
|
|
35
|
+
when "event" then "%A, %B %-d"
|
|
36
|
+
else "%b %-d, %Y"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
format_str += ", %l:%M%P" if options[:time] == true
|
|
40
|
+
|
|
41
|
+
date.strftime(format_str)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Public: Render a block of content or fallback to a message.
|
|
45
|
+
#
|
|
46
|
+
# records - (Array) The list of records to check.
|
|
47
|
+
# options - (Hash) A hash of options (default: {}):
|
|
48
|
+
# :message - (String) The fallback message to display.
|
|
49
|
+
# :title - (String) The title of the collection.
|
|
50
|
+
# block - The block to capture if the collection is present.
|
|
51
|
+
#
|
|
52
|
+
# Examples
|
|
53
|
+
#
|
|
54
|
+
# records = []
|
|
55
|
+
# any_to_list? records, message: "Empty!" do
|
|
56
|
+
# "Hidden"
|
|
57
|
+
# end
|
|
58
|
+
# # => "Empty!"
|
|
59
|
+
#
|
|
60
|
+
# records = [1, 2, 3]
|
|
61
|
+
# any_to_list? records, message: "Empty!" do
|
|
62
|
+
# "Numbers!"
|
|
63
|
+
# end
|
|
64
|
+
# # => "Numbers!"
|
|
65
|
+
#
|
|
66
|
+
# Returns String of the captured block.
|
|
67
|
+
def any_to_list?(records, options={}, &block)
|
|
68
|
+
if records.present?
|
|
69
|
+
return capture(&block)
|
|
70
|
+
else
|
|
71
|
+
if options[:message].blank?
|
|
72
|
+
if options[:title].present?
|
|
73
|
+
options[:message] = "There are currently no #{options[:title]}"
|
|
74
|
+
else
|
|
75
|
+
options[:message] = "There is nothing here to list."
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
return options[:message].html_safe
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Public: Set the first part of the page title.
|
|
84
|
+
#
|
|
85
|
+
# elements - Zero or more strings to prepend onto the page title.
|
|
86
|
+
# The final argument can optionally be hash:
|
|
87
|
+
# :separator - (String) The separator to use between
|
|
88
|
+
# elements (default: " | ").
|
|
89
|
+
#
|
|
90
|
+
# Examples
|
|
91
|
+
#
|
|
92
|
+
# set_page_title "Events", "Forum", separator: " :: "
|
|
93
|
+
# # => "Events :: Forum"
|
|
94
|
+
#
|
|
95
|
+
# Returns String of the first element, meant to allow you to use this
|
|
96
|
+
# method to add to the page title and display a header at the same time.
|
|
97
|
+
def add_to_page_title(*elements)
|
|
98
|
+
@TITLE_ELEMENTS ||= []
|
|
99
|
+
@TITLE_ELEMENTS += elements
|
|
100
|
+
elements.first
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Public: Generate the full page title.
|
|
104
|
+
#
|
|
105
|
+
# last_element - (String) The string that will be appendended onto the
|
|
106
|
+
# rest of the title.
|
|
107
|
+
# separator - (String) The separator to use between the title and the last
|
|
108
|
+
# element (default: " | ").
|
|
109
|
+
#
|
|
110
|
+
# Examples
|
|
111
|
+
#
|
|
112
|
+
# content_for(:page_title) # => "Home"
|
|
113
|
+
# page_title("KPCC", "::")
|
|
114
|
+
# # => "Home :: KPCC"
|
|
115
|
+
#
|
|
116
|
+
# Returns String of the full title.
|
|
117
|
+
def page_title(separator=" | ")
|
|
118
|
+
@TITLE_ELEMENTS.compact.join(separator).html_safe
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Public: Render pure json from a partial.
|
|
122
|
+
# This helper is intended to be used to render jbuilder templates.
|
|
123
|
+
|
|
124
|
+
# path - (String) The path to the json partial.
|
|
125
|
+
# location - (Hash) A hash of locals to pass directly to the partial
|
|
126
|
+
# (default: {}).
|
|
127
|
+
#
|
|
128
|
+
# Examples
|
|
129
|
+
#
|
|
130
|
+
# render_json('api/private/v1/posts/collection', posts: @posts)
|
|
131
|
+
#
|
|
132
|
+
# Returns String of a JSON object.
|
|
133
|
+
def render_json(path, locals={})
|
|
134
|
+
raw(j(render(partial: path, formats: [:json], locals: locals)))
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
##
|
|
2
|
+
# DateTimeInput
|
|
3
|
+
#
|
|
4
|
+
# Just renders a normal text field instead of trying to
|
|
5
|
+
# be a date selector. The date_time_input javascript will
|
|
6
|
+
# take care of filling it in.
|
|
7
|
+
#
|
|
8
|
+
class DateTimeInput < SimpleForm::Inputs::Base
|
|
9
|
+
def input
|
|
10
|
+
@builder.text_field(attribute_name, input_html_options)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class Permission < ActiveRecord::Base
|
|
2
|
+
outpost_model
|
|
3
|
+
|
|
4
|
+
#-------------------
|
|
5
|
+
# Association
|
|
6
|
+
has_many :user_permissions
|
|
7
|
+
has_many :users, class_name: Outpost.config.user_class, through: :user_permissions, dependent: :destroy
|
|
8
|
+
|
|
9
|
+
#-------------------
|
|
10
|
+
# Validation
|
|
11
|
+
validates :resource, uniqueness: true
|
|
12
|
+
|
|
13
|
+
#-------------------
|
|
14
|
+
|
|
15
|
+
def title
|
|
16
|
+
self.resource.titleize
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<%= paginator.render do -%>
|
|
2
|
+
<div class="pagination">
|
|
3
|
+
<ul>
|
|
4
|
+
<%= first_page_tag unless current_page.first? %>
|
|
5
|
+
<%= prev_page_tag unless current_page.first? %>
|
|
6
|
+
<% each_page do |page| -%>
|
|
7
|
+
<% if page.left_outer? || page.right_outer? || page.inside_window? -%>
|
|
8
|
+
<%= page_tag page %>
|
|
9
|
+
<% elsif !page.was_truncated? -%>
|
|
10
|
+
<%= gap_tag %>
|
|
11
|
+
<% end -%>
|
|
12
|
+
<% end -%>
|
|
13
|
+
<%= next_page_tag unless current_page.last? %>
|
|
14
|
+
<%= last_page_tag unless current_page.last? %>
|
|
15
|
+
</ul>
|
|
16
|
+
</div>
|
|
17
|
+
<% end -%>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<% add_to_page_title "Outpost" %>
|
|
5
|
+
<title><%= page_title %></title>
|
|
6
|
+
<%= stylesheet_link_tag "outpost/application" %>
|
|
7
|
+
<%= javascript_include_tag "outpost/application" %>
|
|
8
|
+
|
|
9
|
+
<link rel="shortcut icon" href="/favicon.ico" />
|
|
10
|
+
<%= csrf_meta_tags %>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
|
|
14
|
+
<div class="navbar navbar-fixed-top navbar-inverse">
|
|
15
|
+
<div class="navbar-inner">
|
|
16
|
+
<div class="container">
|
|
17
|
+
<a href="<%=outpost_root_path%>" class="brand">Outpost</a>
|
|
18
|
+
|
|
19
|
+
<% if current_user %>
|
|
20
|
+
<ul class="nav">
|
|
21
|
+
|
|
22
|
+
<!-- Full Navigation -->
|
|
23
|
+
<li class="dropdown">
|
|
24
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-align-justify icon-white"></i> Navigation <b class="caret"></b></a>
|
|
25
|
+
<% models = current_user.allowed_resources.sort_by(&:name) %>
|
|
26
|
+
<% per_col = 20 %>
|
|
27
|
+
<% cols = (models.size.to_f / per_col.to_f).ceil %>
|
|
28
|
+
|
|
29
|
+
<ul class="dropdown-menu cms-nav" style="width:<%= cols * 400 + cols * 10 %>px">
|
|
30
|
+
<% models.each_with_index do |model, index| %>
|
|
31
|
+
<% if index % per_col == 0 %>
|
|
32
|
+
<div class="grouper">
|
|
33
|
+
<% end %>
|
|
34
|
+
|
|
35
|
+
<li>
|
|
36
|
+
<a href="<%=model.admin_index_path%>">
|
|
37
|
+
<%= model.name.titleize.pluralize %>
|
|
38
|
+
</a>
|
|
39
|
+
|
|
40
|
+
<div class="btn-links">
|
|
41
|
+
<% if model.respond_to?(:admin_new_path) %>
|
|
42
|
+
<a class="add btn btn-mini" href="<%=model.admin_new_path%>"><i class="icon-plus-sign"></i> Add</a>
|
|
43
|
+
<% end %>
|
|
44
|
+
</div>
|
|
45
|
+
</li>
|
|
46
|
+
|
|
47
|
+
<% if index % per_col == per_col - 1 or model == models.last %>
|
|
48
|
+
</div>
|
|
49
|
+
<% end %>
|
|
50
|
+
|
|
51
|
+
<% end %>
|
|
52
|
+
</ul> <!-- dropdown-menu -->
|
|
53
|
+
</li> <!-- dropdown -->
|
|
54
|
+
</ul> <!-- nav -->
|
|
55
|
+
|
|
56
|
+
<ul class="nav pull-right">
|
|
57
|
+
<li class="dropdown">
|
|
58
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class='icon-user icon-white'></i> <%= current_user.name %> <b class="caret"></b></a>
|
|
59
|
+
<ul class="dropdown-menu">
|
|
60
|
+
<li><%= link_to "Logout", outpost_logout_path, id: "logout" %></li>
|
|
61
|
+
</ul>
|
|
62
|
+
</li>
|
|
63
|
+
</ul>
|
|
64
|
+
<% else %>
|
|
65
|
+
<ul class="nav pull-right">
|
|
66
|
+
<li><%= link_to "Login", outpost_login_path %></li>
|
|
67
|
+
</ul>
|
|
68
|
+
<% end %>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<% if current_user %>
|
|
74
|
+
<div class="navbar navbar-fixed-top fixed-breadcrumbs">
|
|
75
|
+
<% if breadcrumbs.present? %>
|
|
76
|
+
<div class="breadcrumb unstyled">
|
|
77
|
+
<div class="container">
|
|
78
|
+
<%= render_breadcrumbs %>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
<% end %>
|
|
82
|
+
</div> <!-- navbar -->
|
|
83
|
+
<% end %>
|
|
84
|
+
|
|
85
|
+
<div id="main" class="container">
|
|
86
|
+
<div class="row">
|
|
87
|
+
<div class="span<%= content_for?(:sidebar) ? "9" : "12" %>">
|
|
88
|
+
<%= render_flash_messages %>
|
|
89
|
+
<%= yield %>
|
|
90
|
+
</div>
|
|
91
|
+
<% if content_for?(:sidebar) %>
|
|
92
|
+
<div class="span3" id="admin-sidebar">
|
|
93
|
+
<%= yield :sidebar %>
|
|
94
|
+
</div>
|
|
95
|
+
<% end %>
|
|
96
|
+
</div> <!-- row -->
|
|
97
|
+
</div> <!-- container main -->
|
|
98
|
+
|
|
99
|
+
<%= yield :footer %>
|
|
100
|
+
</body>
|
|
101
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<% add_to_page_title "Outpost" %>
|
|
5
|
+
<title><%= page_title %></title>
|
|
6
|
+
<%= stylesheet_link_tag "outpost/application" %>
|
|
7
|
+
<%= javascript_include_tag "outpost/application" %>
|
|
8
|
+
|
|
9
|
+
<%= csrf_meta_tags %>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
|
|
13
|
+
<div class="navbar navbar-fixed-top navbar-inverse">
|
|
14
|
+
<div class="navbar-inner">
|
|
15
|
+
<div class="container-fluid">
|
|
16
|
+
<a href="<%=outpost_root_path%>" class="brand">Outpost</a>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div id="main" class="container-fluid">
|
|
22
|
+
<%= yield %>
|
|
23
|
+
</div> <!-- container main -->
|
|
24
|
+
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<h3>Not Found.</h3>
|