├── .gitignore ├── Gemfile ├── Guardfile ├── MIT-LICENSE ├── README.md ├── Rakefile ├── changelog.md ├── lib ├── rails-bootstrap-helpers.rb ├── rails-bootstrap-helpers │ ├── core_ext │ │ └── abstract.rb │ ├── helpers │ │ ├── accordion_helper.rb │ │ ├── alert_helper.rb │ │ ├── base_helper.rb │ │ ├── button_helper.rb │ │ ├── form_tag_helper.rb │ │ ├── label_helper.rb │ │ ├── navigation_helper.rb │ │ ├── options_helper.rb │ │ ├── tag_helper.rb │ │ └── url_helper.rb │ ├── rails │ │ └── engine.rb │ ├── renderers │ │ ├── abstract_link_renderer.rb │ │ ├── accordion_renderer.rb │ │ ├── action_link_renderer.rb │ │ ├── button_renderer.rb │ │ ├── content_tag_renderer.rb │ │ ├── dropdown_button_renderer.rb │ │ ├── iconic_icon_renderer.rb │ │ ├── renderer.rb │ │ ├── row_link_renderer.rb │ │ └── tabbable_renderer.rb │ └── version.rb └── tasks │ └── bootstrap-rails-helpers_tasks.rake ├── rails-bootstrap-helpers.gemspec └── spec ├── dummy ├── README.rdoc ├── Rakefile ├── app │ ├── assets │ │ ├── javascripts │ │ │ └── application.js │ │ └── stylesheets │ │ │ └── application.css │ ├── controllers │ │ └── application_controller.rb │ ├── helpers │ │ └── application_helper.rb │ ├── mailers │ │ └── .gitkeep │ ├── models │ │ └── .gitkeep │ └── views │ │ └── layouts │ │ └── application.html.erb ├── config.ru ├── config │ ├── application.rb │ ├── boot.rb │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── backtrace_silencers.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── secret_token.rb │ │ ├── session_store.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ └── routes.rb ├── lib │ └── assets │ │ └── .gitkeep ├── log │ └── .gitkeep ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ └── favicon.ico ├── script │ └── rails └── spec ├── helpers ├── accordion_helper_spec.rb ├── alert_helper_spec.rb ├── base_helper_spec.rb ├── button_helper_spec.rb ├── form_tag_helper_spec.rb ├── label_helper_spec.rb ├── navigation_helper_spec.rb ├── options_helper_spec.rb ├── tag_helper_spec.rb └── url_helper_spec.rb ├── spec_helper.rb └── support ├── html.rb └── matchers └── helpers ├── alert_helper └── render_bs_alert.rb ├── base_helper ├── render_icon.rb └── render_iconic_icon.rb ├── button_helper ├── render_bs_button_to.rb └── render_inline_button_to.rb ├── form_tag_helper ├── render_bs_button_tag.rb └── render_bs_submit_tag.rb ├── label_helper └── render_bs_label.rb └── url_helper ├── render_action_link_to.rb └── render_row_link_to.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | log/*.log 3 | pkg/ 4 | .rvmrc 5 | Gemfile.lock 6 | spec/dummy/db/*.sqlite3 7 | spec/dummy/log/*.log 8 | spec/dummy/tmp/ 9 | spec/dummy/.sass-cache 10 | *.gem 11 | .ruby-version -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Declare your gem's dependencies in rails-bootstrap-helpers.gemspec. 4 | # Bundler will treat runtime dependencies like base dependencies, and 5 | # development dependencies will be added by default to the :development group. 6 | gemspec 7 | 8 | # jquery-rails is used by the dummy application 9 | gem "jquery-rails" 10 | 11 | # Declare any dependencies that are still in development here instead of in 12 | # your gemspec. These might include edge Rails or gems from your path or 13 | # Git. Remember to move these dependencies to your gemspec before releasing 14 | # your gem to rubygems.org. 15 | 16 | # To use debugger 17 | # gem 'debugger' 18 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | # A sample Guardfile 2 | # More info at https://github.com/guard/guard#readme 3 | 4 | guard "spork", :rspec_env => { "RAILS_ENV" => "test" } do 5 | watch("config/application.rb") 6 | watch("config/environment.rb") 7 | watch("config/environments/test.rb") 8 | watch(%r{^config/initializers/.+\.rb$}) 9 | watch("Gemfile") 10 | watch("Gemfile.lock") 11 | watch("spec/spec_helper.rb") { :rspec } 12 | end 13 | 14 | guard "rspec", :cli => "--color --drb", :version => 2 do 15 | watch(%r{^spec/.+_spec\.rb$}) 16 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } 17 | watch("spec/spec_helper.rb") { "spec" } 18 | watch(%r{^spec/support/(.+)\.rb$}) { "spec" } 19 | end -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013 YOURNAME 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rails Bootstrap Helpers 2 | 3 | Rails Bootstrap Helpers is a plugin for Ruby on Rails that adds view helpers for 4 | [Bootstrap](http://getbootstrap.com/2.3.2/). It also contains some helpers 5 | for [Jasny's Bootstrap extensions](http://jasny.github.io/bootstrap/index.html). 6 | 7 | This documentation is for the upcoming release, that is git HEAD. 8 | For documentation for the latest release see: https://github.com/Tretti/rails-bootstrap-helpers/blob/v0.1.0/README.md 9 | 10 | ## Installation 11 | 12 | Add it to your Gemfile: 13 | 14 | ```ruby 15 | gem "rails-bootstrap-helpers" 16 | ``` 17 | 18 | Manually include the necessary stylesheets and JavaScript files from Bootstrap. 19 | 20 | Although it has no direct dependencies on other gems than Rails, it is necessary 21 | to include Bootstrap in some way or another to make this gem useful. 22 | For standard Bootstrap, [bootstrap-sass](https://github.com/thomas-mcdonald/bootstrap-sass) is 23 | recommended. For Jasny Bootstrap, [jasny-bootstrap-extension-rails](https://github.com/mdedetrich/jasny-bootstrap-extension-rails) is recommended. 24 | 25 | ### JavaScript 26 | 27 | Some of the helpers uses features of Bootstrap that requires JavaScript to be 28 | initialized. You need to manually do this initialization. The following helpers 29 | uses JavaScript that needs manually initialization: 30 | 31 | * Any helper with the `:tooltip` option 32 | * [bs\_popover\_button](#bs_popover_button) 33 | 34 | For which JavaScript file to include, follow the 35 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/javascript.html). 36 | 37 | ## Usage 38 | 39 | ### Common 40 | 41 | #### icon 42 | 43 | ```erb 44 | <%= icon :edit %> # renders an icon with the icon-edit icon 45 | <%= icon :edit, invert: true %> # inverts the color of the icon, making it white 46 | ``` 47 | 48 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/base-css.html#icons) 49 | 50 | #### iconic\_icon 51 | 52 | ```erb 53 | <%= iconic_icon :check %> # renders an icon with the iconic-check icon 54 | 55 | <%= iconic_icon :edit, color: :blue %> # render an icon with an CSS color 56 | <%= iconic_icon :edit, color: "#fff" %> # render an icon with an CSS color 57 | 58 | <%= iconic_icon :edit, size: 10 %> # render an icon with an CSS font size 59 | <%= iconic_icon :edit, size: "10" %> # render an icon with an CSS font size 60 | <%= iconic_icon :edit, size: "10em" %> # render an icon with an CSS font size 61 | 62 | <%= iconic_icon :edit, bs_style: "muted" %> # render an Bootstrap style 63 | <%= iconic_icon :edit, bs_style: "success" %> # render an Bootstrap style 64 | 65 | <%= iconic_icon :edit, action_style: "default" %> # render an Jasny Bootstrap action link style 66 | <%= iconic_icon :edit, action_style: "success" %> # render an Jasny Bootstrap action link style 67 | ``` 68 | 69 | Renders an icon using the Jasny Bootstrap Iconic icon set. 70 | 71 | [Jasny Bootstrap documentation](http://jasny.github.io/bootstrap/base-css.html#iconic) 72 | 73 | ### Alerts 74 | 75 | #### bs\_alert 76 | ```erb 77 | <%= bs_alert "foo" %> # standard alert box 78 | <%= bs_alert "foo", block: true %> # alert box with block style 79 | <%= bs_alert "foo", dismiss_button: true %> # alert box with a dismiss button 80 | ``` 81 | 82 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/components.html#alerts) 83 | 84 | ### Buttons 85 | 86 | #### bs\_button\_to 87 | 88 | ```erb 89 | <%= bs_button_to "google", "http://www.google.se" %> 90 | <%= bs_button_to "google", "http://www.google.se", style: "success" %> 91 | <%= bs_button_to "google", "http://www.google.se", disabled: true %> 92 | <%= bs_button_to "google", "http://www.google.se", icon: "edit" %> 93 | <%= bs_button_to "google", "http://www.google.se", icon_position: "left" %> 94 | <%= bs_button_to "google", "http://www.google.se", icon_invert: "left" %> 95 | ``` 96 | 97 | The `bs_button_to` helper renders an `a` tag, styled as a Bootstrap button. It's 98 | basically a wrapper around the `link_to` helper. In addition all the standard 99 | arguments and options that `link_to` accepts it also accepts the above options. 100 | 101 | #### bs\_inline\_button\_to 102 | 103 | ```erb 104 | <%= bs_inline_button_to "http://www.google.se", :edit %> 105 | ``` 106 | 107 | The `bs_inline_button_to` helper renders an `a` tag, styled as a inline 108 | Bootstrap button. That is, a button with the an icon (no text) and the size 109 | "mini". Except from that it accepts all options as the [bs\_button\_to](#bs_button_to) does. 110 | 111 | #### bs\_popover\_button 112 | 113 | ```erb 114 | <%= bs_popover_button "foo", "bar" %> 115 | <%= bs_popover_button "foo", "bar", position: "right" %> 116 | <%= bs_popover_button "foo" do %> 117 | <%= link_to "Google", "http://www.google.se" %> 118 | <% end %> 119 | ``` 120 | 121 | Renders a Bootstrap button that when clicked opens a popover. The content of the 122 | popover can either be supplied as the second argument or as a block. 123 | 124 | **Note:** this helper requires JavaScript to be manually initialized. Add the 125 | following code to your JavaScript file: 126 | 127 | ```javascript 128 | $("[data-toggle=popover]").popover(html: true) 129 | // The "html" option tells the plugin to not escape HTML. Useful when rendering 130 | // the popover content using a block. 131 | ``` 132 | 133 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/base-css.html#buttons) 134 | 135 | #### bs\_collapsible\_button 136 | 137 | ```erb 138 | <%= bs_collapsible_button "foo", "#bar" %> 139 | <%= bs_collapsible_button "foo", "#bar", style: "primary" %> 140 | 141 |
foobar
142 | ``` 143 | 144 | Renders a Bootstrap button that when clicked will open a collapsible section. 145 | The second argument is a selector matching the section to open. 146 | 147 | #### button\_group 148 | 149 | ```erb 150 | <%= button_group do %> 151 | <%= bs_button_to "google", "http://www.google.se" %> 152 | <%= bs_button_to "google", "http://www.google.se", style: "success" %> 153 | <% end %> 154 | 155 | <%= button_group vertical: true do %> 156 | <%= bs_button_to "google", "http://www.google.se" %> 157 | <%= bs_button_to "google", "http://www.google.se", style: "success" %> 158 | <% end %> 159 | 160 | <%= button_group toolbar: true do %> 161 | <%= button_group do %> 162 | <%= bs_button_to "google", "http://www.google.se" %> 163 | <%= bs_button_to "google", "http://www.google.se", style: "success" %> 164 | <% end %> 165 | 166 | <%= button_group do %> 167 | <%= bs_button_to "google", "http://www.google.se", disabled: true %> 168 | <%= bs_button_to "google", "http://www.google.se", icon: "edit" %> 169 | <% end %> 170 | <%= end %> 171 | ``` 172 | 173 | Renders a Bootstrap button group. That is, a div tag with the `btn-group` class. 174 | 175 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/components.html#buttonGroups) 176 | 177 | #### bs\_dropdown\_button\_to 178 | 179 | Renders a Bootstrap button with a dropdown menu. The menu items are rendered in 180 | the block by rendering list items (`
  • `) with a link (``) for the menu items. 181 | 182 | If the second argument is a string it will render a split button with a dropdown 183 | menu. The second argument will be interpreted as the URL to the left side of the 184 | button. Then the third argument can be used for options. 185 | 186 | It accepts all the same options as [bs\_button\_to](#bs_button_to). 187 | 188 | Standard button with dropdown menu. 189 | 190 | ```erb 191 | <%= bs_dropdown_button_to "foo" do %> 192 |
  • <%= link_to "Google", "http://www.google.com" %>
  • 193 |
  • <%= link_to "Github", "http://www.github.com" %>
  • 194 | <% end %> 195 | ``` 196 | Split button with a dropdown menu. 197 | 198 | ```erb 199 | <%= bs_dropdown_button_to "foo", "http://www.google.com" do %> 200 |
  • <%= link_to "Google", "http://www.google.com" %>
  • 201 |
  • <%= link_to "Github", "http://www.github.com" %>
  • 202 | <% end %> 203 | ``` 204 | 205 | Standard button with dropdown menu and an edit icon. 206 | 207 | ```erb 208 | <%= bs_dropdown_button_to "foo", icon: "edit" do %> 209 |
  • <%= link_to "Google", "http://www.google.com" %>
  • 210 |
  • <%= link_to "Github", "http://www.github.com" %>
  • 211 | <% end %> 212 | ``` 213 | 214 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/components.html#buttonDropdowns) 215 | 216 | ###
    Forms 217 | 218 | #### bs\_button\_tag 219 | 220 | ```erb 221 | <%= bs_button_to "google", :submit %> 222 | ``` 223 | 224 | Renders an `button` tag styled as a Bootstrap button. First argument is the text 225 | to be rendered on the button, the other is what type of button (that is, the HTML 226 | attribute `type`). Accepts all the options as [bs\_button\_to](#bs_button_to) does. 227 | 228 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/base-css.html#buttons) 229 | 230 | #### bs\_submit\_tag 231 | 232 | ```erb 233 | <%= bs_submit_tag "save" %> 234 | <%= bs_submit_tag "save", style: "primary" %> 235 | <%= bs_submit_tag "save", size: "small" %> 236 | ``` 237 | 238 | ### Labels 239 | 240 | #### bs\_label 241 | 242 | ```erb 243 | <%= bs_label "foo" # standard label%> 244 | <%= bs_label "foo", :success # styled label %> 245 | ``` 246 | 247 | ### Tooltips 248 | 249 | ```erb 250 | <%= bs_label "foo", tooltip: "bar" %> 251 | ``` 252 | 253 | Basically any helper accepts the `:tooltip` option. This will add a Bootstrap 254 | tooltip to the rendered component. 255 | 256 | **Note:** this option requires JavaScript to be manually initialized. Add the 257 | following code to your JavaScript file: 258 | 259 | ```javascript 260 | $("[data-toggle=tooltip]").tooltip() 261 | ``` 262 | 263 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/components.html#labels-badges) 264 | 265 | ### Tags 266 | 267 | #### bs\_content\_tag 268 | 269 | ```ruby 270 | bs_content_tag :div do 271 | append "foo" 272 | end 273 | 274 | bs_content_tag :div, id: "foo" do 275 | bs_content_tag :div, class: "asd" do 276 | append "bar" 277 | end 278 | 279 | append "foobar" 280 | end 281 | ``` 282 | 283 | The above code will return the following HTML code: 284 | 285 | ```html 286 |
    287 | foo 288 |
    289 | 290 |
    291 |
    292 | bar 293 |
    294 | foobar 295 |
    296 | ``` 297 | 298 | Returns an HTML block. This method behaves basically just like `content_tag` but 299 | properly indents and add newlines to the HTML. This is useful in helpers. 300 | 301 | ### Accordion 302 | 303 | #### accordion 304 | 305 | ```erb 306 | <%= accordion "unique_id" do |a| %> 307 | <% a.group "heading" do %> 308 | content 309 | <% end %> 310 | <% end %> 311 | ``` 312 | 313 | The above code will render the following HTML code: 314 | 315 | ```html 316 |
    317 |
    318 | 323 | 324 |
    325 |
    326 | content 327 |
    328 |
    329 |
    330 |
    331 | ``` 332 | 333 | Renders a Bootstrap accordion/collapsible section. 334 | 335 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/javascript.html#collapse) 336 | 337 | ### Url Helpers 338 | 339 | #### action\_link\_to 340 | 341 | ```erb 342 | <%= action_link_to "google", "http://www.google.se" %> 343 | <%= action_link_to "google", "http://www.google.se", style: "default" %> 344 | <%= action_link_to "google", "http://www.google.se", style: "primary" %> 345 | ``` 346 | 347 | Renders an action link from Jasny's Bootstrap extensions. It's basically a 348 | wrapper around the `link_to` helper. In addition all the standard arguments and 349 | options that `link_to` accepts it also accepts the above options. 350 | 351 | [Jasny Bootstrap documentation](http://jasny.github.io/bootstrap/base-css.html#action-links) 352 | 353 | #### row\_link\_to 354 | 355 | ```erb 356 | <%= row_link_to "google", "http://www.google.se" %> 357 | ``` 358 | 359 | Renders a row link from Jasny's Bootstrap extensions. It's basically a 360 | wrapper around the `link_to` helper. 361 | 362 | [Jasny Bootstrap documentation](http://jasny.github.io/bootstrap/javascript.html#rowlink) 363 | 364 | ### Navigation 365 | 366 | #### tabbable 367 | 368 | Renders a tabbable navigation. By default the first tab will be active. This is 369 | possible to override by passing `active: true` or `active: false` to any tab 370 | or tab pane. If `active: false` is specified to any tab or tab pane the first 371 | tab or tab pane will _not_ get the class "active". 372 | 373 | ```erb 374 | <%= tabbable do |bar| %> 375 | <% bar.tab "foo" %> 376 | <% bar.tab "bar" %> 377 | 378 | <% bar.tab_pane do %> 379 | Foo pane 380 | <% end %> 381 | 382 | <% bar.tab_pane do %> 383 | Bar pane 384 | <% end %> 385 | <% end > 386 | ``` 387 | 388 | The above code will render the following HTML: 389 | 390 | ```html 391 |
    392 | 396 | 397 |
    398 |
    399 | foo content 400 |
    401 | 402 |
    403 | bar content 404 |
    405 |
    406 |
    407 | ``` 408 | 409 | Alternatively the tabs can be passed directly to the `tabbable` method: 410 | 411 | ```erb 412 | <%= tabbable "foo", "bar" do |bar| %> 413 | <% bar.tab_pane do %> 414 | Foo pane 415 | <% end %> 416 | 417 | <% bar.tab_pane do %> 418 | Bar pane 419 | <% end %> 420 | <% end > 421 | ``` 422 | 423 | If the number of tabs and tab panes don't match an error will be raised. 424 | 425 | ```erb 426 | <%= tabbable "foo", fade: true do |bar| %> 427 | <% bar.tab_pane do %> 428 | Foo pane 429 | <% end %> 430 | <% end > 431 | ``` 432 | 433 | The above option will add the "fade in" class to each tab pane. Requires the 434 | bootstrap-transition.js file to work. 435 | 436 | ```erb 437 | <%= tabbable do |bar| %> 438 | <% bar.tab "foo" %> 439 | <% bar.tab "bar", active: true %> 440 | 441 | <% bar.tab_pane do %> 442 | Foo pane 443 | <% end %> 444 | 445 | <% bar.tab_pane active: true do %> 446 | Bar pane 447 | <% end %> 448 | <% end > 449 | ``` 450 | 451 | The above will add the class "active" only to the tabs and tab panes with the 452 | option `active: true`. 453 | 454 | ```erb 455 | <%= tabbable "foo", bordered: true do |bar| %> 456 | <% bar.tab_pane do %> 457 | Foo pane 458 | <% end %> 459 | <% end > 460 | ``` 461 | 462 | The above option will render the tabbable container with a border. Requires 463 | the Jasny Bootstrap extensions. 464 | 465 | Add the option `direction`, with the value `"top"`, `"left"`, `"right"` or 466 | `"below"`, to render the tabs in the direction specified. 467 | 468 | [Bootstrap documentation](http://getbootstrap.com/2.3.2/components.html#navs) 469 | [Jasny Bootstrap documentation](http://jasny.github.io/bootstrap/components.html#navs) 470 | 471 | ## Tests 472 | 473 | Run the tests using RSpec 474 | 475 | $ bundle install 476 | $ bundle exec rspec 477 | 478 | ## License 479 | 480 | Rails Bootstrap Helpers is licensed under [The MIT license](http://opensource.org/licenses/MIT) -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | begin 3 | require 'bundler/setup' 4 | rescue LoadError 5 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks' 6 | end 7 | begin 8 | require 'rdoc/task' 9 | rescue LoadError 10 | require 'rdoc/rdoc' 11 | require 'rake/rdoctask' 12 | RDoc::Task = Rake::RDocTask 13 | end 14 | 15 | RDoc::Task.new(:rdoc) do |rdoc| 16 | rdoc.rdoc_dir = 'rdoc' 17 | rdoc.title = 'RailsBootstrapHelpers' 18 | rdoc.options << '--line-numbers' 19 | rdoc.rdoc_files.include('README.rdoc') 20 | rdoc.rdoc_files.include('lib/**/*.rb') 21 | end 22 | 23 | 24 | 25 | 26 | Bundler::GemHelper.install_tasks 27 | 28 | require 'rake/testtask' 29 | 30 | Rake::TestTask.new(:test) do |t| 31 | t.libs << 'lib' 32 | t.libs << 'test' 33 | t.pattern = 'test/**/*_test.rb' 34 | t.verbose = false 35 | end 36 | 37 | 38 | task :default => :test 39 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Rails Bootstrap Helpers 2 | 3 | ## Version 0.1.0 4 | 5 | ### New/Changed Features 6 | * Renamed option "placement" to "position" for `bs_popover_button` 7 | * Add new form tag helper `bs_submit_tag` 8 | * Add new button `bs_collapsible_button` 9 | * Add new tag helper `bs_content_tag` 10 | * Add new helper `accordion` 11 | * Add new options helper `append_class!` 12 | * Add new button helper `button_group` 13 | * Add support for tooltips to button helpers 14 | * Add new helper `action_link_to` 15 | * Add new helper `iconic_icon` 16 | * Add new helper `row_link_to` 17 | * Add new tabbable navigation helper `tabbable` 18 | * Add "inline" HTML class to inline buttons 19 | * Add new dropdown button helper `bs_dropdown_button_to` 20 | 21 | ### Bugs Fixed 22 | * "class" option not being passed through button helpers 23 | * "class" option not being passed through icon helper 24 | 25 | ## Version 0.0.1 26 | ### New/Changed Features 27 | * Initial releases -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers.rb: -------------------------------------------------------------------------------- 1 | require "rails-bootstrap-helpers/core_ext/abstract" 2 | 3 | module RailsBootstrapHelpers 4 | module Renderers 5 | autoload :AbstractLinkRenderer, "rails-bootstrap-helpers/renderers/abstract_link_renderer" 6 | autoload :AccordionRenderer, "rails-bootstrap-helpers/renderers/accordion_renderer" 7 | autoload :ActionLinkRenderer, "rails-bootstrap-helpers/renderers/action_link_renderer" 8 | autoload :ButtonRenderer, "rails-bootstrap-helpers/renderers/button_renderer" 9 | autoload :ContentTagRenderer, "rails-bootstrap-helpers/renderers/content_tag_renderer" 10 | autoload :DropdownButtonRenderer, "rails-bootstrap-helpers/renderers/dropdown_button_renderer" 11 | autoload :IconicIconRenderer, "rails-bootstrap-helpers/renderers/iconic_icon_renderer" 12 | autoload :Renderer, "rails-bootstrap-helpers/renderers/renderer" 13 | autoload :RowLinkRenderer, "rails-bootstrap-helpers/renderers/row_link_renderer" 14 | autoload :TabbableRenderer, "rails-bootstrap-helpers/renderers/tabbable_renderer" 15 | end 16 | 17 | module Helpers 18 | autoload :OptionsHelper, "rails-bootstrap-helpers/helpers/options_helper" 19 | autoload :BaseHelper, "rails-bootstrap-helpers/helpers/base_helper" 20 | autoload :AccordionHelper, "rails-bootstrap-helpers/helpers/accordion_helper" 21 | autoload :UrlHelper, "rails-bootstrap-helpers/helpers/url_helper" 22 | autoload :AlertHelper, "rails-bootstrap-helpers/helpers/alert_helper" 23 | autoload :ButtonHelper, "rails-bootstrap-helpers/helpers/button_helper" 24 | autoload :FormTagHelper, "rails-bootstrap-helpers/helpers/form_tag_helper" 25 | autoload :LabelHelper, "rails-bootstrap-helpers/helpers/label_helper" 26 | autoload :TagHelper, "rails-bootstrap-helpers/helpers/tag_helper" 27 | autoload :NavigationHelper, "rails-bootstrap-helpers/helpers/navigation_helper" 28 | end 29 | end 30 | 31 | require "rails-bootstrap-helpers/rails/engine" -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/core_ext/abstract.rb: -------------------------------------------------------------------------------- 1 | # 2 | class AbstractError < Exception; end 3 | 4 | # Class method that marks one or several methods as abstract, or a whole 5 | # class. If an abstract method is called an AbstractError will be thrown. 6 | # 7 | # Note: when making a whole class abstract the call to "abstract" must come 8 | # after any constructors. 9 | # 10 | # ==== Parameters 11 | # @param args [Array] A list of methods that should be abstract. 12 | # If the list is empty the class that called the method will be made 13 | # abstract instead. 14 | # 15 | # ==== Examples 16 | # 17 | # class Foo 18 | # abstract 19 | # end 20 | # 21 | # class Bar < Foo 22 | # end 23 | # 24 | # Foo.new 25 | # # => AbstractError: Cannot instantiate abstract class Foo. 26 | # 27 | # Bar.new 28 | # # => # 29 | # 30 | # class Base 31 | # abstract :foo 32 | # end 33 | # 34 | # class Sub < Base 35 | # end 36 | # 37 | # class Foo < Base 38 | # def foo 39 | # 3 40 | # end 41 | # end 42 | # 43 | # Sub.new.foo 44 | # # => AbstractError: Unimplemented abstract method foo. 45 | # 46 | # Foo.new.foo 47 | # # => 3 48 | def abstract(*args) 49 | if args.length == 0 50 | class_eval do 51 | alias __abstract_initialize__ initialize 52 | 53 | def initialize (*params, &block) 54 | raise AbstractError.new("Cannot instantiate abstract class #{self.class.name}.") 55 | end 56 | 57 | def self.inherited (subclass) 58 | subclass.send(:define_method, :initialize) do |*args| 59 | __abstract_initialize__ *args 60 | end 61 | end 62 | end 63 | else 64 | class_eval do 65 | args.each do |name| 66 | define_method name do |*params, &block| 67 | raise AbstractError.new("Unimplemented abstract method #{name}.") 68 | end 69 | end 70 | end 71 | end 72 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/accordion_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::AccordionHelper 2 | # Renders a Bootstrap accordion. 3 | # 4 | # @param [String] an ID that is unique for the page 5 | def accordion (id, &block) 6 | RailsBootstrapHelpers::Renderers::AccordionRenderer.new(self, id, &block).render 7 | end 8 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/alert_helper.rb: -------------------------------------------------------------------------------- 1 | # -*- encoding : utf-8 -*- 2 | 3 | module RailsBootstrapHelpers::Helpers::AlertHelper 4 | # Renders a Bootstrap alert with the given text. 5 | # 6 | # @param text [String] the text to render in the alert 7 | # 8 | # @option options [String] :style the style of alert to render 9 | # 10 | # @option options [Boolean] :block (false) indicates if the alert should 11 | # render with block style 12 | # 13 | # @options options [Boolean] :dismiss_button (false) indicates if an dismiss 14 | # button should be added to the alert 15 | def bs_alert (text, options = {}) 16 | options = options.deep_dup 17 | cls = "alert" 18 | type = options.delete(:type) 19 | 20 | if type 21 | ActiveSupport::Deprecation.warn "Usage of the option `:type` is deprecated. Please use the `:style` option instead" 22 | end 23 | 24 | if style = options.delete(:style) || type 25 | style = style.to_s 26 | 27 | if style == "notice" 28 | style = "success" 29 | end 30 | 31 | unless style == "warning" || style == "default" 32 | cls << " alert-#{style}" 33 | end 34 | end 35 | 36 | if style = options.delete(:block) 37 | cls << " alert-block" 38 | end 39 | 40 | append_class!(options, cls) 41 | 42 | if options.delete(:dismiss_button) 43 | content_tag :div, class: cls do 44 | button = content_tag :button, "×", 45 | type: "button", 46 | class: "close", 47 | :"data-dismiss" => "alert" 48 | 49 | button + text 50 | end 51 | else 52 | content_tag :div, text, options 53 | end 54 | end 55 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/base_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::BaseHelper 2 | include RailsBootstrapHelpers::Helpers::OptionsHelper 3 | 4 | # Renders the given icon 5 | # 6 | # Renders an i tag with the class "icon-#{icon}" 7 | # 8 | # @param icon [String, Symbol] the kind of icon to render 9 | # 10 | # @option options [Boolean] :invert (false) if the color of the icon should be inverted 11 | def icon (icon, options = {}) 12 | options = options.dup 13 | 14 | icon = ERB::Util.html_escape(icon.to_s) 15 | append_class!(options, "icon-" + icon) 16 | 17 | if options.delete(:invert) 18 | append_class!(options, "icon-white") 19 | end 20 | 21 | cls = options[:class] 22 | 23 | "".html_safe 24 | end 25 | 26 | # Renders the given Iconic icon. 27 | # 28 | # This is the Iconic icons from Jasny Bootstrap. 29 | # Renders an i tag with the class "iconic-#{icon}" 30 | # 31 | # @param icon [String, Symbol] the kind of icon to render 32 | # 33 | # @option options [String, Symbol] :color the CSS color of the icon 34 | # @option options [String, Symbol, Number] :size the CSS font size of the icon 35 | # 36 | # @option options [:warning, :error, :info, :success, :muted] :bs_style 37 | # the Bootstrap style to render the icon in 38 | # 39 | # @option options [:primary, :info, :success, :warning, :danger] :action_style 40 | # renders the icon with this action link style 41 | def iconic_icon (icon, options = {}) 42 | RailsBootstrapHelpers::Renderers::IconicIconRenderer.new(self, icon, options).render 43 | end 44 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/button_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::ButtonHelper 2 | include RailsBootstrapHelpers::Helpers::OptionsHelper 3 | include RailsBootstrapHelpers::Helpers::FormTagHelper 4 | 5 | # Renders a Bootstrap button. This method behaves just as "link_to" but will 6 | # render a Bootstrap button instead of a regular link. Note that this is still 7 | # an "a" tag and not an "input" tag. In addition to the options "link_to" 8 | # handles this method also handles the following options: 9 | # 10 | # @option options [String, Symbol] :style the style of the button 11 | # @option options ["large", "small", "mini"] :size the size of the button 12 | # @option options [Boolean] :disabled (false) if the button should be disabled or not 13 | # @option options [String] :icon the name of an icon to render on the button 14 | # @option options ["left", "right"] :icon_position (left) the position of the icon, if present 15 | # 16 | # @option options [Boolean] :icon_invert (false) if the color of the icon 17 | # should be inverted or not 18 | def bs_button_to (*args, &block) 19 | RailsBootstrapHelpers::Renderers::ButtonRenderer.new(self, :link, *args, &block).render 20 | end 21 | 22 | # Renders an inline Bootstrap button. That is, a small button having only an 23 | # icon and no text. 24 | # 25 | # @param url [String] the URL the button should link to 26 | # @param icon [String] the icon of the button 27 | # @param options [Hash] a hash of options. See {#bs_button_to} 28 | # 29 | # @see #bs_button_to 30 | def bs_inline_button_to (url, icon, options = {}) 31 | options = options.reverse_merge icon: icon, size: "mini" 32 | append_class!(options, "inline") 33 | RailsBootstrapHelpers::Renderers::ButtonRenderer.new(self, :link, nil, url, options).render 34 | end 35 | 36 | # Renders a Bootstrap button with a popover. 37 | # 38 | # @param name [String] the name/title of the button 39 | # @param content_or_options [String, Hash] a hash of options if a block is 40 | # passed, otherwise the content of the popover 41 | # 42 | # @param block [block] a block rendering the content of the popover 43 | # 44 | # @option options [String, "bottom", "top", "left", "right"] :position the 45 | # position of the popover 46 | # 47 | # @see #bs_button_to 48 | def bs_popover_button (name, content_or_options = nil, options = {}, &block) 49 | if block_given? 50 | bs_popover_button(name, capture(&block).gsub("\n", ""), content_or_options || {}) 51 | else 52 | options = options.deep_dup 53 | placement = options.delete(:placement) 54 | 55 | if placement 56 | ActiveSupport::Deprecation.warn "Usage of the option `:placement` is deprecated. Please use the `:position` option instead" 57 | end 58 | 59 | position = options.delete(:position) || placement || "bottom" 60 | 61 | options = options.reverse_merge :"data-content" => content_or_options, 62 | :"data-toggle" => "popover", 63 | :"data-placement" => position 64 | 65 | bs_button_to(name, '#', options) 66 | end 67 | end 68 | 69 | # Renders a collapsible Bootstrap button. That is, a button when clicked opens 70 | # a collapsible section. 71 | # 72 | # @param text [String] the text of the button 73 | # @param target [String] a selector matching the 74 | # @param options [Hash] a hash of options. All options are passed straight 75 | # through to the underlying bs_button_to method. 76 | # 77 | # @see #bs_button_to 78 | def bs_collapsible_button (text, target, options = {}) 79 | options = options.dup.reverse_merge :"data-toggle" => "collapse", 80 | :"data-target" => target 81 | 82 | bs_button_tag text, :button, options 83 | end 84 | 85 | # Returns a button group. That is, a div tag with the "btn-group" class. 86 | # 87 | # @param options [Hash] a hash of options. 88 | # 89 | # @option options [Boolean] :vertical (false) if true, appends 90 | # the "btn-group-vertical" class 91 | # 92 | # @option options [Boolean] :toolbar (false) if true, wraps the group in an 93 | # another group with the "btn-toolbar" class 94 | # 95 | # All other options are passed to the button group div. 96 | def button_group (options = {}, &block) 97 | if toolbar = options.delete(:toolbar) 98 | append_class!(options, "btn-toolbar") 99 | else 100 | append_class!(options, "btn-group") 101 | append_class!(options, "btn-group-vertical") if options.delete(:vertical) 102 | end 103 | 104 | content_tag(:div, options, &block) 105 | end 106 | 107 | # Renders a dropdown button. 108 | # 109 | # All options are passed to the underlying button. 110 | # 111 | # @param text [String] the text of the button 112 | # 113 | # @param url_or_options [String, Hash] if a string, the button will be rendered 114 | # as split dropdown button. This argument will be interpreted as the 115 | # URL of the button. If an Hash, it will be interpreted as the options 116 | # for the button an a normal dropdown button will be rendered. 117 | # 118 | # @param options [Hash] if the an URL is passed as the "url_or_options" 119 | # argument this will will be interpreted a hash of options. Otherwise 120 | # it will be ignored. 121 | # 122 | # @param block [Proc] the block should render a the dropdown menu items in the 123 | # form of list items with links. 124 | def bs_dropdown_button_to (text, url_or_options = nil, options = {}, &block) 125 | RailsBootstrapHelpers::Renderers::DropdownButtonRenderer.new(self, text, url_or_options, options, &block).render 126 | end 127 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/form_tag_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::FormTagHelper 2 | # Renders a Bootstrap button tag. This method behaves just as 3 | # button_tag but will render a Bootstrap styled button tag instead. 4 | # 5 | # @params value [String] the text of the button 6 | # @params type [String, Symbol] the type of the button. Adds a "type" 7 | # attribute to the tag 8 | # 9 | # @params options [Hash] a hash of options 10 | # 11 | # @option options [String, Symbol] :style the style of the button 12 | # @option options ["large", "small", "mini"] :size the size of the button 13 | # @option options [Boolean] :disabled (false) if the button should be disabled or not 14 | # @option options [String] :icon the name of an icon to render on the button 15 | # @option options ["left", "right"] :icon_position ("left") the post of the icon, if present 16 | # @option options [Boolean] :icon_invert (left) if the color of the icon should be inverted 17 | def bs_button_tag (value, type, options = {}, &block) 18 | options = options.merge type: type 19 | RailsBootstrapHelpers::Renderers::ButtonRenderer.new(self, :button, value, options, &block).render 20 | end 21 | 22 | # Renders a Boolean submit tag. This method behaves just as 23 | # submit_tag but will render a Bootstrap styled submit tag instead. 24 | # 25 | # @param value [String] the text of the submit tag 26 | # @param options [Hash] a hash of options 27 | # 28 | # @option options [String, Symbol] :style the style of the button 29 | # @option options ["large", "small", "mini"] :size the size of the button 30 | # 31 | # All the other options are passed straight through to the underlying 32 | # submit_tag method. 33 | def bs_submit_tag (value, options = {}) 34 | options = options.dup 35 | 36 | if options[:class].present? 37 | options[:class] << " " 38 | else 39 | options[:class] = "" 40 | end 41 | 42 | options[:class] << "btn" 43 | 44 | if style = options.delete(:style) 45 | options[:class] << " btn-" + style.to_s 46 | end 47 | 48 | if size = options.delete(:size) 49 | options[:class] << " btn-" + size.to_s 50 | end 51 | 52 | submit_tag value, options 53 | end 54 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/label_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::LabelHelper 2 | include RailsBootstrapHelpers::Helpers::OptionsHelper 3 | 4 | # Renders a Bootstrap label. 5 | # 6 | # @param text [String] the text rendered in the label 7 | # @param style [Symbol, Symbol] the style used to render the label 8 | # @param options [Hash] a hash of options. Passed straight through to the 9 | # underlying "span" tag. 10 | # 11 | def bs_label (text, style = :default, options = {}) 12 | normalize_style = lambda do |style| 13 | style = style.to_s 14 | 15 | case style 16 | when "inactive" then "default" 17 | when "active" then "success" 18 | when "error" then "important" 19 | else 20 | style 21 | end 22 | end 23 | 24 | options = options.dup 25 | style = normalize_style.call(style) 26 | 27 | cls = options[:class] 28 | cls ||= "label" 29 | cls << " label-" + style unless style == "default" 30 | 31 | options[:class] = cls 32 | 33 | content_tag :span, text, bs_options(options) 34 | end 35 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/navigation_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::NavigationHelper 2 | include RailsBootstrapHelpers::Helpers::OptionsHelper 3 | 4 | # Renders a Bootstrap tabbable navigation. 5 | # 6 | # @param args [Array, Hash] an array of the names of the tab items. 7 | # If the last item is a Hash it's considered to be the options. 8 | # 9 | # @option options [Boolean] :bordered (false) if true, will render the tab 10 | # container with a border. This option requires the Jasny Bootstrap extensions. 11 | # 12 | # @option option [Bootstrap] :fade (false) if true, will add the "fade in" 13 | # class to all tab panes. This requires the bootstrap-transition.js file. 14 | def tabbable (*args, &block) 15 | RailsBootstrapHelpers::Renderers::TabbableRenderer.new(self, *args, &block).render 16 | end 17 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/options_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::OptionsHelper 2 | # Handles general Bootstrap options available for all Bootstrap helpers. 3 | # 4 | # Any option not specify below are kept intact. 5 | # 6 | # @param options [Hash] a hash of options 7 | # @param html_options [Hash] a hash of HTML options/attributes 8 | # 9 | # @option option [String] :tooltip the text of the tooltip. If present adds attributes 10 | # for a Bootstrap tooltip. This will add the data-toggle="tooltip" 11 | # and title="#{tooltip}" HTML attributes if not already present 12 | # 13 | # @option options ["left", "right", "top", "bottom"] :tooltip_location the position of 14 | # the tooltip if :tooltip is present. Adds the 15 | # data-placement="#{tooltip_position}" HTML attribute if not 16 | # already present. 17 | def bs_options (options, html_options = {}) 18 | options = options.reverse_merge(html_options) 19 | 20 | if tooltip = options.delete(:tooltip) 21 | options[:"data-toggle"] ||= "tooltip" 22 | options[:title] ||= tooltip 23 | 24 | if tooltip_position = options.delete(:tooltip_position) 25 | options[:"data-placement"] ||= tooltip_position 26 | end 27 | end 28 | 29 | options 30 | end 31 | 32 | # Appends the given classes on the given options hash. 33 | # 34 | # It will look for both the "class" and :class key. This will create a new 35 | # :class key in the given hash if neither exist. 36 | # 37 | # @param options [Hash] hash of options to append the classes to 38 | # @param new_classes [Array] the classes to append 39 | # @return options 40 | def append_class! (options, *new_classes) 41 | return options if new_classes.empty? 42 | key = options.key?("class") ? "class" : :class 43 | cls = options[key].to_s || "" 44 | 45 | if cls.present? && new_classes.first.present? 46 | cls << " " 47 | end 48 | 49 | cls << new_classes.join(" ") 50 | options[key] = cls 51 | options 52 | end 53 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/tag_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::TagHelper 2 | # Returns an HTML block tag. Properly adds indentation and newlines for the 3 | # returned HTML. 4 | # 5 | # ==== Example 6 | # bs_content_tag "div", id: "foo" do 7 | # bs_content_tag "div" 8 | # append "foo" 9 | # end 10 | # 11 | # append "bar" 12 | # end 13 | # 14 | #
    15 | #
    16 | # foo 17 | #
    18 | # bar 19 | #
    20 | # 21 | # @param [String] the name of the tag to render 22 | # @param [Hash] a hash of HTML attributes 23 | def bs_content_tag (name, options = {}, &block) 24 | RailsBootstrapHelpers::Renderers::ContentTagRenderer.new(self, name, options, &block).render 25 | end 26 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/helpers/url_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Helpers::UrlHelper 2 | # Renders a Jasny Bootstrap action link. This method behaves just as "link_to" 3 | # but will render a Jasny Bootstrap action link instead of a regular link. 4 | # In addition to the options "link_to" handles, this method also handles the 5 | # following options: 6 | # 7 | # @option options [String, Symbol] :style the style of the link 8 | def action_link_to (*args, &block) 9 | RailsBootstrapHelpers::Renderers::ActionLinkRenderer.new(self, *args, &block).render 10 | end 11 | 12 | # Renders a Jasny Bootstrap row link. This method behaves just as "link_to" 13 | # but will render a Jasny Bootstrap row link instead of a regular link. 14 | def row_link_to (*args, &block) 15 | RailsBootstrapHelpers::Renderers::RowLinkRenderer.new(self, *args, &block).render 16 | end 17 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/rails/engine.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers 2 | module Rails 3 | class Engine < ::Rails::Engine 4 | initializer "rails-bootstrap-helpers.helpers" do 5 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::AccordionHelper 6 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::UrlHelper 7 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::AlertHelper 8 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::BaseHelper 9 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::ButtonHelper 10 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::FormTagHelper 11 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::LabelHelper 12 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::TagHelper 13 | ActionView::Base.send :include, RailsBootstrapHelpers::Helpers::NavigationHelper 14 | end 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/abstract_link_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class AbstractLinkRenderer < Renderer 3 | def initialize (template, type, *args, &block) 4 | super template 5 | @args = args 6 | @block = block 7 | @text = self.args[0] 8 | @type = type 9 | 10 | extract_options! 11 | end 12 | 13 | def render 14 | template.send method, *new_args, &block 15 | end 16 | 17 | protected 18 | 19 | attr_reader :block 20 | attr_reader :args 21 | 22 | attr_accessor :options 23 | attr_accessor :html_options 24 | attr_accessor :text 25 | attr_accessor :type 26 | 27 | def method 28 | case type 29 | when :link then :link_to 30 | when :button then :button_tag 31 | else :link_to 32 | end 33 | end 34 | 35 | def new_args 36 | case type 37 | when :link 38 | [text, options, html_options, *self.args[3 .. -1]] 39 | when :button then 40 | opts = options.reverse_merge(html_options) 41 | [text, opts, *self.args[3 .. -1]] 42 | else 43 | [text, options, html_options, *self.args[3 .. -1]] 44 | end 45 | end 46 | 47 | # Returns true if the given key exists as an option. 48 | # 49 | # @param key [String, Symbol] the key to check for 50 | # @return the value of the option 51 | def has_option? (key) 52 | _has_option?(key, options, html_options) 53 | end 54 | 55 | # Appends the given class to the "class" HTMl attribute. 56 | # 57 | # @param cls [String, Symbol] the class to append 58 | def append_class (cls) 59 | return unless cls 60 | 61 | if c = html_options["class"] 62 | html_options["class"] << " " + cls.to_s 63 | else 64 | if c = has_option?("class") 65 | c << " " + cls.to_s 66 | cls = c 67 | end 68 | 69 | html_options["class"] = cls.to_s 70 | end 71 | end 72 | 73 | private 74 | 75 | def extract_options! 76 | self.options = args[1] 77 | 78 | if options.is_a?(Hash) 79 | self.options = bs_options(options) 80 | self.options = options.stringify_keys 81 | end 82 | 83 | self.html_options = args[2] || {} 84 | self.html_options = bs_options(html_options) 85 | self.html_options = html_options.stringify_keys 86 | 87 | if cls = html_options["class"] 88 | html_options["class"] = cls.dup 89 | end 90 | end 91 | 92 | def _has_option? (key, options, html_options = nil) 93 | result = options.is_a?(Hash) && options.key?(key) && options.delete(key) 94 | 95 | if html_options 96 | result || _has_option?(key, html_options) 97 | else 98 | result 99 | end 100 | end 101 | end 102 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/accordion_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class AccordionRenderer < Renderer 3 | def initialize (template, id, &block) 4 | super template 5 | @id = id 6 | @block = block 7 | @selector = Selector.new 8 | end 9 | 10 | def render 11 | @context = AccordionContext.new(self) 12 | block.call(context) 13 | build_accordion 14 | end 15 | 16 | private 17 | attr_reader :id 18 | attr_reader :block 19 | attr_reader :selector 20 | attr_reader :context 21 | 22 | def build_accordion 23 | content_tag :div, id: id, class: "accordion" do 24 | contents = [] 25 | selector.base "##{id}.accordion" do |base| 26 | context.groups.each_with_index do |group, count| 27 | contents << build_group(group, count, base) 28 | end 29 | end 30 | 31 | contents.join("\n").html_safe 32 | end 33 | end 34 | 35 | def build_group (group, count, accordion_base) 36 | base = "accordion-group" 37 | 38 | selector.base ".#{base}" do |group_base| 39 | foobar = self 40 | content_tag(:div, class: base) do 41 | body = "accordion-body" 42 | build_heading(group.heading, body, count, accordion_base, group_base) + 43 | build_body(body, group.block) 44 | end 45 | end 46 | end 47 | 48 | def build_heading (heading, body, count, accordion_base, group_base) 49 | href = "#{group_base}:nth-child(#{count + 1}) .#{body}.collapse" 50 | 51 | content_tag :div, class: "accordion-heading" do 52 | content_tag :a, heading, 53 | href: href, 54 | class: "accordion-toggle", 55 | :"data-toggle" => "collapse", 56 | :"data-parent" => accordion_base 57 | end 58 | end 59 | 60 | def build_body (body, block) 61 | content_tag :div, class: body + " collapse" do 62 | content_tag :div, class: "accordion-inner", &block 63 | end 64 | end 65 | 66 | class AccordionContext 67 | Group = Struct.new(:heading, :block) 68 | 69 | attr_reader :groups 70 | 71 | def initialize (renderer) 72 | @renderer = renderer 73 | @groups = [] 74 | end 75 | 76 | def group (heading, &block) 77 | @groups << Group.new(heading, block) 78 | end 79 | end 80 | 81 | class Selector 82 | def initialize 83 | @base = [] 84 | end 85 | 86 | def base (base, &block) 87 | @base << base 88 | block.call @base.join(" ") 89 | ensure 90 | @base.pop 91 | end 92 | end 93 | end 94 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/action_link_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class ActionLinkRenderer < AbstractLinkRenderer 3 | def initialize (template, *args, &block) 4 | super template, :link, *args, &block 5 | end 6 | 7 | def render 8 | append_class "act" 9 | 10 | if style = has_option?("style") 11 | unless style.to_s == "default" 12 | append_class "act-" + style.to_s 13 | end 14 | end 15 | 16 | super 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/button_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class ButtonRenderer < AbstractLinkRenderer 3 | include RailsBootstrapHelpers::Helpers::BaseHelper 4 | 5 | def render 6 | append_class "btn" 7 | 8 | if (style = has_option?("style")) && style != "default" 9 | append_class "btn-" + style.to_s 10 | end 11 | 12 | if size = has_option?("size") 13 | append_class "btn-" + size.to_s 14 | end 15 | 16 | if disabled = has_option?("disabled") 17 | append_class "disabled" 18 | end 19 | 20 | if icon = has_option?("icon") 21 | pos = has_option?("icon_position") 22 | icon_args = [icon, invert: has_option?("icon_invert")] 23 | 24 | if pos.to_s == "right" 25 | self.text = self.text.to_s + " " + icon(*icon_args) 26 | else 27 | self.text = icon(*icon_args) + " " + self.text.to_s 28 | end 29 | 30 | self.text = self.text.html_safe 31 | else 32 | strip_unused_options! 33 | end 34 | 35 | super 36 | end 37 | 38 | private 39 | 40 | def strip_unused_options! 41 | has_option?("icon_position") 42 | has_option?("icon_invert") 43 | end 44 | end 45 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/content_tag_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class ContentTagRenderer < Renderer 3 | def initialize (template, name, options, &block) 4 | super template 5 | 6 | @name = name 7 | @options = options 8 | @block = block 9 | 10 | @indentation_level = 0 11 | @default_indentation = 2 12 | @buffer = "" 13 | @context = Context.new(self) 14 | end 15 | 16 | def render 17 | content_tag_impl(name, options, &block) 18 | end 19 | 20 | private 21 | 22 | attr_reader :name 23 | attr_reader :content 24 | attr_reader :options 25 | attr_reader :block 26 | attr_reader :context 27 | attr_reader :buffer 28 | attr_reader :default_indentation 29 | 30 | def content_tag_impl (name, options = {}, &block) 31 | append tag(name, options, true) 32 | indent { context.instance_eval(&block) } 33 | append "" 34 | buffer.html_safe 35 | end 36 | 37 | def indent (&block) 38 | last_indentation_level = @indentation_level 39 | @indentation_level += default_indentation 40 | block.call 41 | ensure 42 | @indentation_level = last_indentation_level 43 | end 44 | 45 | def append (string) 46 | unless string.nil? 47 | buffer << " " * @indentation_level 48 | buffer << string 49 | buffer << "\n" 50 | end 51 | end 52 | 53 | class Context 54 | def initialize (renderer) 55 | @renderer = renderer 56 | end 57 | 58 | def bs_content_tag (name, options = {}, &block) 59 | @renderer.send :content_tag_impl, name, options, &block 60 | end 61 | 62 | def append (string) 63 | @renderer.send :append, string 64 | end 65 | end 66 | end 67 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/dropdown_button_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class DropdownButtonRenderer < Renderer 3 | def initialize (template, text, url_or_options = nil, options = {}, &block) 4 | super template 5 | @text = text 6 | @block = block 7 | 8 | extract_args!(url_or_options, options) 9 | end 10 | 11 | def render 12 | button_group do 13 | render_toggle_button + "\n" + 14 | render_menu 15 | end 16 | end 17 | 18 | private 19 | attr_reader :options 20 | attr_reader :url 21 | attr_reader :split 22 | attr_reader :block 23 | attr_reader :text 24 | 25 | def extract_args! (url_or_options, options) 26 | if url_or_options.is_a?(Hash) 27 | @options = url_or_options.dup 28 | @split = false 29 | elsif url_or_options.nil? 30 | @options = options.dup 31 | @split = false 32 | else 33 | @url = url_or_options 34 | @options = options.dup 35 | @split = true 36 | end 37 | end 38 | 39 | def render_toggle_button 40 | if split 41 | bs_button_to(text, url, options) << "\n" << 42 | render_toggle_button_impl(false) 43 | else 44 | render_toggle_button_impl(true) 45 | end 46 | end 47 | 48 | def toggle_options 49 | @toggle_options ||= begin 50 | opts = split ? {} : options.deep_dup 51 | data = opts[:data] || {} 52 | data[:toggle] = "dropdown" 53 | opts[:data] = data 54 | 55 | append_class!(opts, "dropdown-toggle") 56 | 57 | if (style = options[:style]) && style != "default" 58 | append_class!(opts, "btn-#{style}") 59 | end 60 | 61 | opts 62 | end 63 | end 64 | 65 | def render_caret 66 | content_tag :span, nil, class: "caret" 67 | end 68 | 69 | def render_toggle_button_impl (with_text) 70 | text = with_text ? text_with_caret : render_caret 71 | bs_button_tag text, nil, toggle_options 72 | end 73 | 74 | def text_with_caret 75 | @text_with_caret ||= begin 76 | escaped_text = ERB::Util.html_escape(text) 77 | (escaped_text + " " + render_caret).html_safe 78 | end 79 | end 80 | 81 | def render_menu 82 | content_tag :ul, class: "dropdown-menu" do 83 | template.capture(&block) 84 | end 85 | end 86 | end 87 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/iconic_icon_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class IconicIconRenderer < Renderer 3 | def initialize (template, icon, options) 4 | super template 5 | @icon = icon 6 | @options = options.dup 7 | end 8 | 9 | def render 10 | icon = ERB::Util.html_escape(@icon.to_s) 11 | append_class!(options, "iconic-#{icon}") 12 | append_style(:color, options.delete(:color)) 13 | 14 | handle_size 15 | handle_bs_style 16 | handle_action_style 17 | 18 | content_tag :i, "", bs_options(options) 19 | end 20 | 21 | private 22 | 23 | attr_reader :icon 24 | attr_reader :options 25 | 26 | def handle_bs_style 27 | if bs_style = options.delete(:bs_style) 28 | if bs_style.to_s == "muted" 29 | append_class!(options, :muted) 30 | else 31 | append_class!(options, "text-#{bs_style}") 32 | end 33 | end 34 | end 35 | 36 | def handle_action_style 37 | if action_style = options.delete(:action_style) 38 | append_class!(options, "act") 39 | 40 | unless action_style.to_s == "default" 41 | append_class!(options, "act-#{action_style}") 42 | end 43 | end 44 | end 45 | 46 | def handle_size 47 | if size = options.delete(:size) 48 | size = size.to_s 49 | 50 | if size.to_i > 0 51 | size << "px" 52 | end 53 | 54 | append_style("font-size", size) 55 | end 56 | end 57 | 58 | def append_style (key, value) 59 | if value 60 | style = options[:style].to_s 61 | 62 | if style.present? 63 | unless style.end_with?(";") 64 | style << ";" 65 | end 66 | 67 | style << " " 68 | end 69 | 70 | style << "#{key}: #{value};" 71 | options[:style] = style 72 | end 73 | end 74 | end 75 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class Renderer 3 | abstract :render 4 | attr_reader :template 5 | 6 | def initialize (template) 7 | @template = template 8 | end 9 | 10 | def method_missing (*args, &block) 11 | @template.send(*args, &block) 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/row_link_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class RowLinkRenderer < AbstractLinkRenderer 3 | def initialize (template, *args, &block) 4 | super template, :link, *args, &block 5 | end 6 | 7 | def render 8 | append_class "rowlink" 9 | super 10 | end 11 | end 12 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/renderers/tabbable_renderer.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers::Renderers 2 | class TabbableRenderer < Renderer 3 | def initialize (template, *args, &block) 4 | super template 5 | @args = args || [] 6 | @block = block 7 | 8 | @options = {} 9 | @tabs = [] 10 | @panes = [] 11 | 12 | @last_id = 0 13 | @ids = [] 14 | end 15 | 16 | def render 17 | befor_block 18 | block.call TabContext.new(self) 19 | after_block 20 | end 21 | 22 | def add_tab (text, options) 23 | @tabs << Tab.new(text, options) 24 | end 25 | 26 | def add_pane (block, options) 27 | @panes << Pane.new(block, options) 28 | end 29 | 30 | private 31 | 32 | attr_reader :args 33 | attr_reader :tabs 34 | attr_reader :panes 35 | attr_reader :block 36 | attr_reader :options 37 | attr_accessor :ids 38 | attr_accessor :fade 39 | 40 | def active_tabs? 41 | @active_tabs 42 | end 43 | 44 | def active_panes? 45 | @active_panes 46 | end 47 | 48 | def befor_block 49 | extract_options! 50 | collect_tabs 51 | end 52 | 53 | def after_block 54 | match_tabs_with_panes! 55 | identify_active_tabs 56 | identify_active_panes 57 | 58 | render_tabbable 59 | end 60 | 61 | def extract_options! 62 | if args.last.is_a?(Hash) 63 | @options = args.last.dup 64 | @fade = @options.delete(:fade) 65 | @tabs = args[0 ... -1] 66 | else 67 | @tabs = args 68 | end 69 | end 70 | 71 | def collect_tabs 72 | @tabs = @tabs.map { |text| Tab.new(text, {}) } 73 | end 74 | 75 | def identify_active_tabs 76 | @active_tabs = tabs.any? { |tab| tab.options.key?(:active) } 77 | end 78 | 79 | def identify_active_panes 80 | @active_panes = panes.any? { |pane| pane.options.key?(:active) } 81 | end 82 | 83 | def match_tabs_with_panes! 84 | tab_text = pluralize(tabs.length, "tab") 85 | pane_text = pluralize(panes.length, "pane") 86 | 87 | tab_was = tabs.length == 1 ? "was" : "were" 88 | pane_was = panes.length == 1 ? "was" : "were" 89 | 90 | if tabs.length != panes.length 91 | raise "Unmatching tabs and panes. #{tab_text} #{tab_was} given and #{pane_text} #{pane_was} given" 92 | end 93 | end 94 | 95 | def render_tabbable 96 | append_class!(options, "tabbable") 97 | append_class!(options, "tabbable-bordered") if options.delete(:bordered) 98 | 99 | if direction = options.delete(:direction) 100 | direction = class_for_direction(direction) 101 | append_class!(options, direction) 102 | end 103 | 104 | content_tag :div, options do 105 | render_tabs + "\n" + 106 | render_tab_content 107 | end 108 | end 109 | 110 | def render_tabs 111 | content_tag :ul, class: "nav nav-tabs" do 112 | content = process_tab(tabs.first, !active_tabs?) + "\n" 113 | content << tabs[1 .. -1].map { |tab| process_tab(tab) }.join("\n").html_safe 114 | end 115 | end 116 | 117 | def process_tab (tab, active = false) 118 | @ids << id_for_tab(tab.name) 119 | render_tab(ids.last, tab, active) 120 | end 121 | 122 | def render_tab_content 123 | content_tag :div, class: "tab-content" do 124 | content = render_tab_pane(ids.first, panes.first, !active_panes?) + "\n" 125 | 126 | panes = @panes[1 .. -1] 127 | ids = @ids[1 .. -1] 128 | 129 | content << panes.zip(ids).map { |pane, id| render_tab_pane(id, pane) }.join("\n").html_safe 130 | end 131 | end 132 | 133 | def render_tab (id, tab, active = false) 134 | if tab.options.key?(:active) 135 | active = tab.options[:active] 136 | end 137 | 138 | content_tag :li, class: ("active" if active) do 139 | link_to tab.name, "##{id}", data: { toggle: "tab" } 140 | end 141 | end 142 | 143 | def render_tab_pane (id, pane, active = false) 144 | if pane.options.key?(:active) 145 | active = pane.options[:active] 146 | end 147 | 148 | cls = "tab-pane" 149 | cls << " active" if active 150 | cls << " fade in" if fade 151 | content_tag :div, id: "#{id}", class: cls, &pane.block 152 | end 153 | 154 | def id_for_tab (name) 155 | id = "tab_pane_#{@last_id}_#{name.object_id}" 156 | @last_id += 1 157 | id 158 | end 159 | 160 | def class_for_direction (direction) 161 | direction = ERB::Util.html_escape(direction.to_s) 162 | direction == "top" ? "" : "tabs-#{direction}" 163 | end 164 | 165 | class TabContext 166 | def initialize (renderer) 167 | @renderer = renderer 168 | end 169 | 170 | def tab (text, options = {}) 171 | @renderer.add_tab(text, options) 172 | end 173 | 174 | def tab_pane (options = {}, &block) 175 | @renderer.add_pane(block, options) 176 | end 177 | 178 | private 179 | 180 | attr_reader :renderer 181 | end 182 | 183 | Tab = Struct.new(:name, :options) 184 | Pane = Struct.new(:block, :options) 185 | end 186 | end -------------------------------------------------------------------------------- /lib/rails-bootstrap-helpers/version.rb: -------------------------------------------------------------------------------- 1 | module RailsBootstrapHelpers 2 | VERSION = "0.1.0" 3 | end -------------------------------------------------------------------------------- /lib/tasks/bootstrap-rails-helpers_tasks.rake: -------------------------------------------------------------------------------- 1 | # desc "Explaining what the task does" 2 | # task :rails-bootstrap-helpers do 3 | # # Task goes here 4 | # end 5 | -------------------------------------------------------------------------------- /rails-bootstrap-helpers.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", __FILE__) 2 | 3 | require "rails-bootstrap-helpers/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "rails-bootstrap-helpers" 7 | s.version = RailsBootstrapHelpers::VERSION 8 | s.authors = ["Jacob Carlborg"] 9 | s.email = ["jacob.carlborg@tretti.se"] 10 | s.homepage = "https://github.com/Tretti/rails-bootstrap-helpers" 11 | s.summary = "A Rails plugin that contains helpers for Bootstrap" 12 | s.description = "A Rails plugin that contains helpers for Bootstrap" 13 | s.license = "MIT" 14 | 15 | s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.md"] 16 | s.test_files = Dir["spec/**/*"] 17 | 18 | s.add_dependency 'rails', '>= 3.2.11' 19 | 20 | s.add_development_dependency "guard-rspec" 21 | s.add_development_dependency "guard-spork" 22 | s.add_development_dependency "pry-doc" 23 | s.add_development_dependency "pry-exception_explorer" 24 | s.add_development_dependency "pry-rails" 25 | s.add_development_dependency "pry-stack_explorer" 26 | s.add_development_dependency "rspec-rails" 27 | s.add_development_dependency "spork" 28 | s.add_development_dependency "sqlite3" 29 | end 30 | -------------------------------------------------------------------------------- /spec/dummy/README.rdoc: -------------------------------------------------------------------------------- 1 | == Welcome to Rails 2 | 3 | Rails is a web-application framework that includes everything needed to create 4 | database-backed web applications according to the Model-View-Control pattern. 5 | 6 | This pattern splits the view (also called the presentation) into "dumb" 7 | templates that are primarily responsible for inserting pre-built data in between 8 | HTML tags. The model contains the "smart" domain objects (such as Account, 9 | Product, Person, Post) that holds all the business logic and knows how to 10 | persist themselves to a database. The controller handles the incoming requests 11 | (such as Save New Account, Update Product, Show Post) by manipulating the model 12 | and directing data to the view. 13 | 14 | In Rails, the model is handled by what's called an object-relational mapping 15 | layer entitled Active Record. This layer allows you to present the data from 16 | database rows as objects and embellish these data objects with business logic 17 | methods. You can read more about Active Record in 18 | link:files/vendor/rails/activerecord/README.html. 19 | 20 | The controller and view are handled by the Action Pack, which handles both 21 | layers by its two parts: Action View and Action Controller. These two layers 22 | are bundled in a single package due to their heavy interdependence. This is 23 | unlike the relationship between the Active Record and Action Pack that is much 24 | more separate. Each of these packages can be used independently outside of 25 | Rails. You can read more about Action Pack in 26 | link:files/vendor/rails/actionpack/README.html. 27 | 28 | 29 | == Getting Started 30 | 31 | 1. At the command prompt, create a new Rails application: 32 | rails new myapp (where myapp is the application name) 33 | 34 | 2. Change directory to myapp and start the web server: 35 | cd myapp; rails server (run with --help for options) 36 | 37 | 3. Go to http://localhost:3000/ and you'll see: 38 | "Welcome aboard: You're riding Ruby on Rails!" 39 | 40 | 4. Follow the guidelines to start developing your application. You can find 41 | the following resources handy: 42 | 43 | * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html 44 | * Ruby on Rails Tutorial Book: http://www.railstutorial.org/ 45 | 46 | 47 | == Debugging Rails 48 | 49 | Sometimes your application goes wrong. Fortunately there are a lot of tools that 50 | will help you debug it and get it back on the rails. 51 | 52 | First area to check is the application log files. Have "tail -f" commands 53 | running on the server.log and development.log. Rails will automatically display 54 | debugging and runtime information to these files. Debugging info will also be 55 | shown in the browser on requests from 127.0.0.1. 56 | 57 | You can also log your own messages directly into the log file from your code 58 | using the Ruby logger class from inside your controllers. Example: 59 | 60 | class WeblogController < ActionController::Base 61 | def destroy 62 | @weblog = Weblog.find(params[:id]) 63 | @weblog.destroy 64 | logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") 65 | end 66 | end 67 | 68 | The result will be a message in your log file along the lines of: 69 | 70 | Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! 71 | 72 | More information on how to use the logger is at http://www.ruby-doc.org/core/ 73 | 74 | Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are 75 | several books available online as well: 76 | 77 | * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) 78 | * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) 79 | 80 | These two books will bring you up to speed on the Ruby language and also on 81 | programming in general. 82 | 83 | 84 | == Debugger 85 | 86 | Debugger support is available through the debugger command when you start your 87 | Mongrel or WEBrick server with --debugger. This means that you can break out of 88 | execution at any point in the code, investigate and change the model, and then, 89 | resume execution! You need to install ruby-debug to run the server in debugging 90 | mode. With gems, use sudo gem install ruby-debug. Example: 91 | 92 | class WeblogController < ActionController::Base 93 | def index 94 | @posts = Post.all 95 | debugger 96 | end 97 | end 98 | 99 | So the controller will accept the action, run the first line, then present you 100 | with a IRB prompt in the server window. Here you can do things like: 101 | 102 | >> @posts.inspect 103 | => "[#nil, "body"=>nil, "id"=>"1"}>, 105 | #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" 107 | >> @posts.first.title = "hello from a debugger" 108 | => "hello from a debugger" 109 | 110 | ...and even better, you can examine how your runtime objects actually work: 111 | 112 | >> f = @posts.first 113 | => #nil, "body"=>nil, "id"=>"1"}> 114 | >> f. 115 | Display all 152 possibilities? (y or n) 116 | 117 | Finally, when you're ready to resume execution, you can enter "cont". 118 | 119 | 120 | == Console 121 | 122 | The console is a Ruby shell, which allows you to interact with your 123 | application's domain model. Here you'll have all parts of the application 124 | configured, just like it is when the application is running. You can inspect 125 | domain models, change values, and save to the database. Starting the script 126 | without arguments will launch it in the development environment. 127 | 128 | To start the console, run rails console from the application 129 | directory. 130 | 131 | Options: 132 | 133 | * Passing the -s, --sandbox argument will rollback any modifications 134 | made to the database. 135 | * Passing an environment name as an argument will load the corresponding 136 | environment. Example: rails console production. 137 | 138 | To reload your controllers and models after launching the console run 139 | reload! 140 | 141 | More information about irb can be found at: 142 | link:http://www.rubycentral.org/pickaxe/irb.html 143 | 144 | 145 | == dbconsole 146 | 147 | You can go to the command line of your database directly through rails 148 | dbconsole. You would be connected to the database with the credentials 149 | defined in database.yml. Starting the script without arguments will connect you 150 | to the development database. Passing an argument will connect you to a different 151 | database, like rails dbconsole production. Currently works for MySQL, 152 | PostgreSQL and SQLite 3. 153 | 154 | == Description of Contents 155 | 156 | The default directory structure of a generated Ruby on Rails application: 157 | 158 | |-- app 159 | | |-- assets 160 | | | |-- images 161 | | | |-- javascripts 162 | | | `-- stylesheets 163 | | |-- controllers 164 | | |-- helpers 165 | | |-- mailers 166 | | |-- models 167 | | `-- views 168 | | `-- layouts 169 | |-- config 170 | | |-- environments 171 | | |-- initializers 172 | | `-- locales 173 | |-- db 174 | |-- doc 175 | |-- lib 176 | | |-- assets 177 | | `-- tasks 178 | |-- log 179 | |-- public 180 | |-- script 181 | |-- test 182 | | |-- fixtures 183 | | |-- functional 184 | | |-- integration 185 | | |-- performance 186 | | `-- unit 187 | |-- tmp 188 | | `-- cache 189 | | `-- assets 190 | `-- vendor 191 | |-- assets 192 | | |-- javascripts 193 | | `-- stylesheets 194 | `-- plugins 195 | 196 | app 197 | Holds all the code that's specific to this particular application. 198 | 199 | app/assets 200 | Contains subdirectories for images, stylesheets, and JavaScript files. 201 | 202 | app/controllers 203 | Holds controllers that should be named like weblogs_controller.rb for 204 | automated URL mapping. All controllers should descend from 205 | ApplicationController which itself descends from ActionController::Base. 206 | 207 | app/models 208 | Holds models that should be named like post.rb. Models descend from 209 | ActiveRecord::Base by default. 210 | 211 | app/views 212 | Holds the template files for the view that should be named like 213 | weblogs/index.html.erb for the WeblogsController#index action. All views use 214 | eRuby syntax by default. 215 | 216 | app/views/layouts 217 | Holds the template files for layouts to be used with views. This models the 218 | common header/footer method of wrapping views. In your views, define a layout 219 | using the layout :default and create a file named default.html.erb. 220 | Inside default.html.erb, call <% yield %> to render the view using this 221 | layout. 222 | 223 | app/helpers 224 | Holds view helpers that should be named like weblogs_helper.rb. These are 225 | generated for you automatically when using generators for controllers. 226 | Helpers can be used to wrap functionality for your views into methods. 227 | 228 | config 229 | Configuration files for the Rails environment, the routing map, the database, 230 | and other dependencies. 231 | 232 | db 233 | Contains the database schema in schema.rb. db/migrate contains all the 234 | sequence of Migrations for your schema. 235 | 236 | doc 237 | This directory is where your application documentation will be stored when 238 | generated using rake doc:app 239 | 240 | lib 241 | Application specific libraries. Basically, any kind of custom code that 242 | doesn't belong under controllers, models, or helpers. This directory is in 243 | the load path. 244 | 245 | public 246 | The directory available for the web server. Also contains the dispatchers and the 247 | default HTML files. This should be set as the DOCUMENT_ROOT of your web 248 | server. 249 | 250 | script 251 | Helper scripts for automation and generation. 252 | 253 | test 254 | Unit and functional tests along with fixtures. When using the rails generate 255 | command, template test files will be generated for you and placed in this 256 | directory. 257 | 258 | vendor 259 | External libraries that the application depends on. Also includes the plugins 260 | subdirectory. If the app has frozen rails, those gems also go here, under 261 | vendor/rails/. This directory is in the load path. 262 | -------------------------------------------------------------------------------- /spec/dummy/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Dummy::Application.load_tasks 8 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require_tree . 16 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /spec/dummy/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/dummy/app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tretti/rails-bootstrap-helpers/98bc0458f864be3f21f1a53f1a265b15f9e0e883/spec/dummy/app/mailers/.gitkeep -------------------------------------------------------------------------------- /spec/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tretti/rails-bootstrap-helpers/98bc0458f864be3f21f1a53f1a265b15f9e0e883/spec/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /spec/dummy/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dummy 5 | <%= stylesheet_link_tag "application", :media => "all" %> 6 | <%= javascript_include_tag "application" %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /spec/dummy/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Dummy::Application 5 | -------------------------------------------------------------------------------- /spec/dummy/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | Bundler.require(*Rails.groups) 6 | require "rails-bootstrap-helpers" 7 | 8 | module Dummy 9 | class Application < Rails::Application 10 | # Settings in config/environments/* take precedence over those specified here. 11 | # Application configuration should go into files in config/initializers 12 | # -- all .rb files in that directory are automatically loaded. 13 | 14 | # Custom directories with classes and modules you want to be autoloadable. 15 | # config.autoload_paths += %W(#{config.root}/extras) 16 | 17 | # Only load the plugins named here, in the order given (default is alphabetical). 18 | # :all can be used as a placeholder for all plugins not explicitly named. 19 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 20 | 21 | # Activate observers that should always be running. 22 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 23 | 24 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 25 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 26 | # config.time_zone = 'Central Time (US & Canada)' 27 | 28 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 29 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 30 | # config.i18n.default_locale = :de 31 | 32 | # Configure the default encoding used in templates for Ruby 1.9. 33 | config.encoding = "utf-8" 34 | 35 | # Configure sensitive parameters which will be filtered from the log file. 36 | config.filter_parameters += [:password] 37 | 38 | # Enable escaping HTML in JSON. 39 | config.active_support.escape_html_entities_in_json = true 40 | 41 | # Use SQL instead of Active Record's schema dumper when creating the database. 42 | # This is necessary if your schema can't be completely dumped by the schema dumper, 43 | # like if you have constraints or database-specific column types 44 | # config.active_record.schema_format = :sql 45 | 46 | # Enforce whitelist mode for mass assignment. 47 | # This will create an empty whitelist of attributes available for mass-assignment for all models 48 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible 49 | # parameters by using an attr_accessible or attr_protected declaration. 50 | config.active_record.whitelist_attributes = true 51 | 52 | # Enable the asset pipeline 53 | config.assets.enabled = true 54 | 55 | # Version of your assets, change this if you want to expire all your assets 56 | config.assets.version = '1.0' 57 | end 58 | end 59 | 60 | -------------------------------------------------------------------------------- /spec/dummy/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | gemfile = File.expand_path('../../../../Gemfile', __FILE__) 3 | 4 | if File.exist?(gemfile) 5 | ENV['BUNDLE_GEMFILE'] = gemfile 6 | require 'bundler' 7 | Bundler.setup 8 | end 9 | 10 | $:.unshift File.expand_path('../../../../lib', __FILE__) -------------------------------------------------------------------------------- /spec/dummy/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /spec/dummy/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Dummy::Application.initialize! 6 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Raise exception on mass assignment protection for Active Record models 26 | config.active_record.mass_assignment_sanitizer = :strict 27 | 28 | # Log the query plan for queries taking more than this (works 29 | # with SQLite, MySQL, and PostgreSQL) 30 | config.active_record.auto_explain_threshold_in_seconds = 0.5 31 | 32 | # Do not compress assets 33 | config.assets.compress = false 34 | 35 | # Expands the lines which load the assets 36 | config.assets.debug = true 37 | end 38 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to nil and saved in location specified by config.assets.prefix 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Prepend all log lines with the following tags 37 | # config.log_tags = [ :subdomain, :uuid ] 38 | 39 | # Use a different logger for distributed setups 40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 41 | 42 | # Use a different cache store in production 43 | # config.cache_store = :mem_cache_store 44 | 45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 46 | # config.action_controller.asset_host = "http://assets.example.com" 47 | 48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 49 | # config.assets.precompile += %w( search.js ) 50 | 51 | # Disable delivery errors, bad email addresses will be ignored 52 | # config.action_mailer.raise_delivery_errors = false 53 | 54 | # Enable threaded mode 55 | # config.threadsafe! 56 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 58 | # the I18n.default_locale when a translation can not be found) 59 | config.i18n.fallbacks = true 60 | 61 | # Send deprecation notices to registered listeners 62 | config.active_support.deprecation = :notify 63 | 64 | # Log the query plan for queries taking more than this (works 65 | # with SQLite, MySQL, and PostgreSQL) 66 | # config.active_record.auto_explain_threshold_in_seconds = 0.5 67 | end 68 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | end 38 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Dummy::Application.config.secret_token = '4d1f9a7946f979c24d8bd58214f498094ca9eea099ac67c75c99f0d2caf1d87c36b03ae78e1b7e9ea534703e9bb099fd3f51afcb2c68971cbc6cc3351557a3c4' 8 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Dummy::Application.config.session_store :cookie_store, key: '_dummy_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Dummy::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /spec/dummy/config/routes.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.routes.draw do 2 | # The priority is based upon order of creation: 3 | # first created -> highest priority. 4 | 5 | # Sample of regular route: 6 | # match 'products/:id' => 'catalog#view' 7 | # Keep in mind you can assign values other than :controller and :action 8 | 9 | # Sample of named route: 10 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase 11 | # This route can be invoked with purchase_url(:id => product.id) 12 | 13 | # Sample resource route (maps HTTP verbs to controller actions automatically): 14 | # resources :products 15 | 16 | # Sample resource route with options: 17 | # resources :products do 18 | # member do 19 | # get 'short' 20 | # post 'toggle' 21 | # end 22 | # 23 | # collection do 24 | # get 'sold' 25 | # end 26 | # end 27 | 28 | # Sample resource route with sub-resources: 29 | # resources :products do 30 | # resources :comments, :sales 31 | # resource :seller 32 | # end 33 | 34 | # Sample resource route with more complex sub-resources 35 | # resources :products do 36 | # resources :comments 37 | # resources :sales do 38 | # get 'recent', :on => :collection 39 | # end 40 | # end 41 | 42 | # Sample resource route within a namespace: 43 | # namespace :admin do 44 | # # Directs /admin/products/* to Admin::ProductsController 45 | # # (app/controllers/admin/products_controller.rb) 46 | # resources :products 47 | # end 48 | 49 | # You can have the root of your site routed with "root" 50 | # just remember to delete public/index.html. 51 | # root :to => 'welcome#index' 52 | 53 | # See how all your routes lay out with "rake routes" 54 | 55 | # This is a legacy wild controller route that's not recommended for RESTful applications. 56 | # Note: This route will make all actions in every controller accessible via GET requests. 57 | # match ':controller(/:action(/:id))(.:format)' 58 | end 59 | -------------------------------------------------------------------------------- /spec/dummy/lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tretti/rails-bootstrap-helpers/98bc0458f864be3f21f1a53f1a265b15f9e0e883/spec/dummy/lib/assets/.gitkeep -------------------------------------------------------------------------------- /spec/dummy/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tretti/rails-bootstrap-helpers/98bc0458f864be3f21f1a53f1a265b15f9e0e883/spec/dummy/log/.gitkeep -------------------------------------------------------------------------------- /spec/dummy/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    The page you were looking for doesn't exist.

    23 |

    You may have mistyped the address or the page may have moved.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /spec/dummy/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    The change you wanted was rejected.

    23 |

    Maybe you tried to change something you didn't have access to.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /spec/dummy/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    We're sorry, but something went wrong.

    23 |
    24 | 25 | 26 | -------------------------------------------------------------------------------- /spec/dummy/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tretti/rails-bootstrap-helpers/98bc0458f864be3f21f1a53f1a265b15f9e0e883/spec/dummy/public/favicon.ico -------------------------------------------------------------------------------- /spec/dummy/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /spec/dummy/spec: -------------------------------------------------------------------------------- 1 | ../../spec -------------------------------------------------------------------------------- /spec/helpers/accordion_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::AccordionHelper do 4 | describe "accordion" do 5 | it "should render an accordion" do 6 | expected_html = <<-eos 7 |
    8 |
    9 |
    10 | 11 | bar 12 | 13 |
    14 | 15 |
    16 |
    17 | content 18 |
    19 |
    20 |
    21 |
    22 | eos 23 | 24 | expected_html = expected_html.gsub(/^\s+/, "").gsub("\n", "") 25 | 26 | html = accordion "foo" do |a| 27 | a.group "bar" do 28 | "content" 29 | end 30 | end 31 | 32 | html.should == expected_html 33 | end 34 | end 35 | end -------------------------------------------------------------------------------- /spec/helpers/alert_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::AlertHelper do 4 | describe "bs_alert" do 5 | it { should render_bs_alert("foo") } 6 | 7 | context "with type" do 8 | it { should render_bs_alert("foo").with_style(:error) } 9 | it { should render_bs_alert("foo").with_style(:success) } 10 | it { should render_bs_alert("foo").with_style(:info) } 11 | it { should render_bs_alert("foo").with_style(:warning) } 12 | it { should render_bs_alert("foo").with_style(:default) } 13 | it { should render_bs_alert("foo").with_style(:notice).as_class(:success) } 14 | 15 | context "custom" do 16 | it { should render_bs_alert("foo").with_style(:bar) } 17 | end 18 | 19 | context "deprecated options" do 20 | it { should render_bs_alert("foo").with_type(:error) } 21 | end 22 | end 23 | 24 | context "as block" do 25 | it { should render_bs_alert("foo").as_block(true) } 26 | end 27 | end 28 | end -------------------------------------------------------------------------------- /spec/helpers/base_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::BaseHelper do 4 | describe "icon" do 5 | it { should render_icon(:edit) } 6 | it { should render_icon("remove") } 7 | 8 | context "with invert icon" do 9 | it { should render_icon(:edit).inverted(true) } 10 | it { should render_icon("remove").inverted(true) } 11 | end 12 | 13 | context "custom icons" do 14 | it { should render_icon(:foo) } 15 | it { should render_icon("bar") } 16 | end 17 | 18 | context "with class" do 19 | it { should render_icon(:edit).with_class("bar") } 20 | it { should render_icon("remove").with_class("bar") } 21 | it { should render_icon(:edit).inverted(true).with_class("bar") } 22 | end 23 | end 24 | 25 | describe "iconic_icon" do 26 | it { should render_iconic_icon(:check) } 27 | it { should render_iconic_icon("clock") } 28 | 29 | context "custom icons" do 30 | it { should render_iconic_icon(:foo) } 31 | it { should render_iconic_icon("bar") } 32 | end 33 | 34 | context "with color" do 35 | it { should render_iconic_icon(:check).with_color(:blue) } 36 | it { should render_iconic_icon(:check).with_color('#fff') } 37 | end 38 | 39 | context "with size" do 40 | it { should render_iconic_icon(:check).with_size(10) } 41 | it { should render_iconic_icon(:check).with_size("10") } 42 | it { should render_iconic_icon(:check).with_size("10px") } 43 | it { should render_iconic_icon(:check).with_size("1em") } 44 | end 45 | 46 | context "with Bootstrap style" do 47 | it { should render_iconic_icon(:check).with_bs_style(:muted) } 48 | it { should render_iconic_icon(:check).with_bs_style(:success) } 49 | it { should render_iconic_icon(:check).with_bs_style(:foo) } 50 | end 51 | 52 | context "with action link style" do 53 | it { should render_iconic_icon(:check).with_action_style(:default) } 54 | it { should render_iconic_icon(:check).with_action_style(:success) } 55 | it { should render_iconic_icon(:check).with_action_style(:foo) } 56 | end 57 | 58 | context "with tooltip" do 59 | it { should render_iconic_icon(:check).with_tooltip("foo") } 60 | end 61 | end 62 | end -------------------------------------------------------------------------------- /spec/helpers/button_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::ButtonHelper do 4 | let(:html_attributes) do 5 | attributes.map{ |k, v| "#{k}=\"#{v}\"" }.join(" ") 6 | end 7 | 8 | let(:html) { "foo" } 9 | 10 | describe "bs_button_to" do 11 | context "with url" do 12 | it { should render_bs_button_to("foo").to("bar") } 13 | end 14 | 15 | context "with style" do 16 | it { should render_bs_button_to("foo") } 17 | it { should render_bs_button_to("foo").with_style(:default) } 18 | it { should render_bs_button_to("foo").with_style(:primary) } 19 | it { should render_bs_button_to("foo").with_style(:info) } 20 | it { should render_bs_button_to("foo").with_style(:success) } 21 | it { should render_bs_button_to("foo").with_style(:warning) } 22 | it { should render_bs_button_to("foo").with_style(:danger) } 23 | it { should render_bs_button_to("foo").with_style(:inverse) } 24 | it { should render_bs_button_to("foo").with_style(:link) } 25 | end 26 | 27 | context "with size" do 28 | it { should render_bs_button_to("foo").with_size(:default) } 29 | it { should render_bs_button_to("foo").with_size(:large) } 30 | it { should render_bs_button_to("foo").with_size(:small) } 31 | it { should render_bs_button_to("foo").with_size(:mini) } 32 | end 33 | 34 | context "with icon" do 35 | it { should render_bs_button_to("foo").with_icon(:ok) } 36 | it { should render_bs_button_to("foo").with_icon(:edit) } 37 | it { should render_bs_button_to("foo").with_icon(:none) } 38 | end 39 | 40 | context "with inverted icon" do 41 | it { should render_bs_button_to("foo").with_icon(:ok).with_icon_inverted(true) } 42 | it { should render_bs_button_to("foo").with_icon(:edit).with_icon_inverted(true) } 43 | end 44 | 45 | context "with icon position" do 46 | it { should render_bs_button_to("foo").with_icon_position(:default) } 47 | it { should render_bs_button_to("foo").with_icon_position(:left) } 48 | it { should render_bs_button_to("foo").with_icon_position(:right) } 49 | end 50 | 51 | context "with custom class attribute" do 52 | it { should render_bs_button_to("foo").with_class("bar") } 53 | end 54 | 55 | context "with tooltip" do 56 | it { should render_bs_button_to("foo").with_tooltip("asd") } 57 | it { should render_bs_button_to("foo").with_tooltip("asd").with_tooltip_position(:left) } 58 | end 59 | end 60 | 61 | describe "bs_inline_button_to" do 62 | it { should render_inline_button_to("foo", "edit") } 63 | 64 | context "with size" do 65 | it { should render_inline_button_to("foo", "edit").with_size(:large) } 66 | it { should render_inline_button_to("foo", "edit").with_size(:small) } 67 | it { should render_inline_button_to("foo", "edit").with_size(:mini) } 68 | end 69 | end 70 | 71 | describe "bs_popover_button" do 72 | let(:attributes) do 73 | { 74 | href: '#', 75 | class: "btn", 76 | :"data-content" => "bar", 77 | :"data-placement" => "bottom", 78 | :"data-toggle" => "popover" 79 | } 80 | end 81 | 82 | it "should render a button with a popover" do 83 | helper.bs_popover_button("foo", "bar").should == html 84 | end 85 | 86 | context "render popover using block" do 87 | it "should render a button with a popover" do 88 | helper.bs_popover_button("foo") { "bar" }.should == html 89 | end 90 | end 91 | 92 | context "with custom placement" do 93 | it "should render a button with a popover" do 94 | attributes[:"data-placement"] = "top" 95 | helper.bs_popover_button("foo", "bar", position: "top").should == html 96 | end 97 | end 98 | 99 | context "with deprecated options" do 100 | it "should render a button with a popover" do 101 | attributes[:"data-placement"] = "top" 102 | helper.bs_popover_button("foo", "bar", placement: "top").should == html 103 | end 104 | end 105 | end 106 | 107 | describe "bs_collapsible_button" do 108 | let(:attributes) do 109 | { 110 | class: "btn", 111 | :"data-target" => "bar", 112 | :"data-toggle" => "collapse", 113 | name: "button", 114 | type: "button" 115 | } 116 | end 117 | 118 | let(:html) { "" } 119 | 120 | it "should render a button with a collapsible" do 121 | helper.bs_collapsible_button("foo", "bar").should == html 122 | end 123 | 124 | context "with style" do 125 | it "should render a collapsible button with the proper style" do 126 | attributes[:class] = "btn btn-primary" 127 | helper.bs_collapsible_button("foo", "bar", style: "primary").should == html 128 | end 129 | end 130 | end 131 | 132 | describe "button_group" do 133 | it "should render a button group" do 134 | content = helper.button_group do 135 | "asd" 136 | end 137 | 138 | content.should == '
    asd
    ' 139 | end 140 | 141 | context "vertical button group" do 142 | it "should render a vertical button group" do 143 | content = helper.button_group vertical: true do 144 | "asd" 145 | end 146 | 147 | content.should == '
    asd
    ' 148 | end 149 | end 150 | 151 | context "toolbar button group" do 152 | it "should render a toolbar button group" do 153 | content = helper.button_group toolbar: true do 154 | "asd" 155 | end 156 | 157 | content.should == '
    asd
    ' 158 | end 159 | end 160 | end 161 | 162 | describe "bs_dropdown_button_to" do 163 | let(:expected_html) do 164 | html = <<-eos 165 |
    166 | 169 | 173 |
    174 | eos 175 | 176 | strip_expected(html) 177 | end 178 | 179 | it "should render a dropdown button" do 180 | html = bs_dropdown_button_to "foo" do 181 | content_tag(:li, link_to("bar", "http://www.google.com")) + 182 | content_tag(:li, link_to("baz", "http://www.wikipedia.org")) 183 | end 184 | 185 | strip(html).should == expected_html 186 | end 187 | 188 | context "with link" do 189 | let(:expected_html) do 190 | html = <<-eos 191 |
    192 | foo 193 | 196 | 200 |
    201 | eos 202 | 203 | strip_expected(html) 204 | end 205 | 206 | it "should render a split dropdown button" do 207 | html = bs_dropdown_button_to "foo", "https://github.com" do 208 | content_tag(:li, link_to("bar", "http://www.google.com")) + 209 | content_tag(:li, link_to("baz", "http://www.wikipedia.org")) 210 | end 211 | 212 | strip(html).should == expected_html 213 | end 214 | end 215 | 216 | context "with icon" do 217 | let(:expected_html) do 218 | html = <<-eos 219 |
    220 | 223 | 227 |
    228 | eos 229 | 230 | strip_expected(html) 231 | end 232 | 233 | it "should render a dropdown button with an icon" do 234 | html = bs_dropdown_button_to "foo", icon: "search" do 235 | content_tag(:li, link_to("bar", "http://www.google.com")) + 236 | content_tag(:li, link_to("baz", "http://www.wikipedia.org")) 237 | end 238 | 239 | strip(html).should == expected_html 240 | end 241 | end 242 | 243 | context "with link and icon" do 244 | let(:expected_html) do 245 | html = <<-eos 246 |
    247 | foo 248 | 251 | 255 |
    256 | eos 257 | 258 | strip_expected(html) 259 | end 260 | 261 | it "should render a split dropdown button with an icon" do 262 | html = bs_dropdown_button_to "foo", "https://github.com", icon: "search" do 263 | content_tag(:li, link_to("bar", "http://www.google.com")) + 264 | content_tag(:li, link_to("baz", "http://www.wikipedia.org")) 265 | end 266 | 267 | strip(html).should == expected_html 268 | end 269 | end 270 | 271 | context "with link and style" do 272 | let(:expected_html) do 273 | html = <<-eos 274 |
    275 | foo 276 | 279 | 283 |
    284 | eos 285 | 286 | strip_expected(html) 287 | end 288 | 289 | it "should render a split dropdown button with the success style" do 290 | html = bs_dropdown_button_to "foo", "https://github.com", style: "success" do 291 | content_tag(:li, link_to("bar", "http://www.google.com")) + 292 | content_tag(:li, link_to("baz", "http://www.wikipedia.org")) 293 | end 294 | 295 | strip(html).should == expected_html 296 | end 297 | end 298 | end 299 | end -------------------------------------------------------------------------------- /spec/helpers/form_tag_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::FormTagHelper do 4 | describe "bs_button_tag" do 5 | it { should render_bs_button_tag("foo", :submit) } 6 | it { should render_bs_button_tag("bar", :reset) } 7 | 8 | context "with style" do 9 | it { should render_bs_button_tag("foo", :submit).with_style(:default) } 10 | it { should render_bs_button_tag("foo", :submit).with_style(:primary) } 11 | it { should render_bs_button_tag("foo", :submit).with_style(:info) } 12 | it { should render_bs_button_tag("foo", :submit).with_style(:success) } 13 | it { should render_bs_button_tag("foo", :submit).with_style(:warning) } 14 | it { should render_bs_button_tag("foo", :submit).with_style(:danger) } 15 | it { should render_bs_button_tag("foo", :submit).with_style(:inverse) } 16 | it { should render_bs_button_tag("foo", :submit).with_style(:link) } 17 | end 18 | 19 | context "with size" do 20 | it { should render_bs_button_tag("foo", :submit).with_size(:default) } 21 | it { should render_bs_button_tag("foo", :submit).with_size(:large) } 22 | it { should render_bs_button_tag("foo", :submit).with_size(:small) } 23 | it { should render_bs_button_tag("foo", :submit).with_size(:mini) } 24 | end 25 | 26 | context "with icon" do 27 | it { should render_bs_button_tag("foo", :submit).with_icon(:ok) } 28 | it { should render_bs_button_tag("foo", :submit).with_icon(:edit) } 29 | it { should render_bs_button_tag("foo", :submit).with_icon(:none) } 30 | end 31 | 32 | context "with inverted icon" do 33 | it { should render_bs_button_tag("foo", :submit).with_icon(:ok).with_icon_inverted(true) } 34 | it { should render_bs_button_tag("foo", :submit).with_icon(:edit).with_icon_inverted(true) } 35 | end 36 | 37 | context "with icon position" do 38 | it { should render_bs_button_tag("foo", :submit).with_icon_position(:default) } 39 | it { should render_bs_button_tag("foo", :submit).with_icon_position(:left) } 40 | it { should render_bs_button_tag("foo", :submit).with_icon_position(:right) } 41 | end 42 | 43 | context "with tooltip" do 44 | it { should render_bs_button_tag("foo", :submit).with_tooltip("asd") } 45 | it { should render_bs_button_tag("foo", :submit).with_tooltip("asd").with_tooltip_position(:left) } 46 | end 47 | end 48 | 49 | describe "bs_submit_tag" do 50 | it { should render_bs_submit_tag("foo") } 51 | 52 | context "with style" do 53 | it { should render_bs_submit_tag("foo").with_style(:default) } 54 | it { should render_bs_submit_tag("foo").with_style(:primary) } 55 | it { should render_bs_submit_tag("foo").with_style(:info) } 56 | it { should render_bs_submit_tag("foo").with_style(:success) } 57 | it { should render_bs_submit_tag("foo").with_style(:warning) } 58 | it { should render_bs_submit_tag("foo").with_style(:danger) } 59 | it { should render_bs_submit_tag("foo").with_style(:inverse) } 60 | it { should render_bs_submit_tag("foo").with_style(:link) } 61 | end 62 | 63 | context "with size" do 64 | it { should render_bs_submit_tag("foo").with_size(:default) } 65 | it { should render_bs_submit_tag("foo").with_size(:large) } 66 | it { should render_bs_submit_tag("foo").with_size(:small) } 67 | it { should render_bs_submit_tag("foo").with_size(:mini) } 68 | end 69 | end 70 | end -------------------------------------------------------------------------------- /spec/helpers/label_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::LabelHelper do 4 | describe "bs_label" do 5 | it { should render_bs_label("foo") } 6 | it { should render_bs_label("foo").with_style(:success) } 7 | it { should render_bs_label("foo").with_style(:warning) } 8 | it { should render_bs_label("foo").with_style(:important) } 9 | it { should render_bs_label("foo").with_style(:info) } 10 | it { should render_bs_label("foo").with_style(:inverse) } 11 | 12 | context "custom statuses" do 13 | it { should render_bs_label("foo").with_style(:active).as_class("success") } 14 | it { should render_bs_label("foo").with_style(:inactive).as_class("default") } 15 | it { should render_bs_label("foo").with_style(:error).as_class("important") } 16 | end 17 | 18 | context "with tooltip" do 19 | it { should render_bs_label("foo").with_tooltip("bar") } 20 | it { should render_bs_label("foo").with_tooltip("bar").with_tooltip_position(:left) } 21 | end 22 | end 23 | end -------------------------------------------------------------------------------- /spec/helpers/navigation_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::NavigationHelper do 4 | let(:foo_tab_text) { "foo" } 5 | let(:bar_tab_text) { "bar" } 6 | 7 | let(:foo_tab_id) { "tab_pane_0_#{foo_tab_text.object_id}" } 8 | let(:bar_tab_id) { "tab_pane_1_#{bar_tab_text.object_id}" } 9 | 10 | let(:block) do 11 | lambda do |bar| 12 | bar.tab bar_tab_text 13 | 14 | bar.tab_pane do 15 | "foo content" 16 | end 17 | 18 | bar.tab_pane do 19 | "bar content" 20 | end 21 | end 22 | end 23 | 24 | let(:html_class) { "tabbable" } 25 | let(:expected_html) do 26 | html = <<-eos 27 |
    28 | 32 | 33 |
    34 |
    35 | foo content 36 |
    37 | 38 |
    39 | bar content 40 |
    41 |
    42 |
    43 | eos 44 | 45 | strip_expected(html) 46 | end 47 | 48 | describe "tabbable" do 49 | it "should render an tabbable navigation" do 50 | html = tabbable(foo_tab_text, &block) 51 | strip(html).should == expected_html 52 | end 53 | 54 | context "unmatching tabs and panes" do 55 | let(:errro_message) { "Unmatching tabs and panes. 0 tabs were given and 1 pane was given" } 56 | 57 | it "should raise an unmatching error" do 58 | ->() { tabbable { |bar| bar.tab_pane { "foo" } } }.should raise_error(errro_message) 59 | end 60 | end 61 | 62 | context "options" do 63 | context "with bordered style" do 64 | let(:html_class) { "tabbable tabbable-bordered" } 65 | 66 | it "should render a tabbable navigation with a border" do 67 | html = tabbable(foo_tab_text, bordered: true, &block) 68 | strip(html).should == expected_html 69 | end 70 | end 71 | 72 | context "with fade" do 73 | let(:expected_html) do 74 | html = <<-eos 75 |
    76 | 80 | 81 |
    82 |
    83 | foo content 84 |
    85 | 86 |
    87 | bar content 88 |
    89 |
    90 |
    91 | eos 92 | 93 | strip_expected(html) 94 | end 95 | 96 | it "should render a tabbable navigation with fade" do 97 | html = tabbable(foo_tab_text, fade: true, &block) 98 | strip(html).should == expected_html 99 | end 100 | end 101 | 102 | context "with active" do 103 | it "should render the specified tabs and tab panes as active" do 104 | expected_html = <<-eos 105 |
    106 | 110 | 111 |
    112 |
    113 | foo content 114 |
    115 | 116 |
    117 | bar content 118 |
    119 |
    120 |
    121 | eos 122 | 123 | expected_html = strip_expected(expected_html) 124 | 125 | html = tabbable do |bar| 126 | bar.tab foo_tab_text 127 | bar.tab bar_tab_text, active: true 128 | 129 | bar.tab_pane do 130 | "foo content" 131 | end 132 | 133 | bar.tab_pane active: true do 134 | "bar content" 135 | end 136 | end 137 | 138 | strip(html).should == expected_html 139 | end 140 | 141 | it "should render none of the tabs or tab panes as active if ':active' is set to 'false'" do 142 | expected_html = <<-eos 143 |
    144 | 148 | 149 |
    150 |
    151 | foo content 152 |
    153 | 154 |
    155 | bar content 156 |
    157 |
    158 |
    159 | eos 160 | 161 | expected_html = strip_expected(expected_html) 162 | 163 | html = tabbable do |bar| 164 | bar.tab foo_tab_text 165 | bar.tab bar_tab_text, active: false 166 | 167 | bar.tab_pane do 168 | "foo content" 169 | end 170 | 171 | bar.tab_pane active: false do 172 | "bar content" 173 | end 174 | end 175 | 176 | strip(html).should == expected_html 177 | end 178 | end 179 | 180 | context "with direction" do 181 | context "unspecified" do 182 | let(:html_class) { "tabbable" } 183 | 184 | it "should render a tabbable navigation with the tabs on top" do 185 | html = tabbable(foo_tab_text, &block) 186 | strip(html).should == expected_html 187 | end 188 | end 189 | 190 | context "top" do 191 | let(:html_class) { "tabbable" } 192 | 193 | it "should render a tabbable navigation with the tabs on top" do 194 | html = tabbable(foo_tab_text, direction: "top", &block) 195 | strip(html).should == expected_html 196 | end 197 | end 198 | 199 | context "bottom" do 200 | let(:html_class) { "tabbable tabs-below" } 201 | 202 | it "should render a tabbable navigation with the tabs on the bottom" do 203 | html = tabbable(foo_tab_text, direction: "below", &block) 204 | strip(html).should == expected_html 205 | end 206 | end 207 | 208 | context "left" do 209 | let(:html_class) { "tabbable tabs-left" } 210 | 211 | it "should render a tabbable navigation with the tabs on the left" do 212 | html = tabbable(foo_tab_text, direction: "left", &block) 213 | strip(html).should == expected_html 214 | end 215 | end 216 | 217 | context "right" do 218 | let(:html_class) { "tabbable tabs-right" } 219 | 220 | it "should render a tabbable navigation with the tabs on the right" do 221 | html = tabbable(foo_tab_text, direction: "right", &block) 222 | strip(html).should == expected_html 223 | end 224 | end 225 | end 226 | end 227 | end 228 | end -------------------------------------------------------------------------------- /spec/helpers/options_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::OptionsHelper do 4 | describe "bs_options" do 5 | context "recognized options" do 6 | it "should not override unrecognized options" do 7 | expected = { :"data-toggle" => "bar", title: "text" } 8 | options = expected.merge tooltip: "foo" 9 | helper.bs_options(options).should == expected 10 | end 11 | 12 | context "tooltip" do 13 | let(:options) do 14 | { tooltip: "foo" } 15 | end 16 | 17 | let(:expected) do 18 | { :"data-toggle" => "tooltip", title: "foo" } 19 | end 20 | 21 | it "should handle the :tooltip option" do 22 | helper.bs_options(options).should == expected 23 | end 24 | 25 | it "should handle the :tooltip_position option" do 26 | options[:tooltip_position] = "left" 27 | expected[:"data-placement"] = "left" 28 | helper.bs_options(options).should == expected 29 | end 30 | 31 | it "should not handle :tooltip_position if :tooltip is not specified" do 32 | options.delete(:tooltip) 33 | options[:tooltip_position] = "left" 34 | expected[:"data-placement"] = "left" 35 | helper.bs_options(options).should_not == expected 36 | end 37 | end 38 | end 39 | 40 | context "unrecognized options" do 41 | it "should leave unrecognized options intact" do 42 | options = { a: 3, href: "foo", :"data-placement" => "left", title: "foo" } 43 | helper.bs_options(options).should == options 44 | end 45 | end 46 | end 47 | 48 | describe "append_class!" do 49 | it "should return the options hash" do 50 | options = { class: "foo" } 51 | helper.append_class!(options, "bar").should == options 52 | end 53 | 54 | context "with non existing class" do 55 | let(:options) { { } } 56 | 57 | it "should append the given class" do 58 | helper.append_class!(options, "foo") 59 | options[:class].should == "foo" 60 | end 61 | 62 | it "should add a new key, :class, to the options hash" do 63 | helper.append_class!(options, "foo") 64 | options.key?(:class).should be_true 65 | end 66 | 67 | context "when appending multiple classes" do 68 | let(:classes) { %w[foo bar button small] } 69 | 70 | it "should append all the given classes" do 71 | helper.append_class!(options, *classes) 72 | options[:class].should == classes.join(" ") 73 | end 74 | end 75 | end 76 | 77 | context "with existing class" do 78 | it "should preserve the existing class and append the new" do 79 | options = { class: "foo" } 80 | helper.append_class!(options, "bar") 81 | options[:class].should == "foo bar" 82 | end 83 | 84 | it "should handle 'class' as a key" do 85 | options = { "class" => "foo" } 86 | helper.append_class!(options, "bar") 87 | options["class"].should == "foo bar" 88 | end 89 | 90 | it "should handle :class as key" do 91 | options = { class: "foo" } 92 | helper.append_class!(options, "bar") 93 | options[:class].should == "foo bar" 94 | end 95 | end 96 | end 97 | end -------------------------------------------------------------------------------- /spec/helpers/tag_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::TagHelper do 4 | describe "bs_content_tag" do 5 | it "should render an HTML tag" do 6 | expected_html = <<-eos 7 |
    8 |
    9 | foo 10 |
    11 | bar 12 |
    13 | eos 14 | 15 | html = bs_content_tag :div, id: "foo" do 16 | bs_content_tag :div do 17 | append "foo" 18 | end 19 | 20 | append "bar" 21 | end 22 | 23 | html.should == expected_html 24 | end 25 | end 26 | end -------------------------------------------------------------------------------- /spec/helpers/url_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe RailsBootstrapHelpers::Helpers::UrlHelper do 4 | describe "action_link_to" do 5 | context "with url" do 6 | it { should render_action_link_to("foo").to("bar") } 7 | end 8 | 9 | context "with style" do 10 | it { should render_action_link_to("foo") } 11 | it { should render_action_link_to("foo").with_style(:default).with_class("asd") } 12 | it { should render_action_link_to("foo").with_style(:primary) } 13 | it { should render_action_link_to("foo").with_style(:info) } 14 | it { should render_action_link_to("foo").with_style(:success) } 15 | it { should render_action_link_to("foo").with_style(:warning) } 16 | it { should render_action_link_to("foo").with_style(:danger) } 17 | end 18 | 19 | context "with tooltip" do 20 | it { should render_action_link_to("foo").with_tooltip("asd") } 21 | it { should render_action_link_to("foo").with_tooltip("asd").with_tooltip_position(:left) } 22 | end 23 | end 24 | 25 | describe "row_link_to" do 26 | it { should render_row_link_to("foo").to("bar") } 27 | 28 | context "with tooltip" do 29 | it { should render_row_link_to("foo").with_tooltip("asd") } 30 | it { should render_row_link_to("foo").with_tooltip("asd").with_tooltip_position(:left) } 31 | end 32 | end 33 | end -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require "spork" 3 | 4 | Spork.prefork do 5 | ENV["RAILS_ENV"] ||= 'test' 6 | require File.expand_path("../dummy/config/environment", __FILE__) 7 | 8 | require "rspec/rails" 9 | require "rspec/autorun" 10 | require "pry" 11 | 12 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 13 | 14 | RSpec.configure do |config| 15 | config.order = "random" 16 | config.include Html 17 | end 18 | end 19 | 20 | Spork.each_run do 21 | require "rails-bootstrap-helpers" 22 | end -------------------------------------------------------------------------------- /spec/support/html.rb: -------------------------------------------------------------------------------- 1 | module Html 2 | def strip (html) 3 | html.gsub!("\n", "") 4 | end 5 | 6 | def strip_expected (html) 7 | html.gsub(/^\s+/, "").gsub("\n", "") 8 | end 9 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/alert_helper/render_bs_alert.rb: -------------------------------------------------------------------------------- 1 | # -*- encoding : utf-8 -*- 2 | 3 | RSpec::Matchers.define :render_bs_alert do |text| 4 | def options 5 | @options ||= { } 6 | end 7 | 8 | def text 9 | @text 10 | end 11 | 12 | def cls 13 | cls = "alert" 14 | 15 | if style? || type? 16 | style = (options[:style] || options[:type]).to_s 17 | 18 | if style == "notice" 19 | style = "success" 20 | end 21 | 22 | unless style == "warning" || style == "default" 23 | cls << " alert-#{style}" 24 | end 25 | end 26 | 27 | if block? 28 | cls << " alert-block" 29 | end 30 | 31 | cls 32 | end 33 | 34 | def expected 35 | @render_alert_expected ||= begin 36 | text = self.text 37 | 38 | if dismiss_button? 39 | text = text + '' 40 | end 41 | 42 | "
    #{text}
    " 43 | end 44 | end 45 | 46 | def got 47 | @got ||= helper.bs_alert(text, options) 48 | end 49 | 50 | def failure_message (is_not) 51 | ex = is_not ? "expected not" : "expected" 52 | "#{ex}: #{expected}\n got: #{got}" 53 | end 54 | 55 | def html_class 56 | @html_class ||= class? ? @class.to_s : options[:status].to_s 57 | end 58 | 59 | def style? 60 | @style_set 61 | end 62 | 63 | def type? 64 | @type_set 65 | end 66 | 67 | def block? 68 | @block_set 69 | end 70 | 71 | def dismiss_button? 72 | @dismiss_button_set 73 | end 74 | 75 | def class? 76 | !@class.nil? 77 | end 78 | 79 | chain :with_style do |style| 80 | options[:style] = style 81 | @style_set = true 82 | end 83 | 84 | chain :with_type do |type| 85 | options[:type] = type 86 | @type_set = true 87 | end 88 | 89 | chain :with_dismiss_button do |dismiss_button| 90 | options[:dismiss_button] = dismiss_button 91 | @dismiss_button_set = true 92 | end 93 | 94 | chain :as_block do |block| 95 | options[:block] = block 96 | @block_set = true 97 | end 98 | 99 | chain :as_class do |cls| 100 | @class = cls 101 | end 102 | 103 | match do 104 | @text = text 105 | expected == got 106 | end 107 | 108 | failure_message_for_should do 109 | failure_message(false) 110 | end 111 | 112 | failure_message_for_should_not do 113 | failure_message(true) 114 | end 115 | 116 | description do 117 | desc = "render an alert '#{text}'" 118 | desc << " as block" if block? 119 | desc << " with dismiss button" if dismiss_button? 120 | desc << " with the style: #{options[:style]}" if style? 121 | desc << " with the type: #{options[:type]}" if type? 122 | desc << " as the class #{html_class}" if class? 123 | desc 124 | end 125 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/base_helper/render_icon.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_icon do |icon| 2 | def options 3 | @options ||= { invert: false } 4 | end 5 | 6 | def icon 7 | @icon 8 | end 9 | 10 | def cls 11 | cls = "icon-#{icon}" 12 | cls << " icon-white" if invert? 13 | cls 14 | end 15 | 16 | def cls 17 | @cls ||= begin 18 | base_class = "icon-#{icon}" 19 | cls = extra_class.present? ? extra_class + " " + base_class : base_class 20 | cls << " icon-white" if invert? 21 | cls 22 | end 23 | end 24 | 25 | def expected 26 | @render_icon_expected ||= "" 27 | end 28 | 29 | def got 30 | @got ||= helper.icon(icon, invert: options[:invert], class: options[:class]) 31 | end 32 | 33 | def failure_message (is_not) 34 | ex = is_not ? "expected not" : "expected" 35 | "#{ex}: #{expected}\n got: #{got}" 36 | end 37 | 38 | def invert? 39 | @invert_set 40 | end 41 | 42 | def extra_class 43 | options[:class] 44 | end 45 | 46 | chain :inverted do |invert| 47 | options[:invert] = invert 48 | @invert_set = true 49 | end 50 | 51 | chain :with_class do |cls| 52 | options[:class] = cls 53 | end 54 | 55 | match do 56 | @icon = icon 57 | expected == got 58 | end 59 | 60 | failure_message_for_should do 61 | failure_message(false) 62 | end 63 | 64 | failure_message_for_should_not do 65 | failure_message(true) 66 | end 67 | 68 | description do 69 | ext = invert? ? "inverted " : "" 70 | "render an icon with the #{ext}style: #{icon}" 71 | end 72 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/base_helper/render_iconic_icon.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_iconic_icon do |icon| 2 | def options 3 | @options ||= { } 4 | end 5 | 6 | def icon 7 | @icon 8 | end 9 | 10 | def cls 11 | @cls ||= begin 12 | "iconic-#{icon}".tap do |cls| 13 | cls << bs_style_class 14 | cls << action_style_class 15 | end 16 | end 17 | end 18 | 19 | def bs_style_class 20 | if bs_style = options[:bs_style] 21 | if bs_style.to_s == "muted" 22 | " muted" 23 | else 24 | " text-#{bs_style}" 25 | end 26 | else 27 | "" 28 | end 29 | end 30 | 31 | def action_style_class 32 | if action_style = options[:action_style] 33 | " act".tap do |cls| 34 | unless action_style.to_s == "default" 35 | cls << " act-#{action_style}" 36 | end 37 | end 38 | else 39 | "" 40 | end 41 | end 42 | 43 | def append_style (key, value) 44 | if value 45 | @style ||= "" 46 | 47 | unless @style.end_with?(";") 48 | @style << ";" 49 | end 50 | 51 | @style << " " 52 | 53 | @style << "#{key}: #{value};" 54 | end 55 | end 56 | 57 | def handle_size 58 | if size = options[:size] 59 | size = size.to_s 60 | 61 | if size.to_i > 0 62 | size << "px" 63 | end 64 | 65 | append_style("font-size", size) 66 | end 67 | end 68 | 69 | def html_attributes 70 | handle_size 71 | 72 | if color = options[:color] 73 | append_style(:color, color) 74 | end 75 | 76 | attrs = { class: cls } 77 | attrs[:style] = @style if @style.present? 78 | 79 | if tooltip? 80 | if tooltip_position? 81 | attrs[:"data-placement"] = options[:tooltip_position] 82 | end 83 | 84 | attrs[:"data-toggle"] = "tooltip" 85 | attrs[:title] = options[:tooltip] 86 | end 87 | 88 | attrs.map { |k, v| "#{k}=\"#{v}\"" }.join(" ") 89 | end 90 | 91 | def expected 92 | @render_icon_expected ||= "" 93 | end 94 | 95 | def got 96 | @got ||= helper.iconic_icon(icon, options) 97 | end 98 | 99 | def failure_message (is_not) 100 | ex = is_not ? "expected not" : "expected" 101 | "#{ex}: #{expected}\n got: #{got}" 102 | end 103 | 104 | def bs_style? 105 | options[:bs_style] 106 | end 107 | 108 | def action_style? 109 | options[:action_style] 110 | end 111 | 112 | def color? 113 | options[:color] 114 | end 115 | 116 | def size? 117 | options[:size] 118 | end 119 | 120 | def tooltip? 121 | options.key?(:tooltip) 122 | end 123 | 124 | def tooltip_position? 125 | options.key?(:tooltip_position) 126 | end 127 | 128 | chain :inverted do |invert| 129 | options[:invert] = invert 130 | @invert_set = true 131 | end 132 | 133 | chain :with_class do |cls| 134 | options[:class] = cls 135 | end 136 | 137 | chain :with_action_style do |cls| 138 | options[:action_style] = cls 139 | end 140 | 141 | chain :with_bs_style do |cls| 142 | options[:bs_style] = cls 143 | end 144 | 145 | chain :with_size do |size| 146 | options[:size] 147 | end 148 | 149 | chain :with_color do |color| 150 | options[:color] 151 | end 152 | 153 | chain :with_tooltip do |tooltip| 154 | options[:tooltip] = tooltip 155 | end 156 | 157 | chain :with_tooltip_position do |tooltip_position| 158 | options[:tooltip_position] = tooltip_position 159 | end 160 | 161 | match do 162 | @icon = icon 163 | expected == got 164 | end 165 | 166 | failure_message_for_should do 167 | failure_message(false) 168 | end 169 | 170 | failure_message_for_should_not do 171 | failure_message(true) 172 | end 173 | 174 | description do 175 | # ext = invert? ? "inverted " : "" 176 | # "render an icon with the #{ext}style: #{icon}" 177 | 178 | desc = "render an iconic icon '#{icon}'" 179 | descs = [] 180 | descs << "with the Bootstrap style: #{options[:bs_style]}" if bs_style? 181 | descs << "with the action link style: #{options[:action_style]}" if action_style? 182 | descs << "with the color: #{options[:color]}" if color? 183 | descs << "with the size: #{options[:size]}" if size? 184 | 185 | descs << "with the '#{options[:tooltip]}' tooltip" if tooltip? 186 | descs << "with the '#{options[:tooltip_position]}' tooltip position" if tooltip_position? 187 | 188 | desc << " " if descs.any? 189 | desc << descs.to_sentence 190 | end 191 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/button_helper/render_bs_button_to.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_bs_button_to do |text| 2 | def options 3 | @options ||= { } 4 | end 5 | 6 | def append_style (style) 7 | " btn-#{style}" 8 | end 9 | 10 | def cls 11 | @cls ||= begin 12 | cls = extra_class.present? ? "#{extra_class} btn" : "btn" 13 | cls << " btn-#{options[:style]}" if style? 14 | cls << " btn-#{options[:size]}" if size? 15 | cls 16 | end 17 | end 18 | 19 | def text_with_icon 20 | if icon? 21 | cls = "icon-#{options[:icon]}" 22 | cls << " icon-white" if inverted? 23 | icon = "" 24 | default = icon + " " + text 25 | 26 | if icon_position? 27 | if options[:icon_position].to_s == "right" 28 | return text + " " + icon 29 | end 30 | end 31 | 32 | default 33 | else 34 | text 35 | end 36 | end 37 | 38 | def html_attributes 39 | attrs = { href: url, class: cls } 40 | 41 | if tooltip? 42 | if tooltip_position? 43 | attrs[:"data-placement"] = options[:tooltip_position] 44 | end 45 | 46 | attrs[:"data-toggle"] = "tooltip" 47 | attrs[:title] = options[:tooltip] 48 | end 49 | 50 | attrs.map { |k, v| "#{k}=\"#{v}\"" }.join(" ") 51 | end 52 | 53 | def expected 54 | @render_button_expected ||= "#{text_with_icon}" 55 | end 56 | 57 | def got 58 | @got ||= helper.bs_button_to(text, url, options) 59 | end 60 | 61 | def failure_message (is_not) 62 | ex = is_not ? "expected not" : "expected" 63 | "#{ex}: #{expected}\n got: #{got}" 64 | end 65 | 66 | def text 67 | @text 68 | end 69 | 70 | def url 71 | @url || "default_url" 72 | end 73 | 74 | def style? 75 | @style_set 76 | end 77 | 78 | def size? 79 | @size_set 80 | end 81 | 82 | def icon? 83 | @icon_set 84 | end 85 | 86 | def inverted? 87 | @inverted_set 88 | end 89 | 90 | def icon_position? 91 | @icon_position_set 92 | end 93 | 94 | def tooltip? 95 | options.key?(:tooltip) 96 | end 97 | 98 | def tooltip_position? 99 | options.key?(:tooltip_position) 100 | end 101 | 102 | def extra_class 103 | options[:class] 104 | end 105 | 106 | chain :to do |url| 107 | @url = url 108 | end 109 | 110 | chain :with_style do |style| 111 | options[:style] = style 112 | @style_set = true 113 | end 114 | 115 | chain :with_size do |size| 116 | options[:size] = size 117 | @size_set = true 118 | end 119 | 120 | chain :with_icon do |icon| 121 | options[:icon] = icon 122 | @icon_set = true 123 | end 124 | 125 | chain :with_icon_inverted do |inverted| 126 | options[:icon_invert] = inverted 127 | @inverted_set = true 128 | end 129 | 130 | chain :with_icon_position do |icon_position| 131 | options[:icon_position] = icon_position 132 | @icon_position_set = true 133 | end 134 | 135 | chain :with_class do |cls| 136 | options[:class] = cls 137 | end 138 | 139 | chain :with_tooltip do |tooltip| 140 | options[:tooltip] = tooltip 141 | end 142 | 143 | chain :with_tooltip_position do |tooltip_position| 144 | options[:tooltip_position] = tooltip_position 145 | end 146 | 147 | match do 148 | @text = text 149 | expected == got 150 | end 151 | 152 | failure_message_for_should do 153 | failure_message(false) 154 | end 155 | 156 | failure_message_for_should_not do 157 | failure_message(true) 158 | end 159 | 160 | description do 161 | desc = "render a button to '#{url}'" 162 | descs = [] 163 | descs << "with the style: #{options[:style]}" if style? 164 | descs << "with the size: #{options[:size]}" if size? 165 | 166 | ext = inverted? ? "inverted " : "" 167 | 168 | descs << "with the #{ext}icon: #{options[:icon]}" if icon? 169 | descs << "with the icon_position: #{options[:icon_position]}" if icon_position? 170 | descs << "with the '#{options[:tooltip]}' tooltip" if tooltip? 171 | descs << "with the '#{options[:tooltip_position]}' tooltip position" if tooltip_position? 172 | 173 | desc << " " if descs.any? 174 | desc << descs.to_sentence 175 | end 176 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/button_helper/render_inline_button_to.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_inline_button_to do |url, icon| 2 | def options 3 | @options ||= { size: "mini" } 4 | end 5 | 6 | def cls 7 | @cls ||= "inline btn btn-#{options[:size]}" 8 | end 9 | 10 | def text_with_icon 11 | " " 12 | end 13 | 14 | def attributes 15 | attrs = { 16 | href: url, 17 | class: cls 18 | } 19 | 20 | attrs = attrs.map do |k, v| 21 | "#{k}=\"#{v}\"" 22 | end 23 | 24 | attrs.join(" ") 25 | end 26 | 27 | def expected 28 | @render_remove_button_expected ||= "#{text_with_icon}" 29 | end 30 | 31 | def got 32 | @got ||= helper.bs_inline_button_to(url, icon, options) 33 | end 34 | 35 | def failure_message (is_not) 36 | ex = is_not ? "expected not" : "expected" 37 | "#{ex}: #{expected}\n got: #{got}" 38 | end 39 | 40 | def url 41 | @url 42 | end 43 | 44 | def icon 45 | @icon 46 | end 47 | 48 | def size? 49 | @size_set 50 | end 51 | 52 | chain :with_size do |size| 53 | options[:size] = size 54 | @size_set = true 55 | end 56 | 57 | match do 58 | @url = url 59 | @icon = icon 60 | expected == got 61 | end 62 | 63 | failure_message_for_should do 64 | failure_message(false) 65 | end 66 | 67 | failure_message_for_should_not do 68 | failure_message(true) 69 | end 70 | 71 | description do 72 | desc = "render an inline button to '#{url}' with the icon: #{icon}" 73 | descs = [] 74 | descs << "with the size: #{options[:size]}" if size? 75 | 76 | desc << " " if descs.any? 77 | desc << descs.to_sentence(two_words_connector: " and ", last_word_connector: " and ") 78 | end 79 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/form_tag_helper/render_bs_button_tag.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_bs_button_tag do |text, type| 2 | def options 3 | @options ||= { } 4 | end 5 | 6 | def append_style (style) 7 | " btn-#{style}" 8 | end 9 | 10 | def cls 11 | @cls ||= begin 12 | cls = "btn" 13 | cls << " btn-#{options[:style]}" if style? 14 | cls << " btn-#{options[:size]}" if size? 15 | cls 16 | end 17 | end 18 | 19 | def text_with_icon 20 | if icon? 21 | cls = "icon-#{options[:icon]}" 22 | cls << " icon-white" if inverted? 23 | icon = "" 24 | default = icon + " " + text 25 | 26 | if icon_position? 27 | if options[:icon_position].to_s == "right" 28 | return text + " " + icon 29 | end 30 | end 31 | 32 | default 33 | else 34 | text 35 | end 36 | end 37 | 38 | def html_attributes 39 | attrs = { class: cls } 40 | 41 | if tooltip? 42 | if tooltip_position? 43 | attrs[:"data-placement"] = options[:tooltip_position] 44 | end 45 | 46 | attrs[:"data-toggle"] = "tooltip" 47 | end 48 | 49 | attrs[:name] = "button" 50 | 51 | if tooltip? 52 | attrs[:title] = options[:tooltip] 53 | end 54 | 55 | attrs.map { |k, v| "#{k}=\"#{v}\"" }.join(" ") 56 | end 57 | 58 | def expected 59 | @render_button_expected ||= "" 60 | end 61 | 62 | def got 63 | @got ||= helper.bs_button_tag(text, type, options) 64 | end 65 | 66 | def failure_message (is_not) 67 | ex = is_not ? "expected not" : "expected" 68 | "#{ex}: #{expected}\n got: #{got}" 69 | end 70 | 71 | def text 72 | @text 73 | end 74 | 75 | def type 76 | @type 77 | end 78 | 79 | def style? 80 | @style_set 81 | end 82 | 83 | def size? 84 | @size_set 85 | end 86 | 87 | def icon? 88 | @icon_set 89 | end 90 | 91 | def inverted? 92 | @inverted_set 93 | end 94 | 95 | def icon_position? 96 | @icon_position_set 97 | end 98 | 99 | def tooltip? 100 | options.key?(:tooltip) 101 | end 102 | 103 | def tooltip_position? 104 | options.key?(:tooltip_position) 105 | end 106 | 107 | chain :to do |url| 108 | @url = url 109 | end 110 | 111 | chain :with_style do |style| 112 | options[:style] = style 113 | @style_set = true 114 | end 115 | 116 | chain :with_size do |size| 117 | options[:size] = size 118 | @size_set = true 119 | end 120 | 121 | chain :with_icon do |icon| 122 | options[:icon] = icon 123 | @icon_set = true 124 | end 125 | 126 | chain :with_icon_inverted do |inverted| 127 | options[:icon_invert] = inverted 128 | @inverted_set = true 129 | end 130 | 131 | chain :with_icon_position do |icon_position| 132 | options[:icon_position] = icon_position 133 | @icon_position_Set = true 134 | end 135 | 136 | chain :with_tooltip do |tooltip| 137 | options[:tooltip] = tooltip 138 | end 139 | 140 | chain :with_tooltip_position do |tooltip_position| 141 | options[:tooltip_position] = tooltip_position 142 | end 143 | 144 | match do 145 | @text = text 146 | @type = type 147 | expected == got 148 | end 149 | 150 | failure_message_for_should do 151 | failure_message(false) 152 | end 153 | 154 | failure_message_for_should_not do 155 | failure_message(true) 156 | end 157 | 158 | description do 159 | desc = "render a button with type '#{type}'" 160 | descs = [] 161 | descs << "with the style: #{options[:style]}" if style? 162 | descs << "with the size: #{options[:size]}" if size? 163 | 164 | ext = inverted? ? "inverted " : "" 165 | 166 | descs << "with the #{ext}icon: #{options[:icon]}" if icon? 167 | descs << "with the icon_position: #{options[:icon_position]}" if icon_position? 168 | descs << "with the '#{options[:tooltip]}' tooltip" if tooltip? 169 | descs << "with the '#{options[:tooltip_position]}' tooltip position" if tooltip_position? 170 | 171 | desc << " " if descs.any? 172 | desc << descs.to_sentence(two_words_connector: " and ", last_word_connector: " and ") 173 | end 174 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/form_tag_helper/render_bs_submit_tag.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_bs_submit_tag do |text, type| 2 | def options 3 | @options ||= { } 4 | end 5 | 6 | def append_style (style) 7 | " btn-#{style}" 8 | end 9 | 10 | def cls 11 | @cls ||= begin 12 | cls = "btn" 13 | cls << " btn-#{options[:style]}" if style? 14 | cls << " btn-#{options[:size]}" if size? 15 | cls 16 | end 17 | end 18 | 19 | def text_with_icon 20 | if icon? 21 | cls = "icon-#{options[:icon]}" 22 | cls << " icon-white" if inverted? 23 | icon = "" 24 | default = icon + " " + text 25 | 26 | if icon_position? 27 | if options[:icon_position].to_s == "right" 28 | return text + " " + icon 29 | end 30 | end 31 | 32 | default 33 | else 34 | text 35 | end 36 | end 37 | 38 | def expected 39 | @render_button_expected ||= "" 40 | end 41 | 42 | def got 43 | @got ||= helper.bs_submit_tag(text, options) 44 | end 45 | 46 | def failure_message (is_not) 47 | ex = is_not ? "expected not" : "expected" 48 | "#{ex}: #{expected}\n got: #{got}" 49 | end 50 | 51 | def text 52 | @text 53 | end 54 | 55 | def style? 56 | @style_set 57 | end 58 | 59 | def size? 60 | @size_set 61 | end 62 | 63 | chain :with_style do |style| 64 | options[:style] = style 65 | @style_set = true 66 | end 67 | 68 | chain :with_size do |size| 69 | options[:size] = size 70 | @size_set = true 71 | end 72 | 73 | match do 74 | @text = text 75 | @type = type 76 | expected == got 77 | end 78 | 79 | failure_message_for_should do 80 | failure_message(false) 81 | end 82 | 83 | failure_message_for_should_not do 84 | failure_message(true) 85 | end 86 | 87 | description do 88 | desc = "render a button with type '#{type}'" 89 | descs = [] 90 | descs << "with the style: #{options[:style]}" if style? 91 | descs << "with the size: #{options[:size]}" if size? 92 | 93 | desc << " " if descs.any? 94 | desc << descs.to_sentence(two_words_connector: " and ", last_word_connector: " and ") 95 | end 96 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/label_helper/render_bs_label.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_bs_label do |text| 2 | def options 3 | @options ||= { } 4 | end 5 | 6 | def style 7 | @style 8 | end 9 | 10 | def style? 11 | @style.present? 12 | end 13 | 14 | def custom_class 15 | @custom_class 16 | end 17 | 18 | def custom_class? 19 | @custom_class.present? 20 | end 21 | 22 | def tooltip? 23 | options.key?(:tooltip) 24 | end 25 | 26 | def tooltip_position? 27 | options.key?(:tooltip_position) 28 | end 29 | 30 | def text 31 | @text 32 | end 33 | 34 | def html_cls 35 | @html_cls ||= custom_class? ? custom_class.to_s : style.to_s 36 | end 37 | 38 | def build_html_class 39 | "label".tap do |c| 40 | c << " label-#{html_cls}" unless html_cls == "default" 41 | end 42 | end 43 | 44 | def html_attributes 45 | attrs = { class: build_html_class } 46 | 47 | if tooltip? 48 | if tooltip_position? 49 | attrs[:"data-placement"] = options[:tooltip_position] 50 | end 51 | 52 | attrs[:"data-toggle"] = "tooltip" 53 | attrs[:title] = options[:tooltip] 54 | end 55 | 56 | attrs.map { |k, v| "#{k}=\"#{v}\"" }.join(" ") 57 | end 58 | 59 | def expected 60 | @render_bs_label_expected ||= begin 61 | "#{text}" 62 | end 63 | end 64 | 65 | def got 66 | @got ||= helper.bs_label(text, style, options) 67 | end 68 | 69 | def failure_message (is_not) 70 | ex = is_not ? "expected not" : "expected" 71 | "#{ex}: #{expected}\n got: #{got}" 72 | end 73 | 74 | chain :with_style do |style| 75 | @style = style 76 | end 77 | 78 | chain :as_class do |custom_class| 79 | @custom_class = custom_class 80 | end 81 | 82 | chain :with_tooltip do |tooltip| 83 | options[:tooltip] = tooltip 84 | end 85 | 86 | chain :with_tooltip_position do |tooltip_position| 87 | options[:tooltip_position] = tooltip_position 88 | end 89 | 90 | match do 91 | @text = text 92 | @style ||= "default" 93 | expected == got 94 | end 95 | 96 | failure_message_for_should do 97 | failure_message(false) 98 | end 99 | 100 | failure_message_for_should_not do 101 | failure_message(true) 102 | end 103 | 104 | description do 105 | desc = "should return a label with the text '#{text}' and with the #{style} style" 106 | desc << " as the class #{html_cls}" if custom_class? 107 | descs = [] 108 | descs << "with the '#{options[:tooltip]}' tooltip" if tooltip? 109 | descs << "with the '#{options[:tooltip_position]}' tooltip position" if tooltip_position? 110 | 111 | desc << " " if descs.any? 112 | desc << descs.to_sentence(two_words_connector: " and ", last_word_connector: " and ") 113 | end 114 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/url_helper/render_action_link_to.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_action_link_to do |text| 2 | def options 3 | @options ||= { } 4 | end 5 | 6 | def append_style (style) 7 | " act-#{style}" 8 | end 9 | 10 | def cls 11 | @cls ||= begin 12 | cls = extra_class.present? ? "#{extra_class} act" : "act" 13 | 14 | if style? 15 | style = options[:style] 16 | 17 | unless style.to_s == "default" 18 | cls << " act-#{options[:style]}" 19 | end 20 | end 21 | 22 | cls 23 | end 24 | end 25 | 26 | def html_attributes 27 | attrs = { href: url, class: cls } 28 | 29 | if tooltip? 30 | if tooltip_position? 31 | attrs[:"data-placement"] = options[:tooltip_position] 32 | end 33 | 34 | attrs[:"data-toggle"] = "tooltip" 35 | attrs[:title] = options[:tooltip] 36 | end 37 | 38 | attrs.map { |k, v| "#{k}=\"#{v}\"" }.join(" ") 39 | end 40 | 41 | def expected 42 | @render_button_expected ||= "#{text}" 43 | end 44 | 45 | def got 46 | @got ||= helper.action_link_to(text, url, options) 47 | end 48 | 49 | def failure_message (is_not) 50 | ex = is_not ? "expected not" : "expected" 51 | "#{ex}: #{expected}\n got: #{got}" 52 | end 53 | 54 | def text 55 | @text 56 | end 57 | 58 | def url 59 | @url || "default_url" 60 | end 61 | 62 | def style? 63 | @style_set 64 | end 65 | 66 | def tooltip? 67 | options.key?(:tooltip) 68 | end 69 | 70 | def tooltip_position? 71 | options.key?(:tooltip_position) 72 | end 73 | 74 | def extra_class 75 | options[:class] 76 | end 77 | 78 | chain :to do |url| 79 | @url = url 80 | end 81 | 82 | chain :with_style do |style| 83 | options[:style] = style 84 | @style_set = true 85 | end 86 | 87 | chain :with_class do |cls| 88 | options[:class] = cls 89 | end 90 | 91 | chain :with_tooltip do |tooltip| 92 | options[:tooltip] = tooltip 93 | end 94 | 95 | chain :with_tooltip_position do |tooltip_position| 96 | options[:tooltip_position] = tooltip_position 97 | end 98 | 99 | match do 100 | @text = text 101 | expected == got 102 | end 103 | 104 | failure_message_for_should do 105 | failure_message(false) 106 | end 107 | 108 | failure_message_for_should_not do 109 | failure_message(true) 110 | end 111 | 112 | description do 113 | desc = "render a action link to '#{url}'" 114 | descs = [] 115 | descs << "with the style: #{options[:style]}" if style? 116 | 117 | descs << "with the '#{options[:tooltip]}' tooltip" if tooltip? 118 | descs << "with the '#{options[:tooltip_position]}' tooltip position" if tooltip_position? 119 | 120 | desc << " " if descs.any? 121 | desc << descs.to_sentence 122 | end 123 | end -------------------------------------------------------------------------------- /spec/support/matchers/helpers/url_helper/render_row_link_to.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :render_row_link_to do |text| 2 | def options 3 | @options ||= { } 4 | end 5 | 6 | def cls 7 | @cls ||= extra_class.present? ? "#{extra_class} rowlink" : "rowlink" 8 | end 9 | 10 | def html_attributes 11 | attrs = { href: url, class: cls } 12 | 13 | if tooltip? 14 | if tooltip_position? 15 | attrs[:"data-placement"] = options[:tooltip_position] 16 | end 17 | 18 | attrs[:"data-toggle"] = "tooltip" 19 | attrs[:title] = options[:tooltip] 20 | end 21 | 22 | attrs.map { |k, v| "#{k}=\"#{v}\"" }.join(" ") 23 | end 24 | 25 | def expected 26 | @render_button_expected ||= "#{text}" 27 | end 28 | 29 | def got 30 | @got ||= helper.row_link_to(text, url, options) 31 | end 32 | 33 | def failure_message (is_not) 34 | ex = is_not ? "expected not" : "expected" 35 | "#{ex}: #{expected}\n got: #{got}" 36 | end 37 | 38 | def text 39 | @text 40 | end 41 | 42 | def url 43 | @url || "default_url" 44 | end 45 | 46 | def tooltip? 47 | options.key?(:tooltip) 48 | end 49 | 50 | def tooltip_position? 51 | options.key?(:tooltip_position) 52 | end 53 | 54 | def extra_class 55 | options[:class] 56 | end 57 | 58 | chain :to do |url| 59 | @url = url 60 | end 61 | 62 | chain :with_class do |cls| 63 | options[:class] = cls 64 | end 65 | 66 | chain :with_tooltip do |tooltip| 67 | options[:tooltip] = tooltip 68 | end 69 | 70 | chain :with_tooltip_position do |tooltip_position| 71 | options[:tooltip_position] = tooltip_position 72 | end 73 | 74 | match do 75 | @text = text 76 | expected == got 77 | end 78 | 79 | failure_message_for_should do 80 | failure_message(false) 81 | end 82 | 83 | failure_message_for_should_not do 84 | failure_message(true) 85 | end 86 | 87 | description do 88 | desc = "render a action link to '#{url}'" 89 | descs = [] 90 | 91 | descs << "with the '#{options[:tooltip]}' tooltip" if tooltip? 92 | descs << "with the '#{options[:tooltip_position]}' tooltip position" if tooltip_position? 93 | 94 | desc << " " if descs.any? 95 | desc << descs.to_sentence 96 | end 97 | end --------------------------------------------------------------------------------