bootstrap_builders 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{LICENSE.txt → MIT-LICENSE} +1 -1
- data/README.md +52 -8
- data/Rakefile +17 -44
- data/app/assets/javascripts/bootstrap_builders/application.js +13 -0
- data/app/assets/stylesheets/bootstrap_builders/application.css +15 -0
- data/app/controllers/bootstrap_builders/application_controller.rb +2 -0
- data/app/helpers/bootstrap_builders/application_helper.rb +104 -0
- data/app/views/layouts/bootstrap_builders/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/config/spring.rb +1 -0
- data/lib/bootstrap_builders.rb +15 -5
- data/lib/bootstrap_builders/attribute_rows.rb +95 -0
- data/lib/bootstrap_builders/button.rb +90 -22
- data/lib/bootstrap_builders/class_attribute_handler.rb +20 -0
- data/lib/bootstrap_builders/configuration.rb +7 -0
- data/lib/bootstrap_builders/engine.rb +3 -0
- data/lib/bootstrap_builders/is_a_checker.rb +14 -0
- data/lib/bootstrap_builders/panel.rb +88 -0
- data/lib/bootstrap_builders/table.rb +44 -0
- data/lib/bootstrap_builders/version.rb +3 -0
- data/lib/tasks/bootstrap_builders_tasks.rake +4 -0
- metadata +158 -44
- data/.document +0 -5
- data/.rspec +0 -1
- data/.rubocop.yml +0 -60
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -99
- data/VERSION +0 -1
- data/bootstrap_builders.gemspec +0 -76
- data/lib/bootstrap_builders/application_helpers.rb +0 -55
- data/lib/bootstrap_builders/box.rb +0 -66
- data/spec/bootstrap_helpers/box_spec.rb +0 -17
- data/spec/bootstrap_helpers/button_spec.rb +0 -12
- data/spec/spec_helper.rb +0 -12
- data/spec/support/working_helpers.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2e43bdc56f44def9fdde24067ba74e9496dd833
|
4
|
+
data.tar.gz: fec8d583324e41c4728d2ceb50f36e9567fd0076
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f19384fe95607c4d333ae2cf2fab73f4b2db0adf4a698b3bb1c7e792bc7130a8c3b8a1b69f27b474b90009d4df8954f7f5fe4ecf865d309e0ce0661c8b95eec
|
7
|
+
data.tar.gz: bc903302b6ca80d51f885dd512a8a08a738bc6c7e52aad5c217a544ce7d865b61a80ed95c36e58b535453c6a038f5ba3aaad8103eca77e77fae64ec09ac43203
|
data/{LICENSE.txt → MIT-LICENSE}
RENAMED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# BootstrapBuilders
|
2
2
|
|
3
3
|
## Install
|
4
4
|
|
@@ -10,24 +10,69 @@ gem "bootstrap_builders"
|
|
10
10
|
Then add to your `ApplicationHelper` module:
|
11
11
|
```ruby
|
12
12
|
module ApplicationHelper
|
13
|
-
include BootstrapBuilders::
|
13
|
+
include BootstrapBuilders::ApplicationHelper
|
14
14
|
end
|
15
15
|
```
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
|
19
|
-
###
|
19
|
+
### Panel
|
20
|
+
|
21
|
+
1. Panel in all its glory with elements and classes
|
22
|
+
2. Controls if `:right` argument is given
|
23
|
+
3. Table if `:table` argument is given
|
24
|
+
|
20
25
|
```haml
|
21
|
-
=
|
22
|
-
Content of
|
26
|
+
= bb_panel "Title of panel", right: button_content do
|
27
|
+
Content of panel
|
23
28
|
```
|
24
29
|
|
25
|
-
###
|
30
|
+
### Panel with a table
|
31
|
+
|
26
32
|
```haml
|
27
|
-
=
|
33
|
+
= bb_panel "Title of panel", table: true do
|
28
34
|
%tbody
|
29
35
|
%tr
|
30
36
|
%td= "Test"
|
37
|
+
```
|
38
|
+
|
39
|
+
You can add custom classes like this:
|
40
|
+
```haml
|
41
|
+
= bb_panel "Title of panel", table: {bs_classes: [:striped]} do
|
42
|
+
%tbody
|
43
|
+
%tr
|
44
|
+
%td Test
|
45
|
+
```
|
46
|
+
|
47
|
+
### Table
|
48
|
+
|
49
|
+
1. Adds Bootstrap classes: "table", "table-hover", "table-striped"
|
50
|
+
|
51
|
+
```haml
|
52
|
+
= bb_table do
|
53
|
+
%tbody
|
54
|
+
%tr
|
55
|
+
%td= "Test"
|
56
|
+
```
|
57
|
+
|
58
|
+
You can change the default classes like this:
|
59
|
+
```ruby
|
60
|
+
BootstrapBuilders.configuration.default_table_classes = [:striped, :hover]
|
61
|
+
```
|
62
|
+
|
63
|
+
The classes "bb-table" and "table" are always added.
|
64
|
+
|
65
|
+
### Buttons
|
66
|
+
|
67
|
+
1. Adds icons automatically
|
68
|
+
2. Adds labels automatically
|
69
|
+
3. Doesn't show button if CanCan doesn't allow it
|
70
|
+
|
71
|
+
```haml
|
72
|
+
= bb_new_btn url: [:admin, User]
|
73
|
+
= bb_edit_btn url: [:admin, user], mini: true
|
74
|
+
= bb_destroy_btn url: [:admin, user], label: false
|
75
|
+
```
|
31
76
|
|
32
77
|
## Contributing to bootstrap_builders
|
33
78
|
|
@@ -43,4 +88,3 @@ end
|
|
43
88
|
|
44
89
|
Copyright (c) 2016 kaspernj. See LICENSE.txt for
|
45
90
|
further details.
|
46
|
-
|
data/Rakefile
CHANGED
@@ -1,53 +1,26 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require "rubygems"
|
4
|
-
require "bundler"
|
5
1
|
begin
|
6
|
-
|
7
|
-
rescue
|
8
|
-
|
9
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
-
exit e.status_code
|
11
|
-
end
|
12
|
-
require "rake"
|
13
|
-
|
14
|
-
require "jeweler"
|
15
|
-
Jeweler::Tasks.new do |gem|
|
16
|
-
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
17
|
-
gem.name = "bootstrap_builders"
|
18
|
-
gem.homepage = "http://github.com/kaspernj/bootstrap_builders"
|
19
|
-
gem.license = "MIT"
|
20
|
-
gem.summary = %(A library to generate Bootstrap HTML for Rails.)
|
21
|
-
gem.description = %(A library to generate Bootstrap HTML for Rails.)
|
22
|
-
gem.email = "k@spernj.org"
|
23
|
-
gem.authors = ["kaspernj"]
|
24
|
-
# dependencies defined in Gemfile
|
2
|
+
require "bundler/setup"
|
3
|
+
rescue LoadError
|
4
|
+
puts "You must `gem install bundler` and `bundle install` to run rake tasks"
|
25
5
|
end
|
26
|
-
Jeweler::RubygemsDotOrgTasks.new
|
27
|
-
|
28
|
-
require "rspec/core"
|
29
|
-
require "rspec/core/rake_task"
|
30
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
-
spec.pattern = FileList["spec/**/*_spec.rb"]
|
32
|
-
end
|
33
|
-
|
34
|
-
desc "Code coverage detail"
|
35
|
-
task :simplecov do
|
36
|
-
ENV["COVERAGE"] = "true"
|
37
|
-
Rake::Task["spec"].execute
|
38
|
-
end
|
39
|
-
|
40
|
-
task default: :spec
|
41
6
|
|
42
7
|
require "rdoc/task"
|
43
|
-
Rake::RDocTask.new do |rdoc|
|
44
|
-
version = File.exist?("VERSION") ? File.read("VERSION") : ""
|
45
8
|
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
46
10
|
rdoc.rdoc_dir = "rdoc"
|
47
|
-
rdoc.title
|
48
|
-
rdoc.
|
11
|
+
rdoc.title = "BootstrapBuilders"
|
12
|
+
rdoc.options << "--line-numbers"
|
13
|
+
rdoc.rdoc_files.include("README.rdoc")
|
49
14
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
50
15
|
end
|
51
16
|
|
52
|
-
|
53
|
-
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load "rails/tasks/engine.rake"
|
19
|
+
load "rails/tasks/statistics.rake"
|
20
|
+
|
21
|
+
Bundler::GemHelper.install_tasks
|
22
|
+
|
23
|
+
if Rails.env.development? || Rails.env.test?
|
24
|
+
require "best_practice_project"
|
25
|
+
BestPracticeProject.load_tasks
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
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 any plugin's vendor/assets/javascripts directory 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
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
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 any plugin's vendor/assets/stylesheets directory 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 bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module BootstrapBuilders::ApplicationHelper
|
2
|
+
def bb_attribute_rows(model, attributes)
|
3
|
+
BootstrapBuilders::AttributeRows.new(model: model, attributes: attributes, context: self).html
|
4
|
+
end
|
5
|
+
|
6
|
+
def bb_panel(*opts, &blk)
|
7
|
+
title = opts.shift unless opts.first.is_a?(Hash)
|
8
|
+
width = opts.shift unless opts.first.is_a?(Hash)
|
9
|
+
|
10
|
+
if opts.length == 1 && opts.first.is_a?(Hash)
|
11
|
+
args = opts.first
|
12
|
+
title = args.fetch(:title) if args.key?(:title)
|
13
|
+
width = args[:width] if args.key?(:width)
|
14
|
+
right = args[:right] if args.key?(:right)
|
15
|
+
else
|
16
|
+
args = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
BootstrapBuilders::Panel.new(args.merge(title: title, width: width, right: right, block: blk, context: self)).html
|
20
|
+
end
|
21
|
+
|
22
|
+
def bb_btn(*args)
|
23
|
+
args = BootstrapBuilders::Button.parse_url_args(args)
|
24
|
+
args[:context] = self
|
25
|
+
button = BootstrapBuilders::Button.new(args)
|
26
|
+
button.classes.add("bb-btn")
|
27
|
+
button.html
|
28
|
+
end
|
29
|
+
|
30
|
+
def bb_edit_btn(*args)
|
31
|
+
args = BootstrapBuilders::Button.parse_url_args(args)
|
32
|
+
args[:label] = t("edit") unless args.key?(:label)
|
33
|
+
args[:title] ||= t("edit") if args[:mini]
|
34
|
+
args[:url] = [:edit, args.fetch(:url)] if args[:url] && !args[:url].is_a?(Array) && BootstrapBuilders::IsAChecker.is_a?(args[:url], "ActiveRecord::Base")
|
35
|
+
|
36
|
+
button = BootstrapBuilders::Button.new(args.merge(icon: "wrench", context: self, can_type: :edit))
|
37
|
+
button.classes.add(["bb-btn", "bb-btn-edit"])
|
38
|
+
button.classes.add("bb-btn-edit-#{button.can_model_class.name.tableize.singularize}") if button.can_model_class
|
39
|
+
button.classes.add("bb-btn-edit-#{button.can_model_class.name.tableize.singularize}-#{button.can_model.id}") if button.can_model
|
40
|
+
button.html
|
41
|
+
end
|
42
|
+
|
43
|
+
def bb_destroy_btn(*args)
|
44
|
+
args = BootstrapBuilders::Button.parse_url_args(args)
|
45
|
+
args[:label] = t("delete") unless args.key?(:label)
|
46
|
+
args[:title] ||= t("delete") if args[:mini]
|
47
|
+
|
48
|
+
args[:data] ||= {}
|
49
|
+
args[:data][:confirm] ||= t("are_you_sure")
|
50
|
+
|
51
|
+
button = BootstrapBuilders::Button.new(args.merge(icon: "remove", context: self, can_type: :destroy, method: :delete))
|
52
|
+
button.classes.add(["btn-danger", "bb-btn", "bb-btn-destroy"])
|
53
|
+
button.classes.add("bb-btn-destroy-#{button.can_model_class.name.tableize.singularize}") if button.can_model_class
|
54
|
+
button.classes.add("bb-btn-destroy-#{button.can_model_class.name.tableize.singularize}-#{button.can_model.id}") if button.can_model
|
55
|
+
button.html
|
56
|
+
end
|
57
|
+
|
58
|
+
def bb_new_btn(*args)
|
59
|
+
args = BootstrapBuilders::Button.parse_url_args(args)
|
60
|
+
args[:label] = t("add_new") unless args.key?(:label)
|
61
|
+
args[:title] ||= t("new") if args[:mini]
|
62
|
+
|
63
|
+
button = BootstrapBuilders::Button.new(args.merge(icon: "pencil", context: self, can_type: :new))
|
64
|
+
button.classes.add(["bb-btn", "bb-btn-new"])
|
65
|
+
button.classes.add("bb-btn-new-#{button.can_model_class.name.tableize.singularize}") if button.can_model_class
|
66
|
+
button.html
|
67
|
+
end
|
68
|
+
|
69
|
+
def bb_index_btn(*args)
|
70
|
+
args = BootstrapBuilders::Button.parse_url_args(args)
|
71
|
+
args[:title] ||= t("index") if args[:mini]
|
72
|
+
|
73
|
+
button = BootstrapBuilders::Button.new(args.merge(icon: "table", context: self, can_type: :index))
|
74
|
+
|
75
|
+
if button.label.to_s.strip.empty?
|
76
|
+
if button.can_model_class
|
77
|
+
button.label = button.can_model_class.model_name.human(count: 2)
|
78
|
+
else
|
79
|
+
button.label = t("index")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
button.classes.add(["bb-btn", "bb-btn-index"])
|
84
|
+
button.classes.add("bb-btn-index-#{button.can_model_class.name.tableize}") if button.can_model_class
|
85
|
+
button.html
|
86
|
+
end
|
87
|
+
|
88
|
+
def bb_show_btn(*args)
|
89
|
+
args = BootstrapBuilders::Button.parse_url_args(args)
|
90
|
+
args[:label] = t("show") unless args.key?(:label)
|
91
|
+
args[:title] ||= t("show") if args[:mini]
|
92
|
+
|
93
|
+
button = BootstrapBuilders::Button.new(args.merge(icon: "square-o", context: self, can_type: :show))
|
94
|
+
button.classes.add(["bb-btn", "bb-btn-show"])
|
95
|
+
button.classes.add("bb-btn-show-#{button.can_model_class.name.tableize.singularize}") if button.can_model_class
|
96
|
+
button.classes.add("bb-btn-show-#{button.can_model_class.name.tableize.singularize}-#{button.can_model.id}") if button.can_model
|
97
|
+
button.html
|
98
|
+
end
|
99
|
+
|
100
|
+
def bb_table(args = {}, &blk)
|
101
|
+
table = BootstrapBuilders::Table.new(args.merge(context: self, blk: blk))
|
102
|
+
table.html
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>BootstrapBuilders</title>
|
5
|
+
<%= stylesheet_link_tag "bootstrap_builders/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "bootstrap_builders/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
data/config/spring.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Spring.application_root = "./spec/dummy"
|
data/lib/bootstrap_builders.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
+
require "bootstrap_builders/engine"
|
2
|
+
require "haml"
|
1
3
|
require "html_gen"
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
+
module BootstrapBuilders
|
6
|
+
extend ActiveSupport::Autoload
|
5
7
|
|
6
|
-
autoload :
|
7
|
-
autoload :
|
8
|
-
autoload :
|
8
|
+
autoload :AttributeRows
|
9
|
+
autoload :Button
|
10
|
+
autoload :ClassAttributeHandler
|
11
|
+
autoload :Configuration
|
12
|
+
autoload :IsAChecker
|
13
|
+
autoload :Panel
|
14
|
+
autoload :Table
|
15
|
+
|
16
|
+
def self.configuration
|
17
|
+
@configuration ||= BootstrapBuilders::Configuration.new
|
18
|
+
end
|
9
19
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
class BootstrapBuilders::AttributeRows
|
2
|
+
def initialize(args)
|
3
|
+
@model = args.fetch(:model)
|
4
|
+
@attributes = args.fetch(:attributes)
|
5
|
+
@context = args.fetch(:context)
|
6
|
+
end
|
7
|
+
|
8
|
+
def html
|
9
|
+
elements = []
|
10
|
+
|
11
|
+
@attributes.each do |attribute|
|
12
|
+
tr = HtmlGen::Element.new(:tr, inden: " ", classes: ["bb-attributes-row", "bb-attributes-row-#{attribute}"])
|
13
|
+
tr.add_ele(:th, classes: ["bb-attributes-row-title"], str: @model.class.human_attribute_name(attribute))
|
14
|
+
|
15
|
+
if column_type(attribute) == :boolean
|
16
|
+
str = @model.__send__("#{attribute}?") ? @context.t("yes") : @context.t("no")
|
17
|
+
elsif column_type(attribute) == :model
|
18
|
+
model_value = column_value(attribute)
|
19
|
+
|
20
|
+
unless model_value.nil?
|
21
|
+
link_method_name = "link_to_#{StringCases.camel_to_snake(model_value.class.name)}"
|
22
|
+
|
23
|
+
if @view.respond_to?(:link_to_model)
|
24
|
+
str = @view.link_to_model(model_value)
|
25
|
+
elsif @context.respond_to?(link_method_name)
|
26
|
+
str_html = @context.__send__(link_method_name, model_value)
|
27
|
+
else
|
28
|
+
str = model_value.name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
elsif column_type(attribute) == :datetime || column_type(attribute) == :date
|
32
|
+
str = @context.l(column_value(attribute), format: :long) if column_value(attribute)
|
33
|
+
elsif column_type(attribute) == :money
|
34
|
+
str = @context.number_to_currency(column_value(attribute), unit: "")
|
35
|
+
else
|
36
|
+
str = column_value(attribute).to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
if str
|
40
|
+
tr.add_ele(:td, classes: ["bb-attributes-row-value"], str: str)
|
41
|
+
else
|
42
|
+
tr.add_ele(:td, classes: ["bb-attributes-row-value"], str_html: str_html)
|
43
|
+
end
|
44
|
+
|
45
|
+
elements << tr.html
|
46
|
+
end
|
47
|
+
|
48
|
+
html = elements.join("\n")
|
49
|
+
html = html.html_safe if html.respond_to?(:html_safe)
|
50
|
+
html
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def column_type(column)
|
56
|
+
return :state if column == :state && @model.class.respond_to?(:state_machine)
|
57
|
+
|
58
|
+
type = @model.class.columns_hash[column.to_s].try(:type)
|
59
|
+
return type if type
|
60
|
+
|
61
|
+
reflection = @model.class.reflections[column]
|
62
|
+
return :model if reflection && reflection.is_a?(ActiveRecord::Reflection::AssociationReflection)
|
63
|
+
|
64
|
+
return :money if @model.class.respond_to?(:monetized_attributes) && @model.class.monetized_attributes.key?(column)
|
65
|
+
|
66
|
+
value = column_value(column)
|
67
|
+
return :model if value.is_a?(ActiveRecord::Base)
|
68
|
+
|
69
|
+
reflection_association = @model.class.reflect_on_association(column)
|
70
|
+
return :model if reflection_association
|
71
|
+
|
72
|
+
return :method if @model.respond_to?(column)
|
73
|
+
|
74
|
+
raise "Couldn't find out type for column '#{column}' on class '#{@model.class.name}'."
|
75
|
+
end
|
76
|
+
|
77
|
+
def column_value(column)
|
78
|
+
translated_column_method = "#{column}_translated"
|
79
|
+
translated_column_method_end = "translated_#{column}"
|
80
|
+
translated_option_helper_method = "#{@model.class.name.underscore}_translated_#{column}"
|
81
|
+
translated_state_method_name = "#{@model.class.name.underscore}_translated_state"
|
82
|
+
|
83
|
+
if column == :state && @model.class.respond_to?(:state_machine) && @view.respond_to?(translated_state_method_name)
|
84
|
+
return @view.__send__(translated_state_method_name, @model)
|
85
|
+
elsif @view.respond_to?(translated_option_helper_method)
|
86
|
+
return @view.__send__(translated_option_helper_method, @model)
|
87
|
+
elsif @model.respond_to?(translated_column_method)
|
88
|
+
return @model.__send__(translated_column_method)
|
89
|
+
elsif @model.respond_to?(translated_column_method_end)
|
90
|
+
return @model.__send__(translated_column_method_end)
|
91
|
+
end
|
92
|
+
|
93
|
+
@model.__send__(column)
|
94
|
+
end
|
95
|
+
end
|