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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE.txt → MIT-LICENSE} +1 -1
  3. data/README.md +52 -8
  4. data/Rakefile +17 -44
  5. data/app/assets/javascripts/bootstrap_builders/application.js +13 -0
  6. data/app/assets/stylesheets/bootstrap_builders/application.css +15 -0
  7. data/app/controllers/bootstrap_builders/application_controller.rb +2 -0
  8. data/app/helpers/bootstrap_builders/application_helper.rb +104 -0
  9. data/app/views/layouts/bootstrap_builders/application.html.erb +14 -0
  10. data/config/routes.rb +2 -0
  11. data/config/spring.rb +1 -0
  12. data/lib/bootstrap_builders.rb +15 -5
  13. data/lib/bootstrap_builders/attribute_rows.rb +95 -0
  14. data/lib/bootstrap_builders/button.rb +90 -22
  15. data/lib/bootstrap_builders/class_attribute_handler.rb +20 -0
  16. data/lib/bootstrap_builders/configuration.rb +7 -0
  17. data/lib/bootstrap_builders/engine.rb +3 -0
  18. data/lib/bootstrap_builders/is_a_checker.rb +14 -0
  19. data/lib/bootstrap_builders/panel.rb +88 -0
  20. data/lib/bootstrap_builders/table.rb +44 -0
  21. data/lib/bootstrap_builders/version.rb +3 -0
  22. data/lib/tasks/bootstrap_builders_tasks.rake +4 -0
  23. metadata +158 -44
  24. data/.document +0 -5
  25. data/.rspec +0 -1
  26. data/.rubocop.yml +0 -60
  27. data/Gemfile +0 -14
  28. data/Gemfile.lock +0 -99
  29. data/VERSION +0 -1
  30. data/bootstrap_builders.gemspec +0 -76
  31. data/lib/bootstrap_builders/application_helpers.rb +0 -55
  32. data/lib/bootstrap_builders/box.rb +0 -66
  33. data/spec/bootstrap_helpers/box_spec.rb +0 -17
  34. data/spec/bootstrap_helpers/button_spec.rb +0 -12
  35. data/spec/spec_helper.rb +0 -12
  36. data/spec/support/working_helpers.rb +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc1068f1df81b83a1cbe318ab91a09f816a49703
4
- data.tar.gz: 3122ddf8127d24598e017d73a79fe4f15e927ef0
3
+ metadata.gz: c2e43bdc56f44def9fdde24067ba74e9496dd833
4
+ data.tar.gz: fec8d583324e41c4728d2ceb50f36e9567fd0076
5
5
  SHA512:
6
- metadata.gz: 43bece537feb0ddd22817f6880ba5eb5bc14806c95d572c5ef4fa8a3322904a1dff514861fffa406ad64daa69dea1285281d59d5a7d055e2656a2be6508265d6
7
- data.tar.gz: 5b7564b32f6e7b15f8cd4fd2d751b2f44a7c370d48cd545b28e726360ae34931d46e45db67a246b661895917fced47a8a4898b8304155e9e10582c34ee4d0c06
6
+ metadata.gz: 0f19384fe95607c4d333ae2cf2fab73f4b2db0adf4a698b3bb1c7e792bc7130a8c3b8a1b69f27b474b90009d4df8954f7f5fe4ecf865d309e0ce0661c8b95eec
7
+ data.tar.gz: bc903302b6ca80d51f885dd512a8a08a738bc6c7e52aad5c217a544ce7d865b61a80ed95c36e58b535453c6a038f5ba3aaad8103eca77e77fae64ec09ac43203
@@ -1,4 +1,4 @@
1
- Copyright (c) 2016 kaspernj
1
+ Copyright 2016 kaspernj
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # bootstrap_builders
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::Helpers
13
+ include BootstrapBuilders::ApplicationHelper
14
14
  end
15
15
  ```
16
16
 
17
17
  ## Usage
18
18
 
19
- ### Box
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
- = box "Title of box", right: button_content do
22
- Content of box
26
+ = bb_panel "Title of panel", right: button_content do
27
+ Content of panel
23
28
  ```
24
29
 
25
- ### Box with a table
30
+ ### Panel with a table
31
+
26
32
  ```haml
27
- = box "Title of box", table: true do
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
- Bundler.setup(:default, :development)
7
- rescue Bundler::BundlerError => e
8
- $stderr.puts e.message
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 = "bootstrap_builders #{version}"
48
- rdoc.rdoc_files.include("README*")
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
- require "best_practice_project"
53
- BestPracticeProject.load_tasks
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,2 @@
1
+ class BootstrapBuilders::ApplicationController < ActionController::Base
2
+ end
@@ -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
@@ -0,0 +1,2 @@
1
+ BootstrapBuilders::Engine.routes.draw do
2
+ end
data/config/spring.rb ADDED
@@ -0,0 +1 @@
1
+ Spring.application_root = "./spec/dummy"
@@ -1,9 +1,19 @@
1
+ require "bootstrap_builders/engine"
2
+ require "haml"
1
3
  require "html_gen"
2
4
 
3
- class BootstrapBuilders
4
- path = "#{File.dirname(__FILE__)}/bootstrap_builders"
5
+ module BootstrapBuilders
6
+ extend ActiveSupport::Autoload
5
7
 
6
- autoload :ApplicationHelpers, "#{path}/application_helpers"
7
- autoload :Box, "#{path}/box"
8
- autoload :Button, "#{path}/button"
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