tableize 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +132 -0
- data/lib/tableize.rb +4 -0
- data/lib/tableize/column_builder.rb +77 -0
- data/lib/tableize/helper.rb +8 -0
- data/lib/tableize/table_builder.rb +130 -0
- data/lib/tableize/utils.rb +11 -0
- data/lib/version.rb +7 -0
- data/tableize.gemspec +20 -0
- data/test/app/.gitignore +5 -0
- data/test/app/Gemfile +43 -0
- data/test/app/Gemfile.lock +138 -0
- data/test/app/README +261 -0
- data/test/app/Rakefile +7 -0
- data/test/app/app/assets/images/rails.png +0 -0
- data/test/app/app/assets/javascripts/application.js +9 -0
- data/test/app/app/assets/stylesheets/application.css +7 -0
- data/test/app/app/controllers/application_controller.rb +3 -0
- data/test/app/app/controllers/posts_controller.rb +5 -0
- data/test/app/app/helpers/application_helper.rb +2 -0
- data/test/app/app/mailers/.gitkeep +0 -0
- data/test/app/app/models/.gitkeep +0 -0
- data/test/app/app/models/post.rb +5 -0
- data/test/app/app/views/layouts/application.html.erb +14 -0
- data/test/app/app/views/posts/index.html.haml +3 -0
- data/test/app/config.ru +4 -0
- data/test/app/config/application.rb +48 -0
- data/test/app/config/boot.rb +6 -0
- data/test/app/config/database.yml +25 -0
- data/test/app/config/environment.rb +5 -0
- data/test/app/config/environments/development.rb +30 -0
- data/test/app/config/environments/production.rb +60 -0
- data/test/app/config/environments/test.rb +39 -0
- data/test/app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/app/config/initializers/inflections.rb +10 -0
- data/test/app/config/initializers/mime_types.rb +5 -0
- data/test/app/config/initializers/secret_token.rb +7 -0
- data/test/app/config/initializers/session_store.rb +8 -0
- data/test/app/config/initializers/wrap_parameters.rb +14 -0
- data/test/app/config/locales/en.yml +10 -0
- data/test/app/config/routes.rb +58 -0
- data/test/app/db/migrate/20111008184259_create_posts.rb +11 -0
- data/test/app/db/schema.rb +24 -0
- data/test/app/db/seeds.rb +13 -0
- data/test/app/doc/README_FOR_APP +2 -0
- data/test/app/lib/assets/.gitkeep +0 -0
- data/test/app/lib/tasks/.gitkeep +0 -0
- data/test/app/log/.gitkeep +0 -0
- data/test/app/public/404.html +26 -0
- data/test/app/public/422.html +26 -0
- data/test/app/public/500.html +26 -0
- data/test/app/public/favicon.ico +0 -0
- data/test/app/public/robots.txt +5 -0
- data/test/app/script/rails +6 -0
- data/test/app/test/fixtures/.gitkeep +0 -0
- data/test/app/test/fixtures/posts.yml +11 -0
- data/test/app/test/functional/.gitkeep +0 -0
- data/test/app/test/integration/.gitkeep +0 -0
- data/test/app/test/performance/browsing_test.rb +12 -0
- data/test/app/test/test_helper.rb +13 -0
- data/test/app/test/unit/.gitkeep +0 -0
- data/test/app/test/unit/post_test.rb +7 -0
- data/test/app/vendor/assets/stylesheets/.gitkeep +0 -0
- data/test/app/vendor/plugins/.gitkeep +0 -0
- metadata +109 -0
data/README.md
ADDED
@@ -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
|
data/lib/tableize.rb
ADDED
@@ -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,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
|
data/lib/version.rb
ADDED
data/tableize.gemspec
ADDED
@@ -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
|
data/test/app/.gitignore
ADDED
data/test/app/Gemfile
ADDED
@@ -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
|