bootstrap_admin 0.0.8

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.
Files changed (70) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +246 -0
  5. data/Rakefile +1 -0
  6. data/app/assets/images/cross.gif +0 -0
  7. data/app/assets/images/search_btn.png +0 -0
  8. data/app/assets/javascripts/bootstrap_admin/bootstrap_admin.js.coffee +13 -0
  9. data/app/assets/javascripts/bootstrap_admin.js +5 -0
  10. data/app/assets/stylesheets/_backgrounds.scss +12 -0
  11. data/app/assets/stylesheets/bootstrap_admin.css +12 -0
  12. data/app/assets/stylesheets/bootstrap_overrides.css.scss +173 -0
  13. data/app/helpers/bootstrap_admin/menu_helper.rb +117 -0
  14. data/app/helpers/bootstrap_admin/paginator_helper.rb +115 -0
  15. data/app/helpers/bootstrap_admin_helper.rb +235 -0
  16. data/app/views/admin/shared/_flash_area.html.haml +6 -0
  17. data/app/views/admin/shared/_login_area.html.haml +0 -0
  18. data/app/views/admin/shared/_navigation.html.haml +8 -0
  19. data/app/views/defaults/_form.html.haml +9 -0
  20. data/app/views/defaults/_form_fields.html.haml +5 -0
  21. data/app/views/defaults/_index.html.haml +17 -0
  22. data/app/views/defaults/_paginator.html.haml +6 -0
  23. data/app/views/defaults/_search_box.html.haml +7 -0
  24. data/app/views/defaults/_show.html.haml +4 -0
  25. data/app/views/defaults/edit.html.haml +3 -0
  26. data/app/views/defaults/index.html.haml +14 -0
  27. data/app/views/defaults/new.html.haml +3 -0
  28. data/app/views/defaults/show.html.haml +11 -0
  29. data/app/views/layouts/bootstrap_admin.html.haml +16 -0
  30. data/bootstrap_admin.gemspec +25 -0
  31. data/config/initializers/simple_form.rb +34 -0
  32. data/config/locales/en.yml +5 -0
  33. data/lib/bootstrap_admin/actions.rb +121 -0
  34. data/lib/bootstrap_admin/active_record_extensions.rb +17 -0
  35. data/lib/bootstrap_admin/attribute.rb +34 -0
  36. data/lib/bootstrap_admin/controller_config.rb +57 -0
  37. data/lib/bootstrap_admin/controller_helpers.rb +78 -0
  38. data/lib/bootstrap_admin/responder.rb +157 -0
  39. data/lib/bootstrap_admin/routes.rb +28 -0
  40. data/lib/bootstrap_admin/version.rb +3 -0
  41. data/lib/bootstrap_admin.rb +58 -0
  42. data/lib/generators/bootstrap_admin/USAGE +24 -0
  43. data/lib/generators/bootstrap_admin/install_generator.rb +67 -0
  44. data/lib/generators/bootstrap_admin/templates/bootstrap_admin.rb +18 -0
  45. data/lib/generators/bootstrap_admin/templates/bootstrap_admin_menu.yml +37 -0
  46. data/lib/generators/bootstrap_admin/templates/en_bootstrap_admin.yml +37 -0
  47. data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
  48. data/vendor/assets/images/glyphicons-halflings.png +0 -0
  49. data/vendor/assets/images/jqueryui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  50. data/vendor/assets/images/jqueryui/ui-bg_flat_75_ffffff_40x100.png +0 -0
  51. data/vendor/assets/images/jqueryui/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  52. data/vendor/assets/images/jqueryui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  53. data/vendor/assets/images/jqueryui/ui-bg_glass_75_dadada_1x400.png +0 -0
  54. data/vendor/assets/images/jqueryui/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  55. data/vendor/assets/images/jqueryui/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  56. data/vendor/assets/images/jqueryui/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  57. data/vendor/assets/images/jqueryui/ui-icons_222222_256x240.png +0 -0
  58. data/vendor/assets/images/jqueryui/ui-icons_2e83ff_256x240.png +0 -0
  59. data/vendor/assets/images/jqueryui/ui-icons_454545_256x240.png +0 -0
  60. data/vendor/assets/images/jqueryui/ui-icons_888888_256x240.png +0 -0
  61. data/vendor/assets/images/jqueryui/ui-icons_cd0a0a_256x240.png +0 -0
  62. data/vendor/assets/javascripts/bootstrap.js +2025 -0
  63. data/vendor/assets/javascripts/bootstrap.min.js +6 -0
  64. data/vendor/assets/javascripts/jquery-ui-1.9.2.custom.min.js +6 -0
  65. data/vendor/assets/stylesheets/bootstrap-responsive.css +1088 -0
  66. data/vendor/assets/stylesheets/bootstrap-responsive.min.css +9 -0
  67. data/vendor/assets/stylesheets/bootstrap.css +5893 -0
  68. data/vendor/assets/stylesheets/bootstrap.min.css +9 -0
  69. data/vendor/assets/stylesheets/jquery-ui-1.9.2.custom.css +462 -0
  70. metadata +197 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bootstrap_admin.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ivo Jesus
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,246 @@
1
+ # BootstrapAdmin
2
+
3
+ Dead-simple admin interfaces!<br>
4
+ BootstrapAdmin is a small engine designed to ease the construction of administrative interfaces.
5
+
6
+ ## Installation
7
+
8
+ Add the gem to your Rails app Gemfile:
9
+ `gem 'bootstrap_admin'`
10
+
11
+ And run:
12
+ `$ bundle install`
13
+
14
+ Or just run:
15
+ `$ gem install bootstrap_admin`
16
+
17
+ Then, just run the install generator
18
+ `$ rails g bootstrap_admin:install`
19
+
20
+ By default, bootstrap\_admin will use "admin" as the namespace, but you can change this by adding the wanted namespace:
21
+
22
+ `$ rails g bootstrap_admin:install --namespace=MyAdmin`
23
+
24
+ Running the generator will create the following files (assuming the namespace is "admin"):
25
+
26
+ config/initializers/bootstrap_admin.rb
27
+ config/bootstrap_admin_menu.yml
28
+ app/assets/javascripts/admin
29
+ app/assets/javascripts/admin.js
30
+ app/assets/stylesheets/admin
31
+ app/assets/stylesheets/admin.css
32
+ app/controllers/admin_controller.rb
33
+
34
+ ## Usage
35
+
36
+ Bootstrap Admin was designed to be an almost zero-configuration drop-in solution for administration UIs, so getting it up and running is actually pretty simple.
37
+
38
+ ### Defining Routes
39
+
40
+ Bootstrap Admin comes with a route macro to define the administration section of your app.<br/>
41
+ All you need to do is head up to your `config/routes.rb` and add something like:
42
+
43
+ ```ruby
44
+ bootstrap_admin do
45
+ # define resources normally here...
46
+ # resources :books
47
+ end
48
+ ```
49
+
50
+ This will define:
51
+
52
+ * A basic route to "admin#show"
53
+ * A namespace "admin" that will contain all resources defined within the block
54
+
55
+ ### Creating a basic CRUD scaffold
56
+
57
+ For a basic CRUD interface for an Entity, all you need to do is:
58
+
59
+ * Generate a Model and set it up (relations, accessible attributes, etc..)
60
+ * Generate a Controller that inherits from your AdminController and add the `bootstrap_admin` macro on that controller
61
+ * Add the routes to the controller under the bootstrap_admin route<br/>
62
+ `resource :books`
63
+
64
+ And you're ready to roll!
65
+
66
+ #### Basic Example - Books
67
+
68
+ So, assuming you have a Book model:
69
+
70
+ `$ rails g model Book title:string author:string synopsis:text`
71
+ ```ruby
72
+ class Book < ActiveRecord::Base
73
+ accessible_attributes :title, :author, :synopsis
74
+ end
75
+ ```
76
+
77
+ All you need on the controller side (assuming you are using "admin" as namespace) is:
78
+
79
+ `$ rails g controller Admin::Books`
80
+ ```ruby
81
+ class Admin::BooksController < AdminController
82
+ bootstrap_admin
83
+ end
84
+ ```
85
+
86
+ And a route like:
87
+ ```ruby
88
+ bootstrap_admin do
89
+ resources :books
90
+ end
91
+ ```
92
+
93
+ And BAM, ready to roll!!
94
+
95
+ ## Configuring Bootstrap Admin - Initializer
96
+
97
+ TODO
98
+
99
+ ## Admin Menu
100
+
101
+ If you want to customize the bootstrap_admin menu, you can edit the `config/bootstrap_admin_menu.yml` file. There, you can specify the entries you want for the menu, customize the label, an even define dropdown sub-menus.
102
+
103
+ So, to customize the menu, you must supply a list of menu entries.<br/>
104
+ On each entry you can use this set of options:
105
+
106
+ * `:label` - the label that will be presented in the menu. This can be either:
107
+ * **Symbol** - Will be passed to I18n for translation
108
+ * **String** - Will be used directly
109
+ * `:class` - the css class to apply to the item
110
+ * `:url` - the url to be used on the item link.
111
+ * `:item` - one of 3 things:
112
+ * **String**: must be a name of a model (it will be used to build the link url and the label if not supplied)
113
+ * **List**: This will tell bootstrap_admin that the item is in fact a dropdown menu. **In this case `:label` must be supplied.**
114
+ * **Symbol**: currently only `:divider` is supported and produces a division between dropdown elements.
115
+
116
+ ### Example
117
+
118
+ # Item based on a model
119
+ - :item: Document
120
+
121
+ # Item based on a model with a custom label and css class
122
+ - :item: Author
123
+ :label: The guys who write things
124
+ :class: really_bold
125
+
126
+ # Item based on a model with a custom url
127
+ - :item: Search
128
+ :url: "https://google.com"
129
+
130
+ # Dropdown menu item with several options and a divider
131
+ - :label: :user_admin # this will be called as I18n.t(:user_admin)
132
+ :url: "#"
133
+ :item:
134
+ - :item: Role
135
+ - :item: :divider
136
+ - :item: User
137
+ :label: Dudes
138
+
139
+ ## Configuring the Controller
140
+
141
+ By default, bootstrap\_admin will use the fields defined as accessible on the model matching the name of the controller it is working on to build all markup. Also, by default, bootstrap\_admin will respond to `html` and `json` formats.
142
+ If you want to override this behaviour, the controller macro allows you to pass a block that will be used to configure how bootstrap\_admin will behave.
143
+
144
+ ### Configuring which fields to use
145
+
146
+ To override the default behaviour, you can use the following configurators:
147
+
148
+ * `index_fields` - the fields to be used on the index action
149
+ * `show_fields` - the fields to be used on the show action
150
+ * `form_fields` - the fields to be used on all form actions (new, edit, etc..)
151
+ * `searchable_fields` - the fields to be used while searching
152
+
153
+ To use these configurators, you pass a block to the bootstrap\_admin macro like so:
154
+
155
+ ```ruby
156
+ bootstrap_admin do |config|
157
+ config.index_fields = [:title, :author]
158
+ config.show_fields = [:title, :author, :synopsis]
159
+ config.form_fields = [:title, :author, :synopsis]
160
+ config.searchable_fields = [:title]
161
+ end
162
+ ```
163
+
164
+ ### Configuring response formats
165
+
166
+ bootstrap\_admin also allows you to define to which formats will your controller respond to using the `responder_formats` configurator like so:
167
+
168
+ ```ruby
169
+ bootstrap_admin do |config|
170
+ config.responder_formats = [:html, :xml, :json]
171
+ end
172
+ ```
173
+
174
+ ## Configuring the Routes
175
+
176
+ TODO
177
+
178
+ ## Overriding
179
+
180
+ ### Overriding fields with Helper methods
181
+
182
+ Lets say you have a NewsArticle model that stores news and in that article you have a field named `body` which contains the actual article in the form of markup (built with an WYSIWYG editor like CKEditor). It would be a bummer to display the whole body on the index table!!
183
+
184
+ bootstrap\_admin allows you to override the field usage by defining a helper like so:
185
+ ```ruby
186
+ def index_body record
187
+ strip_tags(record.body)[0..120] + "..."
188
+ end
189
+ ```
190
+
191
+ #### Overriding field on `show` or `index` actions
192
+
193
+ You can override the field usage just for one of the actions or for both at once if applicable.
194
+
195
+ So, if both actions can use the same display, then your helper must:
196
+
197
+ * Be named `<field>` - the name of the field
198
+ * Accept one argument - the model instance we are displaying
199
+
200
+ ```ruby
201
+ def title record
202
+ content_tag(:i, record.title)
203
+ end
204
+ ```
205
+
206
+ If, on the other hand you need to use diferent code to display diferent actions, then your helper must:
207
+
208
+ * Be named `<action>_<field>`
209
+ * Accept one argument - the model instance we are displaying
210
+
211
+ ```ruby
212
+ def show_title record
213
+ content_tag(:b, record.title)
214
+ end
215
+
216
+ def index_title record
217
+ content_tag(:i, record.title)
218
+ end
219
+ ```
220
+
221
+ #### Overriding field on `form` actions (`new`, `edit`, etc..)
222
+
223
+ To override the field usage on a form action, your helper must:
224
+
225
+ * Be named `form_<field>`
226
+ * Accept one argument - the form for the model instance
227
+
228
+ ```ruby
229
+ def form_title form
230
+ form.input(:title)
231
+ end
232
+ ```
233
+ You can use `form.object` to get the object to which the form is for.
234
+
235
+
236
+ ### Overriding the views
237
+
238
+ TODO
239
+
240
+ ## Contributing
241
+
242
+ 1. Fork it
243
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
244
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
245
+ 4. Push to the branch (`git push origin my-new-feature`)
246
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
Binary file
Binary file
@@ -0,0 +1,13 @@
1
+ # ------------------------------------------------------------------------------
2
+ $ = jQuery
3
+ # ------------------------------------------------------------------------------
4
+ $("form.bootstrap_admin.search")
5
+ .on "click", ".reset", ->
6
+ window.location = $(this).closest("form").attr("action")
7
+ .on "click", ".search", ->
8
+ $(this).closest("form").submit()
9
+ # ------------------------------------------------------------------------------
10
+ $("#flash-area").on "click", ".close", ->
11
+ $(this).closest(".alert").slideUp ->
12
+ $(this).remove()
13
+ # ------------------------------------------------------------------------------
@@ -0,0 +1,5 @@
1
+ //= require jquery
2
+ //= require jquery_ujs
3
+ //= require bootstrap
4
+ //= require jquery-ui-1.9.2.custom.min
5
+ //= require_tree './bootstrap_admin'
@@ -0,0 +1,12 @@
1
+ @mixin background-gradient($from, $to){
2
+ background-color: $to;
3
+ background-repeat: repeat-x;
4
+ background-image: -khtml-gradient(linear, left top, left bottom, from($from), to($to));
5
+ background-image: -moz-linear-gradient(top, $from, $to);
6
+ background-image: -ms-linear-gradient(top, $from, $to);
7
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, $from), color-stop(100%, $to));
8
+ background-image: -webkit-linear-gradient(top, $from, $to);
9
+ background-image: -o-linear-gradient(top, $from, $to);
10
+ background-image: linear-gradient(top, $from, $to);
11
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$from}, endColorstr=#{$to}, GradientType=0);
12
+ }
@@ -0,0 +1,12 @@
1
+ /*
2
+ *= require bootstrap
3
+ *= require bootstrap_overrides
4
+ *= require jquery-ui-1.9.2.custom
5
+ *= require_self
6
+ *= require_tree .
7
+ */
8
+ form.search{
9
+ float:right;
10
+ margin-top: -45px;
11
+ }
12
+ .clear_both{clear:both;}
@@ -0,0 +1,173 @@
1
+ @import "backgrounds.scss";
2
+
3
+ .nav_fillup{
4
+ clear:both;
5
+ margin-top:40px;
6
+ }
7
+ .container.content{
8
+ }
9
+
10
+
11
+ /* Bootstrap overrides */
12
+ body { font-size: 13px; }
13
+
14
+ h1 { font-size: 30px; }
15
+ h2 { font-size: 24px; }
16
+ h3 { font-size: 18px; line-height: 20px; }
17
+ h4 { font-size: 14px; }
18
+ h5 { font-size: 12px; }
19
+ h6 { font-size: 10px; }
20
+ h1.dotted, h2.dotted, h3.dotted, h4.dotted, h5.dotted, h6.dotted{
21
+ border-bottom:1px dotted silver;
22
+ }
23
+
24
+ label, input, button, select, textarea { font-size: 13px; }
25
+
26
+ select,
27
+ textarea,
28
+ input[type="text"],
29
+ input[type="password"],
30
+ input[type="datetime"],
31
+ input[type="datetime-local"],
32
+ input[type="date"],
33
+ input[type="month"],
34
+ input[type="time"],
35
+ input[type="week"],
36
+ input[type="number"],
37
+ input[type="email"],
38
+ input[type="url"],
39
+ input[type="search"],
40
+ input[type="tel"],
41
+ input[type="color"],
42
+ .uneditable-input {
43
+ font-size: 13px;
44
+ }
45
+
46
+ .actions{
47
+ border-top: 1px dotted silver;
48
+ padding: 20px 0;
49
+ margin-top: 10px;
50
+ }
51
+
52
+ .input-append input,
53
+ .input-prepend input,
54
+ .input-append select,
55
+ .input-prepend select,
56
+ .input-append .uneditable-input,
57
+ .input-prepend .uneditable-input {
58
+ font-size: 13px;
59
+ }
60
+
61
+ .input-append .add-on,
62
+ .input-prepend .add-on {
63
+ font-size: 13px;
64
+ }
65
+
66
+ .table td.actions{
67
+ text-align: right;
68
+ }
69
+ .btn { font-size: 13px; }
70
+ .btn-group > .btn,
71
+ .btn-group > .dropdown-menu {
72
+ font-size: 13px;
73
+ }
74
+
75
+ /*.navbar-inner {
76
+ background-color: #fafafa;
77
+ background-image: -moz-linear-gradient(top, #333, #222);
78
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333), to(#222));
79
+ background-image: -webkit-linear-gradient(top, #333, #222);
80
+ background-image: -o-linear-gradient(top, #333, #222);
81
+ background-image: linear-gradient(to bottom, #333, #222);
82
+ filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff333333', endColorstr='#ff222222', GradientType=0);
83
+ }*/
84
+
85
+ .navbar .brand {
86
+ /*color: white;*/
87
+ /*text-shadow: none;*/
88
+ }
89
+ .navbar .nav > li > a,
90
+ .navbar .nav > li > a:focus,
91
+ .navbar .nav > li > a:hover {
92
+ /*color: white;*/
93
+ text-shadow: none;
94
+ }
95
+ .navbar .nav > li > a{
96
+ color: silver;
97
+ }
98
+
99
+ .pagination {
100
+ margin: 0;
101
+ }
102
+
103
+ .pagination ul > li > a,
104
+ .pagination ul > li > span {
105
+ line-height: 28px;
106
+ }
107
+
108
+ .popover-title {
109
+ font-size: 13px;
110
+ }
111
+
112
+ .navbar-fixed-top, .navbar-fixed-bottom{
113
+ z-index: 1;
114
+ }
115
+
116
+ // ------------------------------------------------------------------------------------
117
+ .navbar-inner{
118
+ // @include background-gradient(#242424, #050505);
119
+ @include background-gradient(#333, #222);
120
+ }
121
+ .navbar{
122
+ .brand {
123
+ color: white;
124
+ text-shadow: 0 1px 0 #222;
125
+ &:hover{
126
+ text-shadow: 0 0 1px silver;
127
+ }
128
+ }
129
+ .nav > li > a{
130
+ &:focus, &:hover{
131
+ color:white;
132
+ text-shadow: 0 0 1px silver;
133
+ }
134
+ }
135
+ }
136
+ // -----------------------------------------------------------------------------
137
+ form div.error{
138
+ // background:#fae5e3;
139
+ padding:10px 0;
140
+ margin:-10px 0 10px;
141
+ -webkit-border-radius:4px;
142
+ -moz-border-radius:4px;
143
+ border-radius:4px;
144
+
145
+ >label, span.help-inline, span.help-block{
146
+ color: #9d261d;
147
+ }
148
+
149
+ .input-prepend span.add-on, .input-append span.add-on{
150
+ background:#f4c8c5;
151
+ border-color:#c87872;
152
+ color:#b9554d;
153
+ }
154
+ input, textarea, select{
155
+ border-color:#c87872;
156
+ -webkit-box-shadow:0 0 3px rgba(171, 41, 32, 0.25);
157
+ -moz-box-shadow:0 0 3px rgba(171, 41, 32, 0.25);
158
+ box-shadow:0 0 3px rgba(171, 41, 32, 0.25);
159
+ }
160
+ input[type=file]{
161
+ border: 1px solid #c87872;
162
+ }
163
+
164
+ input:focus, textarea:focus{
165
+ border-color:#b9554d;
166
+ -webkit-box-shadow:0 0 6px rgba(171, 41, 32, 0.5);
167
+ -moz-box-shadow:0 0 6px rgba(171, 41, 32, 0.5);
168
+ box-shadow:0 0 6px rgba(171, 41, 32, 0.5);
169
+ }
170
+ }
171
+
172
+
173
+
@@ -0,0 +1,117 @@
1
+ module BootstrapAdmin::MenuHelper
2
+
3
+ BOOTSTRAP_ADMIN_MENU_FILE = "config/bootstrap_admin_menu.yml"
4
+
5
+ # =============================================================================
6
+ # Builds the bootstrap_admin menu markup
7
+ # @return [Markup] bootstrap_admin menu
8
+ def bootstrap_admin_menu
9
+ content_tag :ul, :class=>"nav" do
10
+ bootstrap_admin_menu_items.map do |row|
11
+ if row[:item].is_a? Array
12
+ bootstrap_admin_menu_dropdown row
13
+ elsif row[:item].is_a? Symbol
14
+ bootstrap_admin_menu_separator row
15
+ else
16
+ bootstrap_admin_menu_item row
17
+ end
18
+ end.join.html_safe
19
+ end # content_tag
20
+ end
21
+
22
+ private
23
+ # =============================================================================
24
+ def build_bootstrap_admin_menu_from_controller_names
25
+ namespace = BootstrapAdmin.admin_namespace
26
+ Dir["./app/controllers/#{namespace}/**/*.rb"].each do |controller|
27
+ require controller
28
+ end
29
+
30
+ yml_menu = AdminController.descendants.map do |controller|
31
+ ename = controller.name.demodulize.gsub("Controller","").singularize
32
+ "- :item: #{ename}"
33
+ end.join("\n")
34
+
35
+ @bootstrap_admin_menu_items = YAML.load(yml_menu)
36
+ end
37
+
38
+ # =============================================================================
39
+ def load_bootstrap_admin_menu_items
40
+ @bootstrap_admin_menu_items = YAML.load_file(BOOTSTRAP_ADMIN_MENU_FILE)
41
+ unless @bootstrap_admin_menu_items
42
+ build_bootstrap_admin_menu_from_controller_names
43
+ end
44
+ @bootstrap_admin_menu_load_timestamp = Time.now
45
+ end
46
+
47
+ # =============================================================================
48
+ def bootstrap_admin_menu_items
49
+ if @bootstrap_admin_menu_load_timestamp.nil? or
50
+ File.mtime(BOOTSTRAP_ADMIN_MENU_FILE) > @bootstrap_admin_menu_load_timestamp
51
+ load_bootstrap_admin_menu_items
52
+ end
53
+ @bootstrap_admin_menu_items
54
+ end
55
+
56
+ # =============================================================================
57
+ def bootstrap_admin_menu_item row
58
+ if respond_to?(:cannot?) && cannot?(:read, row[:item].classify.constantize)
59
+ "".html_safe
60
+ else
61
+ content_tag(:li) do
62
+ bootstrap_admin_menu_link row
63
+ end
64
+ end
65
+ end
66
+
67
+ # =============================================================================
68
+ def bootstrap_admin_menu_dropdown row
69
+ content_tag(:li, :class=>"dropdown", :"data-dropdown"=>"dropdown") do
70
+ bootstrap_admin_menu_link(row) +
71
+ content_tag(:ul, :class=>"dropdown-menu") do
72
+ row[:item].map do |sub|
73
+ if sub[:item].is_a? Symbol
74
+ bootstrap_admin_menu_separator sub
75
+ else
76
+ bootstrap_admin_menu_item sub
77
+ end
78
+ end.join.html_safe
79
+ end
80
+ end
81
+ end
82
+
83
+ # =============================================================================
84
+ def bootstrap_admin_menu_separator row
85
+ content_tag(:li, :class => row[:item]){""}
86
+ end
87
+
88
+ # =============================================================================
89
+ def bootstrap_admin_menu_link row
90
+ if row[:item].is_a? Array #then its a dropdown menu
91
+ label = if row[:label].is_a? Symbol
92
+ t row[:label]
93
+ else
94
+ row[:label]
95
+ end
96
+ url = row[:url ] || "#"
97
+ css_class = row[:class] || "dropdown-toggle"
98
+ data_attr = { :toggle => "dropdown" }
99
+
100
+ else #then its a resource link.
101
+ model_class = row[:item].classify.constantize
102
+ model_symbol = row[:item].demodulize.underscore.pluralize.to_sym
103
+
104
+ label = if row[:label].is_a? Symbol
105
+ t row[:label]
106
+ else
107
+ row[:label] || model_class.model_name.human.pluralize
108
+ end
109
+ url = row[:url ] || [BootstrapAdmin.admin_namespace, model_symbol]
110
+ css_class = row[:class]
111
+ data_attr = {}
112
+ end
113
+
114
+ link_to label, url, :class => css_class, :data => data_attr
115
+ end
116
+
117
+ end