simple_admin 0.1.0
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/.rspec +2 -0
- data/Gemfile +12 -0
- data/README.rdoc +318 -0
- data/Rakefile +67 -0
- data/TODO.rdoc +4 -0
- data/app/assets/images/simple_admin/active_admin/admin_notes_icon.png +0 -0
- data/app/assets/images/simple_admin/active_admin/loading.gif +0 -0
- data/app/assets/images/simple_admin/active_admin/nested_menu_arrow.gif +0 -0
- data/app/assets/images/simple_admin/active_admin/nested_menu_arrow_dark.gif +0 -0
- data/app/assets/images/simple_admin/active_admin/orderable.png +0 -0
- data/app/assets/javascripts/simple_admin/active_admin.js +434 -0
- data/app/assets/stylesheets/simple_admin/active_admin.css +1445 -0
- data/app/controllers/simple_admin/admin_controller.rb +117 -0
- data/app/helpers/simple_admin/admin_helper.rb +11 -0
- data/app/helpers/simple_admin/display_helper.rb +38 -0
- data/app/helpers/simple_admin/filter_helper.rb +147 -0
- data/app/helpers/simple_admin/header_helper.rb +60 -0
- data/app/helpers/simple_admin/path_helper.rb +12 -0
- data/app/helpers/simple_admin/sidebar_helper.rb +9 -0
- data/app/helpers/simple_admin/table_helper.rb +39 -0
- data/app/helpers/simple_admin/title_helper.rb +35 -0
- data/app/views/layouts/simple_admin.html.erb +41 -0
- data/app/views/simple_admin/admin/_form.html.erb +16 -0
- data/app/views/simple_admin/admin/edit.html.erb +7 -0
- data/app/views/simple_admin/admin/index.csv.erb +19 -0
- data/app/views/simple_admin/admin/index.html.erb +82 -0
- data/app/views/simple_admin/admin/new.html.erb +7 -0
- data/app/views/simple_admin/admin/show.html.erb +22 -0
- data/config/routes.rb +8 -0
- data/lib/rails/generators/simple_admin/simple_admin_generator.rb +33 -0
- data/lib/rails/generators/simple_admin/templates/initializer.rb +76 -0
- data/lib/simple_admin.rb +100 -0
- data/lib/simple_admin/attributes.rb +80 -0
- data/lib/simple_admin/breadcrumbs.rb +24 -0
- data/lib/simple_admin/builder.rb +35 -0
- data/lib/simple_admin/engine.rb +8 -0
- data/lib/simple_admin/filters.rb +5 -0
- data/lib/simple_admin/interface.rb +55 -0
- data/lib/simple_admin/section.rb +30 -0
- data/lib/simple_admin/version.rb +3 -0
- data/rails/init.rb +2 -0
- data/simple_admin.gemspec +34 -0
- data/spec/acceptance/admin_thing_spec.rb +13 -0
- data/spec/controllers/simple_admin/admin_controller_spec.rb +95 -0
- data/spec/factories.rb +14 -0
- data/spec/simple_admin/attributes_spec.rb +106 -0
- data/spec/simple_admin/breadcrumbs_spec.rb +18 -0
- data/spec/simple_admin/builder_spec.rb +57 -0
- data/spec/simple_admin/engine_spec.rb +9 -0
- data/spec/simple_admin/filters_spec.rb +16 -0
- data/spec/simple_admin/interface_spec.rb +98 -0
- data/spec/simple_admin/section_spec.rb +63 -0
- data/spec/simple_admin/simple_admin_spec.rb +68 -0
- data/spec/spec_helper.rb +32 -0
- metadata +285 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'kaminari'
|
2
|
+
require 'meta_search'
|
3
|
+
|
4
|
+
module SimpleAdmin
|
5
|
+
class AdminController < ::ApplicationController
|
6
|
+
before_filter :require_user
|
7
|
+
before_filter :lookup_interface
|
8
|
+
before_filter :lookup_resource, :only => [:show, :edit, :update, :destroy]
|
9
|
+
before_filter :handle_before
|
10
|
+
|
11
|
+
unloadable
|
12
|
+
|
13
|
+
respond_to :csv, :json, :xml, :html
|
14
|
+
|
15
|
+
helper SimpleAdmin::AdminHelper
|
16
|
+
|
17
|
+
layout 'simple_admin'
|
18
|
+
|
19
|
+
def index
|
20
|
+
@collection = @interface.constant
|
21
|
+
@collection = @collection.order("#{@interface.constant.table_name}.#{$1} #{$2}") if params[:order] && params[:order] =~ /^([\w\_\.]+)_(desc|asc)$/
|
22
|
+
@collection = @collection.metasearch(clean_search_params(params))
|
23
|
+
@collection = @collection.page(params[:page]).per(@per_page || SimpleAdmin.default_per_page) if params[:format].blank? || params[:format] == 'html'
|
24
|
+
respond_with(@collection)
|
25
|
+
end
|
26
|
+
|
27
|
+
def show
|
28
|
+
@resource = @interface.constant.find(params[:id])
|
29
|
+
respond_with(@resource)
|
30
|
+
end
|
31
|
+
|
32
|
+
def new
|
33
|
+
@resource = @interface.constant.new
|
34
|
+
respond_with(@resource)
|
35
|
+
end
|
36
|
+
|
37
|
+
def edit
|
38
|
+
respond_with(@resource)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create
|
42
|
+
@resource = @interface.constant.new(params[@interface.member.to_sym])
|
43
|
+
# respond_with will fail without explicit urls
|
44
|
+
respond_to do |format|
|
45
|
+
if @resource.save
|
46
|
+
format.html { redirect_to send("simple_admin_#{@interface.member}_path", @resource), :notice => "#{@interface.member.titleize} was successfully created." }
|
47
|
+
format.json { render :json => @resource, :status => :created, :location => send("simple_admin_#{@interface.member}_path", @resource) }
|
48
|
+
format.xml { render :xml => @resource, :status => :created, :location => send("simple_admin_#{@interface.member}_path", @resource) }
|
49
|
+
else
|
50
|
+
format.html { render :action => "new" }
|
51
|
+
format.json { render :json => @resource.errors, :status => :unprocessable_entity }
|
52
|
+
format.xml { render :xml => @resource.errors, :status => :unprocessable_entity }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def update
|
58
|
+
# respond_with will fail without explicit urls
|
59
|
+
respond_to do |format|
|
60
|
+
if @resource.update_attributes(params[@interface.member.to_sym])
|
61
|
+
format.html { redirect_to send("simple_admin_#{@interface.member}_path", @resource), :notice => "#{@interface.member.titleize} was successfully updated." }
|
62
|
+
format.json { head :ok }
|
63
|
+
format.xml { head :ok }
|
64
|
+
else
|
65
|
+
format.html { render :action => "edit" }
|
66
|
+
format.json { render :json => @resource.errors, :status => :unprocessable_entity }
|
67
|
+
format.xml { render :xml => @resource.errors, :status => :unprocessable_entity }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def destroy
|
73
|
+
@resource.destroy
|
74
|
+
# respond_with will fail without explicit urls
|
75
|
+
respond_to do |format|
|
76
|
+
format.html { redirect_to send("simple_admin_#{@interface.collection}_path") }
|
77
|
+
format.json { head :ok }
|
78
|
+
format.xml { head :ok }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
def require_user
|
85
|
+
send(SimpleAdmin.require_user_method) if SimpleAdmin.require_user_method
|
86
|
+
end
|
87
|
+
|
88
|
+
def lookup_interface
|
89
|
+
SimpleAdmin.registered.each do |interface|
|
90
|
+
@interface = interface if interface.collection == params[:interface]
|
91
|
+
end
|
92
|
+
# This should not be reached, routing should catch errors before this point
|
93
|
+
raise UnknownAdminInterface.new("Could not find the interface for simple admin") unless @interface
|
94
|
+
end
|
95
|
+
|
96
|
+
def lookup_resource
|
97
|
+
@resource = @interface.constant.find(params[:id])
|
98
|
+
end
|
99
|
+
|
100
|
+
def handle_before
|
101
|
+
@interface.before.each do |before|
|
102
|
+
next unless before[:actions].include?(params[:action].to_sym)
|
103
|
+
instance_eval(&before[:data])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def clean_search_params(search_params)
|
108
|
+
return {} unless search_params.is_a?(Hash)
|
109
|
+
search_params = search_params.dup
|
110
|
+
search_params.delete_if do |key, value|
|
111
|
+
value == "" ||
|
112
|
+
["utf8", "scope", "commit", "action", "order", "interface", "controller", "format"].include?(key)
|
113
|
+
end
|
114
|
+
search_params
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module SimpleAdmin
|
2
|
+
module AdminHelper
|
3
|
+
include SimpleAdmin::TitleHelper
|
4
|
+
include SimpleAdmin::HeaderHelper
|
5
|
+
include SimpleAdmin::TableHelper
|
6
|
+
include SimpleAdmin::DisplayHelper
|
7
|
+
include SimpleAdmin::FilterHelper
|
8
|
+
include SimpleAdmin::SidebarHelper
|
9
|
+
include SimpleAdmin::PathHelper
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SimpleAdmin
|
2
|
+
module DisplayHelper
|
3
|
+
|
4
|
+
# Return a pretty string for any object
|
5
|
+
# Date Time are formatted via #localize with :format => :long
|
6
|
+
# ActiveRecord objects are formatted via #auto_link
|
7
|
+
# We attempt to #display_name of any other objects
|
8
|
+
def pretty_format(object)
|
9
|
+
case object
|
10
|
+
when String
|
11
|
+
object
|
12
|
+
when Date, Time
|
13
|
+
localize(object, :format => :long)
|
14
|
+
else
|
15
|
+
(object.respond_to?(:display_name) && object.send(:display_name)) ||
|
16
|
+
(object.respond_to?(:full_name) && object.send(:full_name)) ||
|
17
|
+
(object.respond_to?(:name) && object.send(:name)) ||
|
18
|
+
(object.respond_to?(:username) && object.send(:username)) ||
|
19
|
+
(object.respond_to?(:login) && object.send(:login)) ||
|
20
|
+
(object.respond_to?(:title) && object.send(:title)) ||
|
21
|
+
(object.respond_to?(:email) && object.send(:email)) ||
|
22
|
+
(object.respond_to?(:to_s) && object.send(:to_s)) ||
|
23
|
+
"#{object}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def data_for(col)
|
28
|
+
value = if col.data
|
29
|
+
col.data.call(@resource, col)
|
30
|
+
elsif col.attribute.to_s =~ /^([\w]+)_id$/ && @resource.respond_to?($1.to_sym)
|
31
|
+
pretty_format(@resource.send($1))
|
32
|
+
else
|
33
|
+
pretty_format(@resource.send(col.attribute))
|
34
|
+
end
|
35
|
+
value ||= content_tag(:span, 'Empty', :class => 'empty')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module SimpleAdmin
|
2
|
+
module FilterHelper
|
3
|
+
def filter_for(method, klass, options={})
|
4
|
+
options ||= {}
|
5
|
+
options[:as] ||= default_filter_type(klass, method)
|
6
|
+
return "" unless options[:as]
|
7
|
+
field_type = options.delete(:as)
|
8
|
+
content_tag :div, :class => "filter_form_field filter_#{field_type}" do
|
9
|
+
send("filter_#{field_type}_input", klass, method, options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def filter_string_input(klass, method, options = {})
|
14
|
+
field_name = "#{method}_contains"
|
15
|
+
|
16
|
+
[ label(field_name, "Search #{method.to_s.titlecase}"),
|
17
|
+
text_field_tag(field_name, params[field_name] || '')
|
18
|
+
].join("\n").html_safe
|
19
|
+
end
|
20
|
+
|
21
|
+
def filter_date_range_input(klass, method, options = {})
|
22
|
+
gt_field_name = "#{method}_gte"
|
23
|
+
lt_field_name = "#{method}_lte"
|
24
|
+
|
25
|
+
[ label(gt_field_name, method.to_s.titlecase),
|
26
|
+
filter_date_text_field(klass, gt_field_name),
|
27
|
+
" - ",
|
28
|
+
filter_date_text_field(klass, lt_field_name)
|
29
|
+
].join("\n").html_safe
|
30
|
+
end
|
31
|
+
|
32
|
+
def filter_date_text_field(klass, method)
|
33
|
+
current_value = params[method] || ''
|
34
|
+
text_field_tag(method, current_value.respond_to?(:strftime) ? current_value.strftime("%Y-%m-%d") : current_value, :size => 12, :class => "datepicker", :max => 10)
|
35
|
+
end
|
36
|
+
|
37
|
+
def filter_numeric_input(klass, method, options = {})
|
38
|
+
filters = numeric_filters_for_method(method, options.delete(:filters) || default_numeric_filters)
|
39
|
+
current_filter = current_numeric_scope(klass, filters)
|
40
|
+
filter_select = select_tag '', options_for_select(filters, current_filter), :onchange => "document.getElementById('#{method}_numeric').name = '' + this.value + '';"
|
41
|
+
filter_input = text_field_tag(current_filter, params[current_filter] || '', :size => 10, :id => "#{method}_numeric")
|
42
|
+
|
43
|
+
[ label_tag(method), filter_select, " ", filter_input].join("\n").html_safe
|
44
|
+
end
|
45
|
+
|
46
|
+
def numeric_filters_for_method(method, filters)
|
47
|
+
filters.collect{|scope| [scope[0], [method,scope[1]].join("_") ] }
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the scope for which we are currently searching. If no search is available
|
51
|
+
# it returns the first scope
|
52
|
+
def current_numeric_scope(klass, filters)
|
53
|
+
filters[1..-1].inject(filters.first){|a,b| params[b[1].to_sym] ? b : a }[1]
|
54
|
+
end
|
55
|
+
|
56
|
+
def default_numeric_filters
|
57
|
+
[['Equal To', 'eq'], ['Greater Than', 'gt'], ['Less Than', 'lt']]
|
58
|
+
end
|
59
|
+
|
60
|
+
def filter_select_input(klass, method, options = {})
|
61
|
+
association_name = method.to_s.gsub(/_id$/, '').to_sym
|
62
|
+
input_name = if reflection = reflection_for(klass, association_name)
|
63
|
+
if [:has_and_belongs_to_many, :has_many].include?(reflection.macro)
|
64
|
+
"#{association_name.to_s.singularize}_ids"
|
65
|
+
else
|
66
|
+
reflection.options[:foreign_key] || "#{association_name}_id"
|
67
|
+
end
|
68
|
+
else
|
69
|
+
association_name
|
70
|
+
end
|
71
|
+
input_name = (input_name + "_eq").to_sym
|
72
|
+
collection = find_collection_for_column(klass, association_name, options)
|
73
|
+
[ label(input_name, method.to_s.titlecase),
|
74
|
+
select_tag(input_name, options_for_select(collection, params[input_name]), :include_blank => options[:include_blank] || 'Any')
|
75
|
+
].join("\n").html_safe
|
76
|
+
end
|
77
|
+
|
78
|
+
def find_collection_for_column(klass, column, options) #:nodoc:
|
79
|
+
collection = if options[:collection]
|
80
|
+
options.delete(:collection)
|
81
|
+
elsif reflection = reflection_for(klass, column)
|
82
|
+
options[:find_options] ||= {}
|
83
|
+
if conditions = reflection.options[:conditions]
|
84
|
+
options[:find_options][:conditions] = reflection.klass.merge_conditions(conditions, options[:find_options][:conditions])
|
85
|
+
end
|
86
|
+
reflection.klass.find(:all, options[:find_options])
|
87
|
+
else
|
88
|
+
boolean_collection(klass, column, options)
|
89
|
+
end
|
90
|
+
collection = collection.to_a if collection.is_a?(Hash)
|
91
|
+
collection.map { |o| [pretty_format(o), o.id] }
|
92
|
+
end
|
93
|
+
|
94
|
+
def boolean_collection(klass, column, options)
|
95
|
+
[['Yes', true], ['No', false]]
|
96
|
+
end
|
97
|
+
|
98
|
+
def filter_check_boxes_input(klass, method, options = {})
|
99
|
+
input_name = (generate_association_input_name(method).to_s + "_in").to_sym
|
100
|
+
collection = find_collection_for_column(method, options)
|
101
|
+
selected_values = klass.send(input_name) || []
|
102
|
+
checkboxes = template.content_tag :div, :class => "check_boxes_wrapper" do
|
103
|
+
collection.map do |c|
|
104
|
+
label = c.is_a?(Array) ? c.first : c
|
105
|
+
value = c.is_a?(Array) ? c.last : c
|
106
|
+
"<label><input type=\"checkbox\" name=\"#{input_name}[]\" value=\"#{value}\" #{selected_values.include?(value) ? "checked" : ""}/> #{label}</label>"
|
107
|
+
end.join("\n").html_safe
|
108
|
+
end
|
109
|
+
|
110
|
+
[ label(input_name, method.to_s.titlecase),
|
111
|
+
checkboxes
|
112
|
+
].join("\n").html_safe
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns the default filter type for a given attribute
|
116
|
+
def default_filter_type(klass, method)
|
117
|
+
if column = column_for(klass, method)
|
118
|
+
case column.type
|
119
|
+
when :date, :datetime
|
120
|
+
return :date_range
|
121
|
+
when :string, :text
|
122
|
+
return :string
|
123
|
+
when :integer
|
124
|
+
return :select if reflection_for(klass, method.to_s.gsub('_id','').to_sym)
|
125
|
+
return :numeric
|
126
|
+
when :float, :decimal
|
127
|
+
return :numeric
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
if reflection = reflection_for(klass, method)
|
132
|
+
return :select if reflection.macro == :belongs_to && !reflection.options[:polymorphic]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns the column for an attribute on the object being searched
|
137
|
+
# if it exists. Otherwise returns nil
|
138
|
+
def column_for(klass, method)
|
139
|
+
klass.columns_hash[method.to_s] if klass.respond_to?(:columns_hash)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns the association reflection for the method if it exists
|
143
|
+
def reflection_for(klass, method)
|
144
|
+
klass.reflect_on_association(method) if klass.respond_to?(:reflect_on_association)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module SimpleAdmin
|
2
|
+
module HeaderHelper
|
3
|
+
def tabs
|
4
|
+
content_tag :ul, :id => 'tabs' do
|
5
|
+
SimpleAdmin.registered.collect do |interface|
|
6
|
+
content_tag :li, :id => interface.collection, :class => "#{'current' if @interface == interface}" do
|
7
|
+
link_to interface.collection.titlecase, send("simple_admin_#{interface.collection}_path".to_sym)
|
8
|
+
end
|
9
|
+
end.join.html_safe
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def utility_nav
|
14
|
+
content_tag :p, :id => 'utility_nav' do
|
15
|
+
if SimpleAdmin.current_user_method && send(SimpleAdmin.current_user_method)
|
16
|
+
content = "".html_safe
|
17
|
+
content << content_tag(:span, send(SimpleAdmin.current_user_name_method), :class => "current_user") if SimpleAdmin.current_user_name_method
|
18
|
+
content << link_to("Logout", Rails.application.routes.url_helpers.logout_path) if Rails.application.routes.url_helpers.respond_to?(:logout_path)
|
19
|
+
content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def breadcrumbs
|
25
|
+
content_tag :span, :class => 'breadcrumb' do
|
26
|
+
SimpleAdmin::Breadcrumbs.parse(request.fullpath, params[:action]).collect do |crumb|
|
27
|
+
link_to(crumb.first, crumb.last) +
|
28
|
+
content_tag(:span, ' / ', :class => 'breadcrumb_sep')
|
29
|
+
end.join.html_safe
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def action_items
|
34
|
+
content_tag :div, :class => "action_items" do
|
35
|
+
content = ""
|
36
|
+
# If we are currently showing, then check for edit and destroy action items
|
37
|
+
if params[:action].to_sym == :show
|
38
|
+
if controller.action_methods.include?('edit')
|
39
|
+
content << link_to("Edit #{@interface.member.titlecase}",
|
40
|
+
send("edit_simple_admin_#{@interface.member}_path", @object))
|
41
|
+
end
|
42
|
+
content << " "
|
43
|
+
if controller.action_methods.include?("destroy")
|
44
|
+
content << link_to("Delete #{@interface.member.titlecase}",
|
45
|
+
send("simple_admin_#{@interface.member}_path", @object),
|
46
|
+
:method => :delete, :confirm => "Are you sure you want to delete this?")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# If we are not showing an item or creating a new one, then check for new action items
|
50
|
+
unless [:new, :show].include?(params[:action].to_sym)
|
51
|
+
if controller.action_methods.include?('new')
|
52
|
+
content << link_to("New #{@interface.member.titlecase}",
|
53
|
+
send("new_simple_admin_#{@interface.member}_path"))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
content.html_safe
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module SimpleAdmin
|
2
|
+
module TableHelper
|
3
|
+
def sortable_header_classes_for(col)
|
4
|
+
sort = current_sort
|
5
|
+
classes = []
|
6
|
+
classes << "sortable" if col.sortable
|
7
|
+
classes << "sorted-#{sort[1]}" if sort[0] == col.sort_key
|
8
|
+
classes.join(' ')
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns an array for the current sort order
|
12
|
+
# current_sort[0] #=> sort_key
|
13
|
+
# current_sort[1] #=> asc | desc
|
14
|
+
def current_sort
|
15
|
+
if params[:order] && params[:order] =~ /^([\w\_\.]+)_(desc|asc)$/
|
16
|
+
[$1,$2]
|
17
|
+
else
|
18
|
+
[]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the order to use for a given sort key
|
23
|
+
#
|
24
|
+
# Default is to use 'desc'. If the current sort key is
|
25
|
+
# 'desc' it will return 'asc'
|
26
|
+
def order_for_sort_key(sort_key)
|
27
|
+
current_key, current_order = current_sort
|
28
|
+
return 'desc' unless current_key == sort_key
|
29
|
+
current_order == 'desc' ? 'asc' : 'desc'
|
30
|
+
end
|
31
|
+
|
32
|
+
def resource_actions(object)
|
33
|
+
links = link_to "View", send("simple_admin_#{@interface.member}_path", object), :class => "member_link view_link"
|
34
|
+
links += link_to "Edit", send("edit_simple_admin_#{@interface.member}_path", object), :class => "member_link edit_link"
|
35
|
+
links += link_to "Delete", send("simple_admin_#{@interface.member}_path", object), :method => :delete, :confirm => "Are you sure you want to delete this?", :class => "member_link delete_link"
|
36
|
+
links
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SimpleAdmin
|
2
|
+
module TitleHelper
|
3
|
+
def title
|
4
|
+
"#{page_title} | #{site_title}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def site_title
|
8
|
+
SimpleAdmin::site_title
|
9
|
+
end
|
10
|
+
|
11
|
+
def page_title
|
12
|
+
options = @interface.options_for(params[:action].to_sym)
|
13
|
+
case options[:title]
|
14
|
+
when Proc
|
15
|
+
options[:title].call(@resource)
|
16
|
+
when Symbol
|
17
|
+
if @resource
|
18
|
+
@resource.send(optons[:title])
|
19
|
+
else
|
20
|
+
options[:title].to_s
|
21
|
+
end
|
22
|
+
when String
|
23
|
+
options[:title]
|
24
|
+
else
|
25
|
+
if @resource && @resource.new_record?
|
26
|
+
"New #{@interface.member.titleize}"
|
27
|
+
elsif @resource
|
28
|
+
"#{@interface.member.titleize}#{@resource.to_param.match(/\d+/) ? ' #' : ': '}#{@resource.to_param}"
|
29
|
+
else
|
30
|
+
@interface.collection.titlecase
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|