tableize 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/README.md +132 -0
  2. data/lib/tableize.rb +4 -0
  3. data/lib/tableize/column_builder.rb +77 -0
  4. data/lib/tableize/helper.rb +8 -0
  5. data/lib/tableize/table_builder.rb +130 -0
  6. data/lib/tableize/utils.rb +11 -0
  7. data/lib/version.rb +7 -0
  8. data/tableize.gemspec +20 -0
  9. data/test/app/.gitignore +5 -0
  10. data/test/app/Gemfile +43 -0
  11. data/test/app/Gemfile.lock +138 -0
  12. data/test/app/README +261 -0
  13. data/test/app/Rakefile +7 -0
  14. data/test/app/app/assets/images/rails.png +0 -0
  15. data/test/app/app/assets/javascripts/application.js +9 -0
  16. data/test/app/app/assets/stylesheets/application.css +7 -0
  17. data/test/app/app/controllers/application_controller.rb +3 -0
  18. data/test/app/app/controllers/posts_controller.rb +5 -0
  19. data/test/app/app/helpers/application_helper.rb +2 -0
  20. data/test/app/app/mailers/.gitkeep +0 -0
  21. data/test/app/app/models/.gitkeep +0 -0
  22. data/test/app/app/models/post.rb +5 -0
  23. data/test/app/app/views/layouts/application.html.erb +14 -0
  24. data/test/app/app/views/posts/index.html.haml +3 -0
  25. data/test/app/config.ru +4 -0
  26. data/test/app/config/application.rb +48 -0
  27. data/test/app/config/boot.rb +6 -0
  28. data/test/app/config/database.yml +25 -0
  29. data/test/app/config/environment.rb +5 -0
  30. data/test/app/config/environments/development.rb +30 -0
  31. data/test/app/config/environments/production.rb +60 -0
  32. data/test/app/config/environments/test.rb +39 -0
  33. data/test/app/config/initializers/backtrace_silencers.rb +7 -0
  34. data/test/app/config/initializers/inflections.rb +10 -0
  35. data/test/app/config/initializers/mime_types.rb +5 -0
  36. data/test/app/config/initializers/secret_token.rb +7 -0
  37. data/test/app/config/initializers/session_store.rb +8 -0
  38. data/test/app/config/initializers/wrap_parameters.rb +14 -0
  39. data/test/app/config/locales/en.yml +10 -0
  40. data/test/app/config/routes.rb +58 -0
  41. data/test/app/db/migrate/20111008184259_create_posts.rb +11 -0
  42. data/test/app/db/schema.rb +24 -0
  43. data/test/app/db/seeds.rb +13 -0
  44. data/test/app/doc/README_FOR_APP +2 -0
  45. data/test/app/lib/assets/.gitkeep +0 -0
  46. data/test/app/lib/tasks/.gitkeep +0 -0
  47. data/test/app/log/.gitkeep +0 -0
  48. data/test/app/public/404.html +26 -0
  49. data/test/app/public/422.html +26 -0
  50. data/test/app/public/500.html +26 -0
  51. data/test/app/public/favicon.ico +0 -0
  52. data/test/app/public/robots.txt +5 -0
  53. data/test/app/script/rails +6 -0
  54. data/test/app/test/fixtures/.gitkeep +0 -0
  55. data/test/app/test/fixtures/posts.yml +11 -0
  56. data/test/app/test/functional/.gitkeep +0 -0
  57. data/test/app/test/integration/.gitkeep +0 -0
  58. data/test/app/test/performance/browsing_test.rb +12 -0
  59. data/test/app/test/test_helper.rb +13 -0
  60. data/test/app/test/unit/.gitkeep +0 -0
  61. data/test/app/test/unit/post_test.rb +7 -0
  62. data/test/app/vendor/assets/stylesheets/.gitkeep +0 -0
  63. data/test/app/vendor/plugins/.gitkeep +0 -0
  64. metadata +109 -0
@@ -0,0 +1,132 @@
1
+ Tableize
2
+ ========
3
+
4
+ Installation
5
+ ------------
6
+ gem install tableize
7
+
8
+ Examples
9
+ -----
10
+ #### Basic
11
+ table_for Post, @posts do |t|
12
+ t.column "Title", :title
13
+ t.column "Author", :author
14
+ end
15
+
16
+ Is the same as:
17
+
18
+ table_for do |t|
19
+ t.columns :title, :author
20
+ end
21
+
22
+ Both examples generate the following html:
23
+
24
+ <table class="posts">
25
+ <thead>
26
+ <tr>
27
+ <th class="title string">Title</th>
28
+ <th class="author string">Author</th>
29
+ </tr>
30
+ </thead>
31
+ <tbody>
32
+ <tr class="post_1">
33
+ <td>Hello World!</td>
34
+ <td>Christian Blais</td>
35
+ </tr>
36
+ </tbody>
37
+ </table>
38
+
39
+ #### Few defaults
40
+ * Inherited Resources
41
+
42
+ By default, `Tableize` will search for both `resource_class` and `collection` methods. So you don't have to specify them each time, unless
43
+ of course you want to override the default behavior. That being said, the following code produce the exact same output as the basic example
44
+ above.
45
+
46
+ table_for do |t|
47
+ t.column "Title", :title
48
+ t.column "Author", :author
49
+ end
50
+
51
+ * I18n
52
+
53
+ By default, `Tableize` will try to internationalised your attribute, so you don't have to name each of your column. So, assuming my
54
+ model responds to `human_attribute_name`, the following example still produces the exact same output.
55
+
56
+ table_for do |t|
57
+ t.column :title
58
+ t.column :author
59
+ end
60
+
61
+ * Columns
62
+
63
+ `Tableize` responds to `defaults` method, which will create a column for each public attribute of your model. Use it like this:
64
+
65
+ table_for do |t|
66
+ t.defaults
67
+ end
68
+
69
+ * Multiple columns, one line
70
+
71
+ table_for do |t|
72
+ t.columns :title, :author
73
+ end
74
+
75
+ #### Advanced features
76
+ * Lambdas
77
+
78
+ You can use lambdas if you want to have a custom column.
79
+
80
+ table_for do |t|
81
+ t.column "Title" do |post|
82
+ post.title + "!"
83
+ end
84
+ end
85
+
86
+ You can also specify a method to be called before the yield.
87
+
88
+ table_for do |t|
89
+ t.column "Title", :title do |title|
90
+ title + "!"
91
+ end
92
+ end
93
+
94
+ * Extras
95
+
96
+ Let's say `author` is a relation, and you want to show his first name and last name as separate columns. The following would works:
97
+
98
+ table_for do |t|
99
+ t.column "First name", :author do |author|
100
+ author.first_name
101
+ end
102
+ t.column "Last name", :author do |author|
103
+ author.last_name
104
+ end
105
+ end
106
+
107
+ But the above code triggers the `author` method twice. In order to avoid that, you could use the `extra` method, which will be executed only
108
+ once per row, yielding the result alongside the resource in each block. You can use more than one extra without any problem.
109
+
110
+ table_for do |t|
111
+ t.extra do |post|
112
+ post.author
113
+ end
114
+
115
+ t.column "First name" do |post, author|
116
+ author.first_name
117
+ end
118
+ t.column "Last name" do |post, author|
119
+ author.last_name
120
+ end
121
+ end
122
+
123
+ * Hashes
124
+
125
+ `Tableize` also accepts hashes instead of regular collections. Use it the same way.
126
+
127
+ collection = [{:title => "Hello World", "author" => "Christian Blais"}]
128
+
129
+ table_for Post, collection do |t|
130
+ t.column :title
131
+ t.column "author"
132
+ end
@@ -0,0 +1,4 @@
1
+ require File.dirname(__FILE__) + "/tableize/helper"
2
+ require File.dirname(__FILE__) + "/tableize/utils"
3
+ require File.dirname(__FILE__) + "/tableize/table_builder"
4
+ require File.dirname(__FILE__) + "/tableize/column_builder"
@@ -0,0 +1,77 @@
1
+ module Tableize
2
+ class ColumnBuilder
3
+
4
+ attr_reader :title, :method
5
+
6
+ def initialize(resource_class, *args, &block)
7
+ @options = args.extract_options!
8
+ @resource_class = resource_class
9
+ @html_options = @options.delete(:html) || {}
10
+ @block = block
11
+ @title = get_title(args)
12
+ @method = get_method(args)
13
+ end
14
+
15
+ def value(resource, extras)
16
+ if @block
17
+ @method ? @block.call(resource.send(@method), *extras) : @block.call(resource, *extras)
18
+ else
19
+ if @method
20
+ if resource.respond_to?(@method)
21
+ resource.send(@method)
22
+ elsif resource.kind_of?(Hash)
23
+ resource[@method]
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def td_options
30
+ get_options(:td)
31
+ end
32
+
33
+ def th_options
34
+ options = get_options(:th)
35
+
36
+ if @method
37
+ options[:class] = Tableize::convert_to_array(options[:class], @method.to_s.underscore, value_type)
38
+ end
39
+
40
+ options
41
+ end
42
+
43
+ protected
44
+
45
+ def get_options(key)
46
+ @html_options[key] || {}
47
+ end
48
+
49
+ def get_title(args)
50
+ if title = args.first
51
+ if title.kind_of?(String)
52
+ args.shift
53
+ elsif @options.key?(:title)
54
+ @options[:title]
55
+ elsif title.kind_of?(Symbol) && @resource_class.respond_to?(:human_attribute_name)
56
+ @resource_class.send(:human_attribute_name, title)
57
+ else
58
+ title.to_s
59
+ end
60
+ end
61
+ end
62
+
63
+ def get_method(args)
64
+ if method = args.last
65
+ method
66
+ end
67
+ end
68
+
69
+ def value_type
70
+ if @method && @resource_class.respond_to?(:columns)
71
+ if column = @resource_class.columns.detect{ |column| column.name.to_sym == @method }
72
+ column.type
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,8 @@
1
+ module Tableize
2
+ def table_for(*args, &block)
3
+ Tableize::TableBuilder.new(self, *args, &block).render
4
+ end
5
+ alias_method :table, :table_for
6
+ end
7
+
8
+ ActionView::Base.send :include, Tableize
@@ -0,0 +1,130 @@
1
+ module Tableize
2
+ class TableBuilder
3
+
4
+ delegate :content_tag, :to => :@view_context
5
+
6
+ DEFAULT_OPTIONS = {
7
+ :default_table_class => true,
8
+ :default_tr_class => true
9
+ }
10
+
11
+ def initialize(view_context, *args, &block)
12
+ @options = DEFAULT_OPTIONS.merge(args.extract_options!)
13
+ @table_options = @options.delete(:html) || {}
14
+ @tr_options = @table_options.delete(:tr) || {}
15
+ @view_context = view_context
16
+ @block = block
17
+ @resource_class = get_resource_class(args)
18
+ @collection = get_collection(args)
19
+ @columns = []
20
+ @extras = []
21
+ end
22
+
23
+ def defaults
24
+ (@resource_class.new.attributes.keys - @resource_class.protected_attributes.to_a).each do |attribute|
25
+ column(attribute.to_sym)
26
+ end
27
+ end
28
+
29
+ def columns(*args)
30
+ args.each do |arg|
31
+ column(arg)
32
+ end
33
+ end
34
+
35
+ def column(*args, &block)
36
+ @columns << Tableize::ColumnBuilder.new(@resource_class, *args, &block)
37
+ end
38
+
39
+ def extra(&block)
40
+ @extras << block if block_given?
41
+ end
42
+
43
+ def render
44
+ @view_context.capture{ @block.call(self) }
45
+
46
+ content_tag(:table, table_options) do
47
+ [thead, tbody].join.html_safe
48
+ end
49
+ end
50
+
51
+ protected
52
+
53
+ def thead
54
+ content_tag(:thead) do
55
+ content_tag(:tr) do
56
+ @columns.map do |column|
57
+ content_tag(:th, column.th_options) do
58
+ column.title
59
+ end
60
+ end.join.html_safe
61
+ end
62
+ end
63
+ end
64
+
65
+ def tbody
66
+ content_tag(:tbody) do
67
+ @collection.map do |resource|
68
+ extras = @extras.map{ |block| block.call(resource) }
69
+
70
+ content_tag(:tr, tr_options(resource)) do
71
+ @columns.map do |column|
72
+ content_tag(:td, column.td_options) do
73
+ column.value(resource, extras).to_s.html_safe
74
+ end
75
+ end.join.html_safe
76
+ end
77
+ end.join.html_safe
78
+ end
79
+ end
80
+
81
+ def table_options
82
+ options = @table_options.dup
83
+
84
+ if @options[:default_table_class] && @resource_class.respond_to?(:model_name)
85
+ options[:class] = Tableize::convert_to_array(options[:class], @resource_class.model_name.tableize)
86
+ end
87
+
88
+ options
89
+ end
90
+
91
+ def tr_options(resource)
92
+ options = @tr_options.dup
93
+
94
+ if @options[:default_tr_class] && @resource_class.respond_to?(:model_name)
95
+ options[:class] = Tableize::convert_to_array(options[:class], "#{@resource_class.model_name.underscore}_#{get_resource_id(resource)}")
96
+ end
97
+
98
+ options
99
+ end
100
+
101
+ def get_resource_id(resource)
102
+ if resource.respond_to?(:id)
103
+ resource.id
104
+ elsif resource.kind_of?(Hash)
105
+ resource[:id] || resource["id"]
106
+ end
107
+ end
108
+
109
+ def get_resource_class(args)
110
+ if resource_class = args.shift
111
+ resource_class
112
+ elsif @options.key?(:resource_class)
113
+ @options[:resource_class]
114
+ elsif @view_context.respond_to?(:resource_class)
115
+ @view_context.resource_class
116
+ end
117
+ end
118
+
119
+ def get_collection(args)
120
+ if collection = args.shift
121
+ collection
122
+ elsif @options.key?(:collection)
123
+ @options[:collection]
124
+ elsif @view_context.respond_to?(:collection)
125
+ @view_context.collection
126
+ end
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,11 @@
1
+ module Tableize
2
+ def self.convert_to_array(array, *args)
3
+ array = [array].flatten.compact
4
+
5
+ args.each do |arg|
6
+ array.push(arg)
7
+ end
8
+
9
+ array
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Tableize
2
+ MAJOR = 0
3
+ MINOR = 0
4
+ BUILD = 1
5
+
6
+ VERSION = "#{MAJOR}.#{MINOR}.#{BUILD}"
7
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require './lib/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "tableize"
9
+ s.version = Tableize::VERSION
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = ["Christian Blais"]
12
+ s.email = ["christ.blais@gmail.com"]
13
+ s.homepage = "http://github.com/christianblais/tableize"
14
+ s.summary = "Simple table helper"
15
+ s.description = "Simple table helper"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+
19
+ s.require_paths = ['lib', 'test']
20
+ end
@@ -0,0 +1,5 @@
1
+ .bundle
2
+ db/*.sqlite3
3
+ log/*.log
4
+ tmp/
5
+ .sass-cache/
@@ -0,0 +1,43 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rails', '3.1.1'
4
+
5
+ # Bundle edge Rails instead:
6
+ # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
+
8
+ gem 'sqlite3'
9
+ gem 'haml'
10
+ gem 'utilities'
11
+ gem 'inherited_resources'
12
+ gem 'tableize', :path => "~/projects/gems/tableize"
13
+
14
+ # Gems used only for assets and not required
15
+ # in production environments by default.
16
+ group :assets do
17
+ gem 'sass-rails', '~> 3.1.4'
18
+ gem 'coffee-rails', '~> 3.1.1'
19
+ gem 'uglifier', '>= 1.0.3'
20
+ end
21
+
22
+ gem 'jquery-rails'
23
+
24
+ # To use ActiveModel has_secure_password
25
+ # gem 'bcrypt-ruby', '~> 3.0.0'
26
+
27
+ # Use unicorn as the web server
28
+ # gem 'unicorn'
29
+
30
+ # Deploy with Capistrano
31
+ # gem 'capistrano'
32
+
33
+ # To use debugger
34
+ # gem 'ruby-debug19', :require => 'ruby-debug'
35
+
36
+ # fixing /gems/execjs-1.2.4/lib/execjs/runtimes.rb:45:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
37
+ gem 'execjs'
38
+ gem 'therubyracer'
39
+
40
+ group :test do
41
+ # Pretty printed test output
42
+ gem 'turn', :require => false
43
+ end