bootstrap2-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/README.rdoc +54 -0
  4. data/Rakefile +1 -0
  5. data/app/views/layouts/application.html.erb +21 -0
  6. data/app/views/shared/_search.html.erb +4 -0
  7. data/app/views/shared/_search.html.erb~ +4 -0
  8. data/bootstrap2-rails.gemspec +25 -0
  9. data/lib/bootstrap2-rails.rb +19 -0
  10. data/lib/bootstrap2-rails/bootstrap_helper.rb +24 -0
  11. data/lib/bootstrap2-rails/menu_creator.rb +39 -0
  12. data/lib/bootstrap2-rails/version.rb +3 -0
  13. data/lib/generators/bootstrap/views_generator.rb +23 -0
  14. data/lib/templates/erb/scaffold/_form.html.erb +43 -0
  15. data/lib/templates/erb/scaffold/edit.html.erb +7 -0
  16. data/lib/templates/erb/scaffold/index.html.erb +53 -0
  17. data/lib/templates/erb/scaffold/new.html.erb +7 -0
  18. data/lib/templates/erb/scaffold/show.html.erb +21 -0
  19. data/lib/templates/rails/scaffold_controller/controller.rb +102 -0
  20. data/vendor/assets/images/close.gif +0 -0
  21. data/vendor/assets/images/error.png +0 -0
  22. data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
  23. data/vendor/assets/images/glyphicons-halflings.png +0 -0
  24. data/vendor/assets/images/left_arrow.png +0 -0
  25. data/vendor/assets/images/notice.png +0 -0
  26. data/vendor/assets/images/right_arrow.png +0 -0
  27. data/vendor/assets/images/success.png +0 -0
  28. data/vendor/assets/images/warning.png +0 -0
  29. data/vendor/assets/javascripts/bootstrap.js +1722 -0
  30. data/vendor/assets/javascripts/jquery.toastmessage.js +161 -0
  31. data/vendor/assets/stylesheets/bootstrap.css +3363 -0
  32. data/vendor/assets/stylesheets/jquery.toastmessage.css +142 -0
  33. metadata +88 -0
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bootstrap2-rails.gemspec
4
+ gemspec
@@ -0,0 +1,54 @@
1
+ == bootstrap2-rails gem
2
+ Warning: this gem is under development, bugs are present.
3
+
4
+ This gem replaces Rails default scaffold to create views based on Bootstrap 2, from Twitter (http://twitter.github.com/bootstrap). There is also a toast message feature based on JQuery Toast Message plugin.
5
+
6
+ When installed, this gem overrides Rails default scaffold templates, which means that any call to scaffold generator will use the gem templates. The views also are generated with some others features like search and sort.
7
+ There is also a dropdown menu generator to avoid manual menu creation.
8
+
9
+ === Building gem
10
+ After downloading project folder, run this command on root folder to make a gem file inside pkg folder:
11
+ rake build
12
+
13
+ === Installation
14
+ You can use this gem with only Rails 3. Include this line inside your Gemfile:
15
+ gem 'bootstrap2-rails', :path => '/path/to/gemfolder'
16
+
17
+ Run the bundle command to install required gems in your Rails application:
18
+ bundle
19
+
20
+ === Generating view files
21
+ After installing gem, run the views generator to copy some needed files (caution: it will override application.html.erb)
22
+ rails generate bootstrap:views
23
+
24
+ === Loading bootstrap CSS file
25
+ Include this line in your app/assets/stylesheets/application.css file to load a required CSS file
26
+ *= require bootstrap
27
+
28
+ === Toast messages
29
+ Toast messages are notifications with an android-like visual. There are 4 types of toast messages: error, warning, notice and success. In order to use the toast-messages include this required line in your app/assets/javascripts/application.js file
30
+ *= require jquery.toastmessage
31
+
32
+ And also this line for loading CSS in your app/assets/stylesheets/application.css file
33
+ *= require jquery.toastmessage
34
+
35
+ To show a toast message use this helper method
36
+ display_toast_message(message, type)
37
+
38
+ where message is the message text and type is one of the four types of messages (notice, error, success or warning)
39
+
40
+ === Menu generator
41
+ The menu generator creates a dropdown menu for your actions inside your controllers. There are three steps needed for creating a menu:
42
+
43
+ 1) Load a required javascript file by adding this line to your app/assets/javascripts/application.js
44
+ //= require bootstrap-dropdown
45
+
46
+ 2) Define wich items and subitems will be available. In a dropdown menu there is a main item and several subitems. The main item is only a text explaining the content (e.g. File, Window, Tools). The subitems are controller actions (e.g. New, Save, Close). To define the main item and corresponding subitems, insert this line in your application_controller.rb:
47
+ menu_options [{:title => 'Index', :itens => [
48
+ {:text => 'Projects', :controller => 'projects', :action => 'index'}
49
+ ]}]
50
+
51
+ The menu_options parameter is an array of hashes with 2 keys: title and itens. The title is the text of the main item and can be anything you want. The itens is an array of hashes, wich one with 3 keys: text (the subitem text), controller (the controller with the action) and action (the action itself).
52
+
53
+ 3) Include a menu_bar call in your html page:
54
+ <%= menu_bar %>
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Framework</title>
5
+ <%= stylesheet_link_tag "application" %>
6
+ <%= javascript_include_tag "application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= menu_bar %>
12
+
13
+ <div class="container-fluid" style="padding-top: 45px">
14
+ <% flash.each do |name, msg| %>
15
+ <%= display_toast_message(msg, name) %>
16
+ <% end %>
17
+ <%= yield %>
18
+ </div>
19
+
20
+ </body>
21
+ </html>
@@ -0,0 +1,4 @@
1
+ <%= form_tag({action: "index"}, {method: :get, class: 'form-search'}) do %>
2
+ <%= text_field_tag("search", params[:search], {size: 70, placeholder: placeholder, class: 'input-medium search-query'}) %>
3
+ <%= submit_tag("Search", class: 'btn') %>
4
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <%= form_tag({action: "index"}, {method: :get, class: 'form-search'}) do %>
2
+ <%= text_field_tag("search", params[:search], {size: 70, placeholder: placeholder}) %>
3
+ <%= submit_tag("Search", class: 'btn') %>
4
+ <% end %>
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bootstrap2-rails/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bootstrap2-rails"
7
+ s.version = BootstrapRails::VERSION
8
+ s.authors = ["Fabio Stapait"]
9
+ s.email = ["stapait@gmail.com"]
10
+ s.homepage = "https://github.com/stapait/bootstrap2-rails"
11
+ s.summary = %q{This is a scaffold replacement with a Twitter Bootstrap look}
12
+ s.description = %q{This is a scaffold replacement with a Twitter Bootstrap look}
13
+
14
+ s.rubyforge_project = "bootstrap2-rails"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ s.add_dependency "will_paginate"
25
+ end
@@ -0,0 +1,19 @@
1
+ require "bootstrap2-rails/version"
2
+ require "will_paginate"
3
+ require "bootstrap2-rails/bootstrap_helper"
4
+ require "bootstrap2-rails/menu_creator"
5
+
6
+ module BootstrapRails
7
+ module Rails
8
+ class Engine < ::Rails::Engine
9
+ # Include helper inside app
10
+ ActionView::Base.send :include, BootstrapHelper
11
+ ActionView::Base.send :include, MenuCreator
12
+
13
+ config.app_generators do |g|
14
+ # Make templates loadable from gem insted of copying to app
15
+ g.templates.unshift File::expand_path('../templates', __FILE__)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ module BootstrapHelper
2
+ # returns a link to sort table columns
3
+ def sortable(column, title = nil)
4
+ title ||= column.titleize
5
+ direction = params[:direction] == "asc" ? "desc" : "asc"
6
+ link_to title, sort: column, direction: direction
7
+ end
8
+
9
+ def sort_class(direction, column, table_column)
10
+ return nil if column != table_column
11
+ return 'yellow headerSortDown' if direction == 'asc'
12
+ return 'yellow headerSortUp' if direction == 'desc'
13
+ end
14
+
15
+ # display a message using the JQuery Toast Message plugin
16
+ # types available: notice, success, warning an error
17
+ def display_toast_message(message, type)
18
+ return nil unless ['notice', 'success', 'warning', 'error'].include? type.to_s.downcase
19
+ result = "<script>"
20
+ result << "$().toastmessage('show#{type.to_s.capitalize}Toast', '#{message}');"
21
+ result << "</script>"
22
+ result.html_safe
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ module MenuCreator
2
+ @@loaded = false
3
+ @@menu_params = []
4
+
5
+ def menu_options(params)
6
+ @@menu_params = params unless @@loaded
7
+ end
8
+
9
+ def menu_bar
10
+ return nil unless @@menu_params
11
+
12
+ html = '<div class="topbar-wrapper" style="z-index:5">'
13
+ html += '<div class="topbar" data-dropdown="dropdown">'
14
+ html += '<div class="topbar-inner">'
15
+ html += '<div class="container">'
16
+ html += '<ul class="nav">'
17
+
18
+ @@menu_params.each do |param|
19
+ html += '<li class="dropdown">'
20
+ html += link_to(param[:title], '#', class: 'dropdown-toggle')
21
+ html += '<ul class="dropdown-menu">'
22
+
23
+ param[:itens].each do |subitem|
24
+ html += content_tag(:li, link_to(subitem[:text], controller: subitem[:controller], action: subitem[:action]))
25
+ end
26
+
27
+ html += '</ul>'
28
+ html += '</li>'
29
+ end
30
+
31
+ html += '</ul>'
32
+ html += '</div>'
33
+ html += '</div>'
34
+ html += '</div>'
35
+ html += '</div>'
36
+
37
+ html.html_safe
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module BootstrapRails
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ module Bootstrap
2
+ module Generators
3
+ class ViewsGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../../templates", __FILE__)
5
+
6
+ desc "Creates views needed for working with bootstrap2-rails"
7
+
8
+ def generate_files
9
+ source_folder = File.join(File.dirname(File.absolute_path(__FILE__)), "..", "..", "..", "app", "views", "shared")
10
+ dest_folder = File.join("app", "views", "shared")
11
+ Dir.entries(source_folder).each do |file|
12
+ copy_file("#{source_folder}/#{file}", "#{dest_folder}/#{file}") unless File.directory? "#{source_folder}/#{file}"
13
+ end
14
+
15
+ source_folder = File.join(File.dirname(File.absolute_path(__FILE__)), "..", "..", "..", "app", "views", "layouts")
16
+ dest_folder = File.join("app", "views", "layouts")
17
+ Dir.entries(source_folder).each do |file|
18
+ copy_file("#{source_folder}/#{file}", "#{dest_folder}/#{file}") unless File.directory? "#{source_folder}/#{file}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,43 @@
1
+ <%%= form_for(@<%= singular_table_name %>, html: {class: 'form-horizontal'}) do |f| %>
2
+ <%% if @<%= singular_table_name %>.errors.any? %>
3
+ <div class="alert alert-block">
4
+ <p>
5
+ <strong><%%= pluralize(@<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</strong>
6
+ <ul>
7
+ <%% @<%= singular_table_name %>.errors.full_messages.each do |msg| %>
8
+ <li><%%= msg %></li>
9
+ <%% end %>
10
+ </ul>
11
+ </p>
12
+ </div>
13
+
14
+ <script type="text/javascript">
15
+ $('document').ready(function() {
16
+ $(".field_with_errors label").css('color', 'red');
17
+
18
+ // Remove field_with_errors div
19
+ $(".field_with_errors").each(function(index, element) {
20
+ var content = element.innerHTML;
21
+ $(element).replaceWith(content);
22
+ });
23
+
24
+ <%% @<%= singular_table_name %>.errors.each do |a| %>
25
+ $('#<%= singular_table_name %>_<%%= a %>').css('border-color', 'red');
26
+ <%% end %>
27
+ });
28
+ </script>
29
+ <%% end %>
30
+
31
+ <% attributes.each do |attribute| -%>
32
+ <div class="control-group">
33
+ <%%= f.label :<%= attribute.name %>, class: 'control-label' %>
34
+ <div class="controls">
35
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
36
+ </div>
37
+ </div>
38
+ <% end -%>
39
+ <div class="form-actions">
40
+ <%%= f.submit <%= key_value :class, "'btn btn-primary'" %> %>
41
+ <%%= link_to 'Back', <%= plural_table_name %>_path, <%= key_value :class, "'btn btn-default'" %> %>
42
+ </div>
43
+ <%% end %>
@@ -0,0 +1,7 @@
1
+ <div class="breadcrumb">
2
+ <div class="page-header">
3
+ <h2>Editing <%= singular_table_name %></h2>
4
+ </div>
5
+
6
+ <%%= render 'form' %>
7
+ </div>
@@ -0,0 +1,53 @@
1
+ <script type="text/javascript">
2
+ $('.btn-danger').click(function(){
3
+ event.preventDefault();
4
+ });
5
+
6
+ $('document').ready(function(){
7
+ $('.btn-info').tooltip({title: "Show <%= singular_table_name %>"});
8
+ $('.btn-primary').tooltip({title: "Edit <%= singular_table_name %>"});
9
+ $('.btn-danger').tooltip({title: "Delete <%= singular_table_name %>"});
10
+ $('.btn-success').tooltip({title: "Create a new <%= singular_table_name %>"});
11
+ });
12
+ </script>
13
+
14
+ <div class="page-header">
15
+ <h2>Listing <%= plural_table_name %></h2>
16
+ </div>
17
+
18
+ <%%= render(partial: '/shared/search', locals: {placeholder: 'Text to search'}) %>
19
+
20
+ <table class="table table-striped table-bordered table-condensed">
21
+ <thead>
22
+ <tr>
23
+ <% attributes.each do |attribute| -%>
24
+ <th class="<%%= sort_class(@sort_direction, @sort_column, '<%= attribute.name %>') %>"><%%= sortable('<%= attribute.name %>') %></th>
25
+ <% end -%>
26
+ <th width="140px"><a href="#">Actions</a></th>
27
+ </tr>
28
+ </thead>
29
+
30
+ <tbody>
31
+
32
+ <%% if @<%= plural_table_name %>.size > 0 %>
33
+ <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
34
+ <tr>
35
+ <% attributes.each do |attribute| -%>
36
+ <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
37
+ <% end -%>
38
+ <td>
39
+ <%%= link_to content_tag(:i, nil, class: 'icon-list-alt icon-white'), <%= singular_table_name %>, <%= key_value :class, "'btn btn-info btn-small'" %> %> &nbsp;
40
+ <%%= link_to content_tag(:i, nil, class: 'icon-tag icon-white'), edit_<%= singular_table_name %>_path(<%= singular_table_name %>), <%= key_value :class, "'btn btn-primary btn-small'" %> %> &nbsp;
41
+ <%%= link_to content_tag(:i, nil, class: 'icon-trash icon-white'), <%= singular_table_name %>, <%= key_value :confirm, "'Are you sure?'" %>, <%= key_value :method, ":delete" %>, <%= key_value :class, "'btn btn-danger btn-small'" %> %>
42
+ </td>
43
+ </tr>
44
+ <%% end %>
45
+ <%% else %>
46
+ <tr><td colspan="10">Empty</td></tr>
47
+ <%% end %>
48
+ </tbody>
49
+ </table>
50
+
51
+ <%%= will_paginate @<%= plural_table_name %> %>
52
+
53
+ <%%= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path, <%= key_value :class, "'btn btn-large btn-success'" %>, <%= key_value :style, "'float: right'" %> %>
@@ -0,0 +1,7 @@
1
+ <div class="breadcrumb">
2
+ <div class="page-header">
3
+ <h2>New <%= singular_table_name %></h2>
4
+ </div>
5
+
6
+ <%%= render 'form' %>
7
+ </div>
@@ -0,0 +1,21 @@
1
+ <div class="breadcrumb">
2
+ <div class="page-header">
3
+ <h2><%= class_name %> details</h2>
4
+ </div>
5
+
6
+ <% attributes.each do |attribute| -%>
7
+ <div class="row">
8
+ <div class="span1">
9
+ <strong><%= attribute.human_name %></strong>
10
+ </div>
11
+ <div class="span8">
12
+ <%%= @<%= singular_table_name %>.<%= attribute.name %> %>
13
+ </div>
14
+ </div>
15
+ <% end -%>
16
+ </div>
17
+
18
+ <div class="breadcrumb">
19
+ <%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>), :class => 'btn btn-primary' %>
20
+ <%%= link_to 'Back', <%= index_helper %>_path, class: 'btn btn-default' %>
21
+ </div>
@@ -0,0 +1,102 @@
1
+ <% module_namespacing do -%>
2
+ class <%= controller_class_name %>Controller < ApplicationController
3
+ # Attribute used for search (change if needed)
4
+ SEARCH_ATTR = "name"
5
+
6
+ # GET <%= route_url %>
7
+ # GET <%= route_url %>.json
8
+ def index
9
+ condition = "#{SEARCH_ATTR} like ?"
10
+ @<%= plural_table_name %> = <%= class_name %>.where(condition, "%#{params[:search]}%")
11
+ .page(params[:page]).order(sort_column + " " + sort_direction).per_page(10)
12
+
13
+ @sort_direction = sort_direction
14
+ @sort_column = sort_column
15
+ respond_to do |format|
16
+ format.html # index.html.erb
17
+ format.json { render <%= key_value :json, "@#{plural_table_name}" %> }
18
+ end
19
+ end
20
+
21
+ # GET <%= route_url %>/1
22
+ # GET <%= route_url %>/1.json
23
+ def show
24
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
25
+
26
+ respond_to do |format|
27
+ format.html # show.html.erb
28
+ format.json { render <%= key_value :json, "@#{singular_table_name}" %> }
29
+ end
30
+ end
31
+
32
+ # GET <%= route_url %>/new
33
+ # GET <%= route_url %>/new.json
34
+ def new
35
+ @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
36
+
37
+ respond_to do |format|
38
+ format.html # new.html.erb
39
+ format.json { render <%= key_value :json, "@#{singular_table_name}" %> }
40
+ end
41
+ end
42
+
43
+ # GET <%= route_url %>/1/edit
44
+ def edit
45
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
46
+ end
47
+
48
+ # POST <%= route_url %>
49
+ # POST <%= route_url %>.json
50
+ def create
51
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "params[:#{singular_table_name}]") %>
52
+
53
+ respond_to do |format|
54
+ if @<%= orm_instance.save %>
55
+ format.html { redirect_to @<%= singular_table_name %>, <%= key_value :notice, "'#{human_name} was successfully created.'" %> }
56
+ format.json { render <%= key_value :json, "@#{singular_table_name}" %>, <%= key_value :status, ':created' %>, <%= key_value :location, "@#{singular_table_name}" %> }
57
+ else
58
+ format.html { render <%= key_value :action, '"new"' %> }
59
+ format.json { render <%= key_value :json, "@#{orm_instance.errors}" %>, <%= key_value :status, ':unprocessable_entity' %> }
60
+ end
61
+ end
62
+ end
63
+
64
+ # PUT <%= route_url %>/1
65
+ # PUT <%= route_url %>/1.json
66
+ def update
67
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
68
+
69
+ respond_to do |format|
70
+ if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %>
71
+ format.html { redirect_to @<%= singular_table_name %>, <%= key_value :notice, "'#{human_name} was successfully updated.'" %> }
72
+ format.json { head :ok }
73
+ else
74
+ format.html { render <%= key_value :action, '"edit"' %> }
75
+ format.json { render <%= key_value :json, "@#{orm_instance.errors}" %>, <%= key_value :status, ':unprocessable_entity' %> }
76
+ end
77
+ end
78
+ end
79
+
80
+ # DELETE <%= route_url %>/1
81
+ # DELETE <%= route_url %>/1.json
82
+ def destroy
83
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
84
+ @<%= orm_instance.destroy %>
85
+
86
+ respond_to do |format|
87
+ format.html { redirect_to <%= index_helper %>_url, <%= key_value :notice, "'#{human_name} deleted.'" %> }
88
+ format.json { head :ok }
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def sort_column
95
+ <%= class_name %>.column_names.include?(params[:sort]) ? params[:sort] : SEARCH_ATTR
96
+ end
97
+
98
+ def sort_direction
99
+ %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
100
+ end
101
+ end
102
+ <% end -%>