bootstrap_admin 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +246 -0
- data/Rakefile +1 -0
- data/app/assets/images/cross.gif +0 -0
- data/app/assets/images/search_btn.png +0 -0
- data/app/assets/javascripts/bootstrap_admin/bootstrap_admin.js.coffee +13 -0
- data/app/assets/javascripts/bootstrap_admin.js +5 -0
- data/app/assets/stylesheets/_backgrounds.scss +12 -0
- data/app/assets/stylesheets/bootstrap_admin.css +12 -0
- data/app/assets/stylesheets/bootstrap_overrides.css.scss +173 -0
- data/app/helpers/bootstrap_admin/menu_helper.rb +117 -0
- data/app/helpers/bootstrap_admin/paginator_helper.rb +115 -0
- data/app/helpers/bootstrap_admin_helper.rb +235 -0
- data/app/views/admin/shared/_flash_area.html.haml +6 -0
- data/app/views/admin/shared/_login_area.html.haml +0 -0
- data/app/views/admin/shared/_navigation.html.haml +8 -0
- data/app/views/defaults/_form.html.haml +9 -0
- data/app/views/defaults/_form_fields.html.haml +5 -0
- data/app/views/defaults/_index.html.haml +17 -0
- data/app/views/defaults/_paginator.html.haml +6 -0
- data/app/views/defaults/_search_box.html.haml +7 -0
- data/app/views/defaults/_show.html.haml +4 -0
- data/app/views/defaults/edit.html.haml +3 -0
- data/app/views/defaults/index.html.haml +14 -0
- data/app/views/defaults/new.html.haml +3 -0
- data/app/views/defaults/show.html.haml +11 -0
- data/app/views/layouts/bootstrap_admin.html.haml +16 -0
- data/bootstrap_admin.gemspec +25 -0
- data/config/initializers/simple_form.rb +34 -0
- data/config/locales/en.yml +5 -0
- data/lib/bootstrap_admin/actions.rb +121 -0
- data/lib/bootstrap_admin/active_record_extensions.rb +17 -0
- data/lib/bootstrap_admin/attribute.rb +34 -0
- data/lib/bootstrap_admin/controller_config.rb +57 -0
- data/lib/bootstrap_admin/controller_helpers.rb +78 -0
- data/lib/bootstrap_admin/responder.rb +157 -0
- data/lib/bootstrap_admin/routes.rb +28 -0
- data/lib/bootstrap_admin/version.rb +3 -0
- data/lib/bootstrap_admin.rb +58 -0
- data/lib/generators/bootstrap_admin/USAGE +24 -0
- data/lib/generators/bootstrap_admin/install_generator.rb +67 -0
- data/lib/generators/bootstrap_admin/templates/bootstrap_admin.rb +18 -0
- data/lib/generators/bootstrap_admin/templates/bootstrap_admin_menu.yml +37 -0
- data/lib/generators/bootstrap_admin/templates/en_bootstrap_admin.yml +37 -0
- data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
- data/vendor/assets/images/glyphicons-halflings.png +0 -0
- data/vendor/assets/images/jqueryui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/vendor/assets/images/jqueryui/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/vendor/assets/images/jqueryui/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/vendor/assets/images/jqueryui/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/vendor/assets/images/jqueryui/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/vendor/assets/images/jqueryui/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/vendor/assets/images/jqueryui/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/vendor/assets/images/jqueryui/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/vendor/assets/images/jqueryui/ui-icons_222222_256x240.png +0 -0
- data/vendor/assets/images/jqueryui/ui-icons_2e83ff_256x240.png +0 -0
- data/vendor/assets/images/jqueryui/ui-icons_454545_256x240.png +0 -0
- data/vendor/assets/images/jqueryui/ui-icons_888888_256x240.png +0 -0
- data/vendor/assets/images/jqueryui/ui-icons_cd0a0a_256x240.png +0 -0
- data/vendor/assets/javascripts/bootstrap.js +2025 -0
- data/vendor/assets/javascripts/bootstrap.min.js +6 -0
- data/vendor/assets/javascripts/jquery-ui-1.9.2.custom.min.js +6 -0
- data/vendor/assets/stylesheets/bootstrap-responsive.css +1088 -0
- data/vendor/assets/stylesheets/bootstrap-responsive.min.css +9 -0
- data/vendor/assets/stylesheets/bootstrap.css +5893 -0
- data/vendor/assets/stylesheets/bootstrap.min.css +9 -0
- data/vendor/assets/stylesheets/jquery-ui-1.9.2.custom.css +462 -0
- metadata +197 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
module BootstrapAdmin::PaginatorHelper
|
2
|
+
|
3
|
+
# =============================================================================
|
4
|
+
def render_paginator(paginator)
|
5
|
+
render "paginator", :paginator => paginator
|
6
|
+
end
|
7
|
+
|
8
|
+
# =============================================================================
|
9
|
+
def render_searchbox
|
10
|
+
render "search_box"
|
11
|
+
end
|
12
|
+
|
13
|
+
# =============================================================================
|
14
|
+
def paginator_previous(paginator)
|
15
|
+
if paginator[:current_page] == 1
|
16
|
+
url = "#"
|
17
|
+
css_class = "prev disabled"
|
18
|
+
else
|
19
|
+
url = url_for(params.merge(:page => paginator[:current_page]-1))
|
20
|
+
css_class = "prev"
|
21
|
+
end
|
22
|
+
|
23
|
+
content_tag(:li, :class=>css_class) do
|
24
|
+
if "#" == url
|
25
|
+
content_tag(:span, "← #{t(:previous)}".html_safe)
|
26
|
+
else
|
27
|
+
link_to "← #{t(:previous)}".html_safe, url
|
28
|
+
end
|
29
|
+
end.html_safe
|
30
|
+
end
|
31
|
+
|
32
|
+
# =============================================================================
|
33
|
+
def paginator_next(paginator)
|
34
|
+
if paginator[:current_page] == paginator[:pages]
|
35
|
+
url = "#"
|
36
|
+
css_class = "next disabled"
|
37
|
+
else
|
38
|
+
url = url_for(params.merge(:page => paginator[:current_page]+1))
|
39
|
+
css_class = "next"
|
40
|
+
end
|
41
|
+
|
42
|
+
content_tag(:li, :class=>css_class) do
|
43
|
+
if "#" == url
|
44
|
+
content_tag(:span, "#{t(:next)} →".html_safe)
|
45
|
+
else
|
46
|
+
link_to "#{t(:next)} →".html_safe, url
|
47
|
+
end
|
48
|
+
end.html_safe
|
49
|
+
end
|
50
|
+
|
51
|
+
# =============================================================================
|
52
|
+
def paginator_pages(paginator)
|
53
|
+
if paginator[:pages] <= 5
|
54
|
+
[
|
55
|
+
paginator_range(paginator[:current_page], 1..paginator[:pages])
|
56
|
+
]
|
57
|
+
|
58
|
+
elsif paginator[:current_page] <= 3
|
59
|
+
[
|
60
|
+
paginator_range(paginator[:current_page], 1..4),
|
61
|
+
paginator_page("...", "disabled"),
|
62
|
+
paginator_page(paginator[:pages])
|
63
|
+
]
|
64
|
+
|
65
|
+
elsif paginator[:current_page] >= paginator[:pages] - 2
|
66
|
+
[
|
67
|
+
paginator_page(1),
|
68
|
+
paginator_page("...", "disabled"),
|
69
|
+
paginator_range(paginator[:current_page], (paginator[:pages]-3)..paginator[:pages])
|
70
|
+
]
|
71
|
+
|
72
|
+
else
|
73
|
+
[
|
74
|
+
paginator_page(1),
|
75
|
+
paginator_page("...", "disabled"),
|
76
|
+
paginator_range(paginator[:current_page], (paginator[:current_page]-1)..(paginator[:current_page]+1)),
|
77
|
+
paginator_page("...", "disabled"),
|
78
|
+
paginator_page(paginator[:pages])
|
79
|
+
]
|
80
|
+
end.join.html_safe
|
81
|
+
end
|
82
|
+
|
83
|
+
# =============================================================================
|
84
|
+
def paginator_range(current_page, range)
|
85
|
+
contents = range.map do |page|
|
86
|
+
content_tag(:li, :class => (page==current_page ? "active" : "")) do
|
87
|
+
if page==current_page
|
88
|
+
content_tag(:span, page)
|
89
|
+
else
|
90
|
+
link_to page, url_for(params.merge(:page => page))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
contents.join.html_safe
|
96
|
+
end
|
97
|
+
|
98
|
+
# =============================================================================
|
99
|
+
def paginator_page(num, css_class = nil)
|
100
|
+
if num.to_i > 0
|
101
|
+
url = url_for(params.merge :page => num)
|
102
|
+
else
|
103
|
+
url = "#"
|
104
|
+
end
|
105
|
+
|
106
|
+
content_tag(:li, :class=>css_class) do
|
107
|
+
if '#' == url
|
108
|
+
content_tag(:span, num)
|
109
|
+
else
|
110
|
+
link_to num, url
|
111
|
+
end
|
112
|
+
end.html_safe
|
113
|
+
end
|
114
|
+
|
115
|
+
end # module BootstrapAdmin::PaginatorHelper
|
@@ -0,0 +1,235 @@
|
|
1
|
+
module BootstrapAdminHelper
|
2
|
+
# =============================================================================
|
3
|
+
# This re-implementation of link_to simply looks at the link label and if it
|
4
|
+
# falls under certain conditions, then it tries to create a label and/or url
|
5
|
+
# accordingly. Else works normally
|
6
|
+
#
|
7
|
+
# @param *args Same as the original link_to
|
8
|
+
# @param &block Same as the original link_to
|
9
|
+
#
|
10
|
+
# @return [String] link markup
|
11
|
+
#
|
12
|
+
# @example Assuming locale is set to PT
|
13
|
+
# link_to :Show, @document
|
14
|
+
# # <a href='/documents/1'>Ver</a>
|
15
|
+
#
|
16
|
+
# link_to Document
|
17
|
+
# # <a href='/documents'>Documentos</a>
|
18
|
+
#
|
19
|
+
# link_to [:edit, @document]
|
20
|
+
# # <a href='/document/1/edit'>Editar Documento</a>
|
21
|
+
#
|
22
|
+
def link_to(*args, &block)
|
23
|
+
super(*args, &block) if block_given?
|
24
|
+
|
25
|
+
# When args[0] is a symbol, then just translate the symbol...
|
26
|
+
if args[0].is_a? Symbol
|
27
|
+
super(t(args[0]), *args[1..-1])
|
28
|
+
|
29
|
+
# when arg[0] is a ActiveRecord class...
|
30
|
+
elsif args[0].is_a?(Class) and args[0] < ActiveRecord::Base
|
31
|
+
label = args[0].model_name.human.pluralize
|
32
|
+
if args.length == 1
|
33
|
+
controller_name = args[0].name.underscore.pluralize
|
34
|
+
super(label, url_for(controller: controller_name, action: "index"))
|
35
|
+
else
|
36
|
+
super(label, *args[1..-1])
|
37
|
+
end
|
38
|
+
|
39
|
+
elsif args[0].is_a?(Array) && args[0][0].is_a?(Symbol) && args[0][1] < ActiveRecord::Base
|
40
|
+
link_content = t("helpers.submit.#{args[0][0]}", :model => args[0][1].model_name.human)
|
41
|
+
super(link_content, *args[1..-1])
|
42
|
+
else
|
43
|
+
super(*args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# =============================================================================
|
48
|
+
# Builds the markup to properly display a field, including label and field value.
|
49
|
+
#
|
50
|
+
# If a block is given, then it uses the block as the field "value"
|
51
|
+
# else it looks at what the field value is and if it is:
|
52
|
+
# * a boolean, builds a fake checkbox
|
53
|
+
# * an array, builds a ul list with each element of the array
|
54
|
+
# * else, just uses the string value
|
55
|
+
#
|
56
|
+
# @param item [ActiveRecord::Base] The item record
|
57
|
+
# @param field [Symbol or String] The field to display
|
58
|
+
# @param &block [Block] An optional block that yields markup
|
59
|
+
#
|
60
|
+
# @return [Markup] the necessary markup to display the field
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# display_field @document, :title
|
64
|
+
# # <p><b>Title: </b>So Long, and Thanks For All the Fish</p>
|
65
|
+
#
|
66
|
+
# display_field @document, :awesome?
|
67
|
+
# # <p><b>Awesome: </b><span class='checkbox true'><span class='icon'></span></span></p>
|
68
|
+
#
|
69
|
+
# display_field @document, :authors
|
70
|
+
# # <p><b>Authors: </b><ul><li>Douglas Adams</li></ul></p>
|
71
|
+
#
|
72
|
+
# display_field @document, :details do
|
73
|
+
# "#{@document.title} - #{@document.year}"
|
74
|
+
# end
|
75
|
+
# # <p><b>Title: </b>So Long, and Thanks For All the Fish - 1984</p>
|
76
|
+
#
|
77
|
+
def display_field item, field, &block
|
78
|
+
content_tag :p do
|
79
|
+
content_tag(:b) do
|
80
|
+
item.class.human_attribute_name(field) + ": "
|
81
|
+
end +
|
82
|
+
if block_given?
|
83
|
+
capture(&block)
|
84
|
+
else
|
85
|
+
val = render_field item, field
|
86
|
+
if val.class.name =~ /(TrueClass|FalseClass)/
|
87
|
+
content_tag(:span, :class => "checkbox #{val.to_s}") do
|
88
|
+
content_tag(:span, :class=>"icon"){""}
|
89
|
+
end
|
90
|
+
elsif val.is_a? Array
|
91
|
+
content_tag :ul do
|
92
|
+
val.map do |uniq_val|
|
93
|
+
content_tag(:li, uniq_val.to_s)
|
94
|
+
end.join.html_safe
|
95
|
+
end
|
96
|
+
else
|
97
|
+
val.to_s
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end.html_safe
|
101
|
+
end
|
102
|
+
|
103
|
+
# =============================================================================
|
104
|
+
def render_field item, field
|
105
|
+
if self.respond_to?(helper = "#{params[:action]}_#{field}") ||
|
106
|
+
self.respond_to?(helper = "#{field}")
|
107
|
+
send helper, item
|
108
|
+
else
|
109
|
+
item.send field
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# =============================================================================
|
114
|
+
def render_form_field form, field
|
115
|
+
if self.respond_to?(helper = "#{params[:action]}_form_#{field.name}") ||
|
116
|
+
self.respond_to?(helper = "form_#{field.name}")
|
117
|
+
send helper, form
|
118
|
+
|
119
|
+
elsif field.association?
|
120
|
+
form.association field.name
|
121
|
+
|
122
|
+
else
|
123
|
+
form.input field.name
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# =============================================================================
|
128
|
+
def available_actions
|
129
|
+
bootstrap_admin_config.available_actions
|
130
|
+
end
|
131
|
+
|
132
|
+
# =============================================================================
|
133
|
+
def index_actions_for item
|
134
|
+
actions = []
|
135
|
+
|
136
|
+
if available_actions.include? :show
|
137
|
+
actions << link_to(:show, [BootstrapAdmin.admin_namespace, item], class: 'btn')
|
138
|
+
end
|
139
|
+
|
140
|
+
if available_actions.include? :edit
|
141
|
+
actions << link_to(:edit, [:edit, BootstrapAdmin.admin_namespace, item], class: 'btn')
|
142
|
+
end
|
143
|
+
|
144
|
+
if available_actions.include? :destroy
|
145
|
+
actions << link_to(:destroy, [BootstrapAdmin.admin_namespace, item], confirm: t(:confirm), method: :delete, class: 'btn btn-danger')
|
146
|
+
end
|
147
|
+
|
148
|
+
actions.join("\n").html_safe
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
# =============================================================================
|
153
|
+
# @param controller [ActionController::Base]
|
154
|
+
# @return [Class] the model class for the current controller
|
155
|
+
def model_for controller
|
156
|
+
collection_name_for(controller).classify.constantize
|
157
|
+
end
|
158
|
+
|
159
|
+
# =============================================================================
|
160
|
+
# @return [ActiveRecord::Base] the model instance based on the controller name
|
161
|
+
def model_instance_for controller
|
162
|
+
name = collection_name_for(controller).singularize
|
163
|
+
instance_variable_get "@#{name}"
|
164
|
+
end
|
165
|
+
|
166
|
+
# =============================================================================
|
167
|
+
# @return [ActiveRecord::Base Array] the model instance collection for the current controller
|
168
|
+
def collection_for controller
|
169
|
+
name = collection_name_for controller
|
170
|
+
instance_variable_get "@#{name}"
|
171
|
+
end
|
172
|
+
|
173
|
+
# =============================================================================
|
174
|
+
# @return [String] the model instance name for the current controller
|
175
|
+
def model_name_for controller
|
176
|
+
model_for(controller).model_name.underscore
|
177
|
+
end
|
178
|
+
|
179
|
+
# =============================================================================
|
180
|
+
# @return [String] the model instance collection name for the current controller
|
181
|
+
def collection_name_for controller
|
182
|
+
controller.class.name.sub("Controller", "").underscore.split('/').last
|
183
|
+
end
|
184
|
+
|
185
|
+
# =============================================================================
|
186
|
+
# Finds the model instance attributes to use for the current action.
|
187
|
+
#
|
188
|
+
# First it checks if the bootstrap_admin_config has fields configured for the
|
189
|
+
# current action. If so, it uses those, if not, it tries to guess which
|
190
|
+
# attributes to use through the model's "accessible_attributes"
|
191
|
+
#
|
192
|
+
# @return [BootstrapAdmin::Attribute Array] Attributes to be used on the current
|
193
|
+
# action
|
194
|
+
#
|
195
|
+
def attributes
|
196
|
+
return @attributes if @attributes
|
197
|
+
model_klass = model_for controller
|
198
|
+
|
199
|
+
fields = bootstrap_admin_config.send("#{params[:action]}_fields") ||
|
200
|
+
bootstrap_admin_config.send("action_fields") ||
|
201
|
+
model_klass.accessible_attributes.
|
202
|
+
reject(&:blank?).
|
203
|
+
map{|att| real_attribute_name att }
|
204
|
+
|
205
|
+
@attributes = fields.map do |att|
|
206
|
+
BootstrapAdmin::Attribute.new att,
|
207
|
+
model_klass.human_attribute_name(att),
|
208
|
+
model_klass.type_of(att)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# =============================================================================
|
213
|
+
# def render_attribute name, type = :index
|
214
|
+
# # content_tag :td do
|
215
|
+
# # if respond_to? "#{attribute.name}_index"
|
216
|
+
# # %td= send "#{attribute.name}_index", item
|
217
|
+
# # else
|
218
|
+
# # %td= item.send attribute.name
|
219
|
+
# # end
|
220
|
+
# end
|
221
|
+
|
222
|
+
private
|
223
|
+
# =============================================================================
|
224
|
+
# Translates "*_id" attribute names to association names when needed
|
225
|
+
# @param attribute [String] The attribute to "translate"
|
226
|
+
# @return [String] The attribute name translated
|
227
|
+
def real_attribute_name attribute
|
228
|
+
if attribute.match /(.+)_(?:id)(s)?$/
|
229
|
+
"#{$1}#{$2}".to_sym
|
230
|
+
else
|
231
|
+
attribute.to_sym
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
File without changes
|
@@ -0,0 +1,9 @@
|
|
1
|
+
- model_instance = model_instance_for(controller)
|
2
|
+
= simple_form_for [BootstrapAdmin.admin_namespace, model_instance] do |f|
|
3
|
+
= f.error_notification
|
4
|
+
|
5
|
+
= render "form_fields", :form => f
|
6
|
+
|
7
|
+
.actions
|
8
|
+
= yield :actions
|
9
|
+
= link_to :back, [BootstrapAdmin.admin_namespace, collection_name_for(controller)], :class => 'btn'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
- collection = collection_for controller
|
2
|
+
|
3
|
+
%table.table{:class => BootstrapAdmin.ui_styles[:index]}
|
4
|
+
%thead
|
5
|
+
%tr
|
6
|
+
- attributes.each do |attribute|
|
7
|
+
%th= attribute.human_name
|
8
|
+
%th= t(:actions)
|
9
|
+
|
10
|
+
%tbody
|
11
|
+
- collection.each do |item|
|
12
|
+
%tr
|
13
|
+
- attributes.each do |attribute|
|
14
|
+
%td= render_field item, attribute.to_s
|
15
|
+
|
16
|
+
%td.actions
|
17
|
+
= index_actions_for item
|
@@ -0,0 +1,7 @@
|
|
1
|
+
= form_tag url_for(:controller => params[:controller]), :method => :get, :class=>"search bootstrap_admin" do
|
2
|
+
.input-append{:class => params[:q].blank? ? "" : "input-prepend"}
|
3
|
+
- unless params[:q].blank?
|
4
|
+
.add-on.prepend.btn.reset= image_tag "cross.gif"
|
5
|
+
= text_field_tag "q", params[:q], :placeholder => I18n.t("placeholder.search")
|
6
|
+
.add-on.append.btn.search= image_tag "search_btn.png"
|
7
|
+
.clear
|
@@ -0,0 +1,14 @@
|
|
1
|
+
- model_klass = model_for(controller)
|
2
|
+
- model_name = model_name_for(controller)
|
3
|
+
|
4
|
+
%h1= t :listing, :elem => model_klass.model_name.human.pluralize
|
5
|
+
|
6
|
+
= render_searchbox
|
7
|
+
= render "index"
|
8
|
+
= render_paginator @paginator
|
9
|
+
|
10
|
+
.clear_both
|
11
|
+
|
12
|
+
.actions
|
13
|
+
- if available_actions.include? :new
|
14
|
+
= link_to [:new, model_klass], [:new, BootstrapAdmin.admin_namespace, model_name], :class => 'btn btn-primary'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
- model_instance = model_instance_for controller
|
2
|
+
- collection_name = collection_name_for controller
|
3
|
+
|
4
|
+
%h1= t :showing, :elem => model_instance
|
5
|
+
|
6
|
+
= render "show"
|
7
|
+
|
8
|
+
.actions
|
9
|
+
- if available_actions.include? :edit
|
10
|
+
= link_to :edit, [:edit, BootstrapAdmin.admin_namespace, model_instance], :class => 'btn'
|
11
|
+
= link_to :back, [BootstrapAdmin.admin_namespace, collection_name], :class => 'btn'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title= t :app_name
|
5
|
+
= stylesheet_link_tag BootstrapAdmin.admin_namespace, :media => "all"
|
6
|
+
= csrf_meta_tags
|
7
|
+
= yield :head
|
8
|
+
%body
|
9
|
+
= render "admin/shared/navigation"
|
10
|
+
= render "admin/shared/flash_area"
|
11
|
+
|
12
|
+
.container.content= yield
|
13
|
+
|
14
|
+
= javascript_include_tag BootstrapAdmin.admin_namespace
|
15
|
+
= yield :bottom
|
16
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bootstrap_admin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "bootstrap_admin"
|
8
|
+
gem.version = BootstrapAdmin::VERSION
|
9
|
+
gem.authors = ["Ivo Jesus", "Bruno Coelho"]
|
10
|
+
gem.email = ["ivo.jesus@gmail.com", "brunoflcoelho@gmail.com"]
|
11
|
+
gem.description = %q{Create beatifull admin sections}
|
12
|
+
gem.summary = %q{Small lib to create standard admin sections.}
|
13
|
+
gem.homepage = "https://github.com/LynxEyes/bootstrap_admin"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
# gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_runtime_dependency %q<rails>, [">= 3.1.0"]
|
21
|
+
gem.add_runtime_dependency %q<simple_form>, [">= 2.0.0"]
|
22
|
+
gem.add_runtime_dependency %q<haml>
|
23
|
+
gem.add_runtime_dependency %q<coffee-rails>
|
24
|
+
gem.add_runtime_dependency %q<jquery-rails>
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
SimpleForm.setup do |config|
|
2
|
+
|
3
|
+
config.wrappers :default,
|
4
|
+
:tag => 'div',
|
5
|
+
:class => [:clearfix ,:field_container],
|
6
|
+
:hint_class => :field_with_hint,
|
7
|
+
:error_class => :error do |wrapper|
|
8
|
+
|
9
|
+
wrapper.use :label_input
|
10
|
+
wrapper.use :hint, :wrap_with => { :tag => :span, :class => :hint }
|
11
|
+
#b.use :error, :wrap_with => { :tag => :span, :class => :error }
|
12
|
+
end
|
13
|
+
|
14
|
+
config.wrappers :full_width,
|
15
|
+
:tag => 'div',
|
16
|
+
:class => [:clearfix ,:field_container, :full_width],
|
17
|
+
:hint_class => :field_with_hint,
|
18
|
+
:error_class => :error do |wrapper|
|
19
|
+
|
20
|
+
wrapper.use :label_input
|
21
|
+
wrapper.use :hint, :wrap_with => { :tag => :span, :class => :hint }
|
22
|
+
#b.use :error, :wrap_with => { :tag => :span, :class => :error }
|
23
|
+
end
|
24
|
+
|
25
|
+
config.wrappers :non_persistence_fields,
|
26
|
+
:tag => :div,
|
27
|
+
:class => [:clearfix],
|
28
|
+
:error_class => :error do |wrapper|
|
29
|
+
wrapper.use :label
|
30
|
+
end
|
31
|
+
|
32
|
+
SimpleForm.form_class = "form-stacked"
|
33
|
+
SimpleForm.browser_validations = false
|
34
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module BootstrapAdmin
|
2
|
+
|
3
|
+
# This module defines default controller actions
|
4
|
+
# * index
|
5
|
+
# * show
|
6
|
+
# * create
|
7
|
+
# * update
|
8
|
+
# * destroy
|
9
|
+
# These actions are automagically injected on every controller
|
10
|
+
# that declares the usage of bootstrap_admin
|
11
|
+
module Actions
|
12
|
+
|
13
|
+
# The actual controller action methods!
|
14
|
+
module InstanceMethods
|
15
|
+
|
16
|
+
# =============================================================================
|
17
|
+
# Lists (all) items
|
18
|
+
def index; namespaced_response collection; end
|
19
|
+
|
20
|
+
# =============================================================================
|
21
|
+
# Shows a specific item
|
22
|
+
def show; namespaced_response instance; end
|
23
|
+
|
24
|
+
# =============================================================================
|
25
|
+
# Displays the form to create a new item
|
26
|
+
def new; namespaced_response instance; end
|
27
|
+
|
28
|
+
# =============================================================================
|
29
|
+
# Creates a new item
|
30
|
+
def create
|
31
|
+
instance model_class.create(params[model_name])
|
32
|
+
instance.save
|
33
|
+
namespaced_response instance
|
34
|
+
end
|
35
|
+
|
36
|
+
# =============================================================================
|
37
|
+
# Displays the form to edit an existing item
|
38
|
+
def edit; namespaced_response instance; end
|
39
|
+
|
40
|
+
# =============================================================================
|
41
|
+
# Updates the existing item
|
42
|
+
def update
|
43
|
+
instance.update_attributes params[model_name]
|
44
|
+
namespaced_response instance
|
45
|
+
end
|
46
|
+
|
47
|
+
# =============================================================================
|
48
|
+
# Destroys an existing item
|
49
|
+
def destroy
|
50
|
+
instance.destroy
|
51
|
+
namespaced_response instance
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
# =============================================================================
|
56
|
+
# @return [String] model name based on the controller's name
|
57
|
+
def model_name
|
58
|
+
collection_name.singularize
|
59
|
+
end
|
60
|
+
|
61
|
+
# =============================================================================
|
62
|
+
# @return [ActiveRecord::Base] model class based on the controller's name
|
63
|
+
def model_class
|
64
|
+
model_name.classify.constantize
|
65
|
+
end
|
66
|
+
|
67
|
+
# =============================================================================
|
68
|
+
# @return [ActiveRecord::Base] instance
|
69
|
+
def instance instance_var = nil
|
70
|
+
if instance_var
|
71
|
+
instance_variable_set "@#{collection_name.singularize}", instance_var
|
72
|
+
else
|
73
|
+
unless ivar = instance_variable_get("@#{collection_name.singularize}")
|
74
|
+
ivar = model_class.find params[:id]
|
75
|
+
instance_variable_set "@#{collection_name.singularize}", ivar
|
76
|
+
end
|
77
|
+
ivar
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# =============================================================================
|
82
|
+
# @return [ActiveRecord::Relation] collection of all items for the model
|
83
|
+
# named after the controller
|
84
|
+
def collection collection_var = nil
|
85
|
+
if collection_var
|
86
|
+
instance_variable_set "@#{collection_name}", collection_var
|
87
|
+
else
|
88
|
+
unless cvar = instance_variable_get("@#{collection_name}")
|
89
|
+
cvar = model_class.scoped
|
90
|
+
instance_variable_set "@#{collection_name}", cvar
|
91
|
+
end
|
92
|
+
cvar
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# =============================================================================
|
97
|
+
# @return [String] collection name based on the controller name
|
98
|
+
def collection_name
|
99
|
+
self.class.name.sub("Controller", "").underscore.split('/').last
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
# =============================================================================
|
104
|
+
# Prepares a response using the controllers reponder.
|
105
|
+
def namespaced_response var
|
106
|
+
# namespace is a property of BootstrapAdmin::Config and gets called because
|
107
|
+
# the controller's method_missing redirects the call!
|
108
|
+
response_obj = [self.namespace].flatten.compact << var
|
109
|
+
respond_with *response_obj
|
110
|
+
end
|
111
|
+
|
112
|
+
end # module InstanceMethods
|
113
|
+
|
114
|
+
# =============================================================================
|
115
|
+
# includes InstanceMethods on the target class
|
116
|
+
def self.included base
|
117
|
+
base.send :include, InstanceMethods
|
118
|
+
end
|
119
|
+
|
120
|
+
end # module Actions
|
121
|
+
end # module BootstrapAdmin
|