html_table 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +61 -0
- data/Rakefile +14 -0
- data/html_table.gemspec +24 -0
- data/lib/html_table.rb +17 -0
- data/lib/html_table/table_builder.rb +60 -0
- data/lib/html_table/table_builder/column_footers.rb +20 -0
- data/lib/html_table/table_builder/column_headers.rb +19 -0
- data/lib/html_table/table_row_builder.rb +25 -0
- data/lib/html_table/version.rb +3 -0
- data/test/row_test.rb +30 -0
- data/test/table_builder_test.rb +42 -0
- data/test/table_test.rb +12 -0
- data/test/test_helper.rb +29 -0
- metadata +80 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# html_table
|
2
|
+
|
3
|
+
Table creates horizontal html tables.
|
4
|
+
Table is very small and very DRY to use.
|
5
|
+
Their is no repetition between header definition and attribute definition.
|
6
|
+
Actually their is no thead definition.
|
7
|
+
|
8
|
+
## Example
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
table(products) do |row|
|
12
|
+
row.column :name
|
13
|
+
row.column :description
|
14
|
+
row.column :price
|
15
|
+
end
|
16
|
+
|
17
|
+
this generates (formatted for reading purposes)
|
18
|
+
|
19
|
+
<table>
|
20
|
+
<thead>
|
21
|
+
<th>name</th>
|
22
|
+
<th>description</th>
|
23
|
+
<th>price</th>
|
24
|
+
</thead>
|
25
|
+
|
26
|
+
<tbody>
|
27
|
+
<tr>
|
28
|
+
<td>Tomato</td>
|
29
|
+
<td>Delicious red fruit.</td>
|
30
|
+
<td>€14/kg</td>
|
31
|
+
</tr>
|
32
|
+
</tbody>
|
33
|
+
</table>
|
34
|
+
```
|
35
|
+
|
36
|
+
## Installation
|
37
|
+
|
38
|
+
gem install html_table
|
39
|
+
|
40
|
+
## Configuration
|
41
|
+
|
42
|
+
You could also specify a class attribute for the table using
|
43
|
+
|
44
|
+
table(collection, :class => "some_class")
|
45
|
+
|
46
|
+
|
47
|
+
If you're using it together with Rails you could try
|
48
|
+
|
49
|
+
table-rails -> still working on it
|
50
|
+
|
51
|
+
To use different column headers one should overwrite
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
class HtmlTable::TableBuilder
|
55
|
+
def column_translation column
|
56
|
+
I18n.t(column)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
Copyright (c) 2011 Tom Maeckelberghe, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the table plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
data/html_table.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "html_table/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "html_table"
|
7
|
+
s.version = HtmlTable::VERSION
|
8
|
+
s.authors = ["Tom Maeckelberghe"]
|
9
|
+
s.email = ["tom.maeckelberghe@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Table is very small and very DRY to use. Their is no repetition between header definition and attribute definition.}
|
12
|
+
s.description = %q{Creates horizontal html tables from ruby objects.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "html_table"
|
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
|
+
end
|
data/lib/html_table.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "html_table/version"
|
2
|
+
module HtmlTable
|
3
|
+
require File.join(File.dirname(__FILE__), '/html_table/table_row_builder')
|
4
|
+
require File.join(File.dirname(__FILE__), '/html_table/table_builder')
|
5
|
+
attr_reader :table_builder
|
6
|
+
def table(collection=@collection, *args, &block)
|
7
|
+
if collection && collection.any?
|
8
|
+
options = args.extract_options!
|
9
|
+
set_table_builder(collection, options, &block)
|
10
|
+
@table_builder.to_s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_table_builder(collection, options, &block)
|
15
|
+
@table_builder = TableBuilder.new(collection, options, &block)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class HtmlTable::TableBuilder
|
2
|
+
require File.join(File.dirname(__FILE__),"table_builder/column_headers")
|
3
|
+
|
4
|
+
attr_accessor :rows
|
5
|
+
|
6
|
+
def initialize(collection, options={}, &block)
|
7
|
+
init_instance_vars(options)
|
8
|
+
collection.each do |object|
|
9
|
+
@rows << HtmlTable::TableRowBuilder.new(object, &block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"<table#{attributes}>
|
15
|
+
#{thead}
|
16
|
+
#{tbody}
|
17
|
+
#{tfoot}
|
18
|
+
</table>"
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def init_instance_vars options
|
24
|
+
@rows = []
|
25
|
+
@class = options[:class]
|
26
|
+
@footer = options[:footer]
|
27
|
+
end
|
28
|
+
|
29
|
+
def attributes
|
30
|
+
if @class
|
31
|
+
" class='#{@class}'"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def thead
|
36
|
+
"<thead>#{column_headers}</thead>"
|
37
|
+
end
|
38
|
+
|
39
|
+
def tbody
|
40
|
+
"<tbody>#{@rows}</tbody>"
|
41
|
+
end
|
42
|
+
|
43
|
+
def tfoot
|
44
|
+
if @footer
|
45
|
+
"<tfoot>#{column_footers}</tfoot>"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def column_footers
|
50
|
+
ColumnFooters.new(first_row, @footer).to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
def column_headers
|
54
|
+
ColumnHeaders.new(first_row).to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
def first_row
|
58
|
+
@rows.first
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class HtmlTable::TableBuilder::ColumnFooters
|
2
|
+
attr_reader :row, :footer
|
3
|
+
|
4
|
+
def initialize(row, footer)
|
5
|
+
@columns = row.columns
|
6
|
+
@row = row
|
7
|
+
@footer = footer
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
@columns.map do |column|
|
12
|
+
"<th>#{footer_or_empty(column)}</th>"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def footer_or_empty column
|
17
|
+
footer[column] || " "
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class HtmlTable::TableBuilder::ColumnHeaders
|
2
|
+
attr_reader :row
|
3
|
+
|
4
|
+
def initialize(row)
|
5
|
+
@columns = row.columns
|
6
|
+
@row = row
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
@columns.map do |column|
|
11
|
+
"<th>#{column_translation(column)}</th>"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def column_translation column
|
16
|
+
column
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class HtmlTable::TableRowBuilder
|
2
|
+
attr_accessor :columns, :html_columns
|
3
|
+
attr_reader :object
|
4
|
+
def initialize(object)
|
5
|
+
@object = object
|
6
|
+
@columns = []
|
7
|
+
@html_columns = []
|
8
|
+
yield(self)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"<tr>#{html_columns}</tr>"
|
13
|
+
end
|
14
|
+
|
15
|
+
def column column_name, *args
|
16
|
+
options = args.extract_options!
|
17
|
+
columns << column_name
|
18
|
+
html_columns << "<td>#{value(column_name, options)}</td>"
|
19
|
+
html_columns.last
|
20
|
+
end
|
21
|
+
|
22
|
+
def value column_name, options
|
23
|
+
options[:value] || column_name && object.send(column_name)
|
24
|
+
end
|
25
|
+
end
|
data/test/row_test.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
class RowTest < Test::Unit::TestCase
|
3
|
+
|
4
|
+
OBJECT = stubs_obj(:name => "A object", :description => "A description")
|
5
|
+
|
6
|
+
ROW = TableRowBuilder.new(OBJECT) do |row|
|
7
|
+
row.column :name
|
8
|
+
row.column :description
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_columns
|
12
|
+
assert_equal ([:name, :description]), ROW.columns
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_to_s
|
16
|
+
assert_match "<tr><td>A object</td><td>A description</td></tr>", ROW.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_object
|
20
|
+
assert_equal OBJECT, ROW.object
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_column
|
24
|
+
TableRowBuilder.new(OBJECT) do |row|
|
25
|
+
assert_equal "<td>A object</td>", row.column(:name)
|
26
|
+
assert_equal "<td>alternate value</td>", row.column(:name, :value => "alternate value")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
class TableBuilderTest < Test::Unit::TestCase
|
3
|
+
|
4
|
+
COLLECTION = [
|
5
|
+
stubs_obj(:name => "First Object", :description => "Testing table"),
|
6
|
+
stubs_obj(:name => "Second Object", :description => "This tests if table can display two rows")
|
7
|
+
]
|
8
|
+
|
9
|
+
TABLE = TableBuilder.new(COLLECTION) do |row|
|
10
|
+
row.column :name
|
11
|
+
row.column :description
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_rows
|
15
|
+
assert_equal 2, TABLE.rows.size
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_thead
|
19
|
+
assert_equal "<thead><th>name</th><th>description</th></thead>", TABLE.send(:thead)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_tbody
|
23
|
+
assert_equal "<tbody><tr><td>First Object</td><td>Testing table</td></tr><tr><td>Second Object</td><td>This tests if table can display two rows</td></tr></tbody>", TABLE.send(:tbody)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_to_s
|
27
|
+
TABLE.stubs(:thead).returns("thead")
|
28
|
+
TABLE.stubs(:tbody).returns("tbody")
|
29
|
+
TABLE.stubs(:attributes).returns("_with_attr")
|
30
|
+
assert_equal "<table_with_attr>theadtbody</table>", TABLE.to_s.gsub(/\n|\s/i, "")
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_attributes
|
34
|
+
table = TableBuilder.new(COLLECTION, {:class => "test_class"}) {}
|
35
|
+
assert_equal " class='test_class'", table.send(:attributes)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_empty_collection
|
39
|
+
assert_nil table([])
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/test/table_test.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
class TableSomethingTest < Test::Unit::TestCase
|
3
|
+
include ::TableViewHelper
|
4
|
+
def test_table
|
5
|
+
TableBuilder.any_instance.stubs(:to_s).returns("table")
|
6
|
+
assert_equal "table", table(["something"], :class => "test_extract_options") {}
|
7
|
+
assert_equal " class='test_extract_options'", @table_builder.send(:attributes)
|
8
|
+
table(["something"]) {}
|
9
|
+
assert_nil @table_builder.send(:attributes)
|
10
|
+
TableBuilder.any_instance.unstub(:to_s)
|
11
|
+
end
|
12
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
def self.rails_loaded?
|
4
|
+
!! defined?(RAILS_ENV)
|
5
|
+
end
|
6
|
+
|
7
|
+
unless rails_loaded?
|
8
|
+
require "rubygems"
|
9
|
+
require "test/unit"
|
10
|
+
require 'mocha'
|
11
|
+
require "ostruct"
|
12
|
+
require "active_support/core_ext/array/extract_options"
|
13
|
+
module TableViewHelper; end
|
14
|
+
require File.join(File.dirname(__FILE__), '/../lib/html_table')
|
15
|
+
require File.join(File.dirname(__FILE__), '/../lib/html_table/table_row_builder')
|
16
|
+
require File.join(File.dirname(__FILE__), '/../lib/html_table/table_builder')
|
17
|
+
end
|
18
|
+
|
19
|
+
class Test::Unit::TestCase
|
20
|
+
include HtmlTable
|
21
|
+
end
|
22
|
+
|
23
|
+
def rails_loaded
|
24
|
+
self.class.rails_loaded?
|
25
|
+
end
|
26
|
+
|
27
|
+
def stubs_obj(*args)
|
28
|
+
::OpenStruct.new(*args)
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: html_table
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Tom Maeckelberghe
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-02-12 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Creates horizontal html tables from ruby objects.
|
22
|
+
email:
|
23
|
+
- tom.maeckelberghe@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- Gemfile
|
33
|
+
- README.md
|
34
|
+
- Rakefile
|
35
|
+
- html_table.gemspec
|
36
|
+
- lib/html_table.rb
|
37
|
+
- lib/html_table/table_builder.rb
|
38
|
+
- lib/html_table/table_builder/column_footers.rb
|
39
|
+
- lib/html_table/table_builder/column_headers.rb
|
40
|
+
- lib/html_table/table_row_builder.rb
|
41
|
+
- lib/html_table/version.rb
|
42
|
+
- test/row_test.rb
|
43
|
+
- test/table_builder_test.rb
|
44
|
+
- test/table_test.rb
|
45
|
+
- test/test_helper.rb
|
46
|
+
homepage: ""
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project: html_table
|
75
|
+
rubygems_version: 1.8.10
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: Table is very small and very DRY to use. Their is no repetition between header definition and attribute definition.
|
79
|
+
test_files: []
|
80
|
+
|