tangofoxtrot-table_helper 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,45 @@
1
+ == master
2
+
3
+ == 0.2.1 / 2009-04-25
4
+
5
+ * Automatically determine the colspan for the last footer to match the number of headers
6
+ * Fix default headers including all model columns when using :select in the collection query
7
+
8
+ == 0.2.0 / 2009-04-25
9
+
10
+ * Reorganize documentation
11
+ * Allow css classes to be customized
12
+ * Use the jQuery UI css naming convention
13
+ * Allow multiple headers to be created at once
14
+ * No longer allow pre-existing headers to be customized (instead must re-define all headers)
15
+ * Remove :header / :footer options
16
+ * Simplify public interface
17
+
18
+ == 0.1.0 / 2008-12-14
19
+
20
+ * Remove the PluginAWeek namespace
21
+ * Update tests to use ActionView::TestCase
22
+
23
+ == 0.0.5 / 2008-06-22
24
+
25
+ * Remove log files from gems
26
+
27
+ == 0.0.4 / 2008-06-15
28
+
29
+ * Support cell/column names that conflict with existing method names on the Row/Header classes
30
+ * Avoid string evaluation for dynamic methods
31
+
32
+ == 0.0.3 / 2008-06-01
33
+
34
+ * Remove dependency on set_or_append
35
+
36
+ == 0.0.2 / 2008-05-05
37
+
38
+ * Updated documentation
39
+
40
+ == 0.0.1 / 2007-08-18
41
+
42
+ * Add README documentation
43
+ * Add gem dependency on set_or_append
44
+ * Refactor test method names
45
+ * Convert dos newlines to unix newlines
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2009 Aaron Pfeifer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,171 @@
1
+ = table_helper
2
+
3
+ +table_helper+ adds a helper method for generating HTML tables from collections.
4
+
5
+ == Resources
6
+
7
+ API
8
+
9
+ * http://api.pluginaweek.org/table_helper
10
+
11
+ Bugs
12
+
13
+ * http://pluginaweek.lighthouseapp.com/projects/13290-table_helper
14
+
15
+ Development
16
+
17
+ * http://github.com/pluginaweek/table_helper
18
+
19
+ Source
20
+
21
+ * git://github.com/pluginaweek/table_helper.git
22
+
23
+ == Description
24
+
25
+ Tables of summary data for ActiveRecord models are often formatted in the same
26
+ way by creating a header indicating the attribute and a body containing the
27
+ data from each record in separate rows. table_helper makes it easier to create
28
+ these types of tables by DRYing much of the html being generated.
29
+
30
+ == Usage
31
+
32
+ === Basic Example
33
+
34
+ <%= collection_table Person.find(:all) %>
35
+
36
+ ...is compiled to (formatted here for the sake of sanity):
37
+
38
+ <table cellpadding="0" cellspacing="0" class="people ui-collection">
39
+ <thead>
40
+ <tr>
41
+ <th class="person-first_name" scope="col">First Name</th>
42
+ <th class="person-last_name" scope="col">Last Name</th>
43
+ <th class="person-company_id" scope="col">Company</th>
44
+ <th class="person-role" scope="col">Role</th>
45
+ </tr>
46
+ </thead>
47
+ <tbody>
48
+ <tr class="person ui-collection-result">
49
+ <td class="person-first_name">John</td>
50
+ <td class="person-last_name">Doe</td>
51
+ <td class="person-company_id">1</td>
52
+ <td class="person-role">President</td>
53
+ </tr>
54
+ <tr class="person ui-collection-result">
55
+ <td class="person-first_name">Jane</td>
56
+ <td class="person-last_name">Doe</td>
57
+ <td class="person-company_id">1</td>
58
+ <td class="person-role">Vice-President</td>
59
+ </tr>
60
+ </tbody>
61
+ <table>
62
+
63
+ === Advanced Example
64
+
65
+ <%=
66
+ collection_table(@posts, :id => 'posts', :class => 'summary') do |t|
67
+ t.header :title
68
+ t.header :category
69
+ t.header :author
70
+ t.header :publish_date, 'Date<br \>Published'
71
+ t.header :num_comments, '# Comments'
72
+ t.header :num_trackbacks, '# Trackbacks'
73
+
74
+ t.rows.alternate = :odd
75
+ t.rows.each do |row, post, index|
76
+ # Notice there's no need to explicitly define the title
77
+ row.category post.category.name
78
+ row.author post.author.name
79
+ row.publish_date time_ago_in_words(post.published_at)
80
+ row.num_comments post.comments.empty? ? '-' : post.comments.size
81
+ row.num_trackbacks post.trackbacks.empty? ? '-' : post.trackbacks.size
82
+ end
83
+
84
+ t.footer :num_comments, @posts.inject(0) {|sum, post| sum += post.comments.size}
85
+ t.footer :num_trackbacks, @posts.inject(0) {|sum, post| sum += post.trackbacks.size}
86
+ end
87
+ %>
88
+
89
+ ...is compiled to (formatted here for the sake of sanity):
90
+
91
+ <table cellpadding="0" cellspacing="0" class="summary posts ui-collection" id="posts">
92
+ <thead>
93
+ <tr>
94
+ <th class="post-title" scope="col">Title</th>
95
+ <th class="post-category" scope="col">Category</th>
96
+ <th class="post-author" scope="col">Author</th>
97
+ <th class="post-publish_date" scope="col">Date<br \>Published</th>
98
+ <th class="post-num_comments" scope="col"># Comments</th>
99
+ <th class="post-num_trackbacks" scope="col"># Trackbacks</th>
100
+ </tr>
101
+ </thead>
102
+ <tbody>
103
+ <tr class="post ui-collection-result">
104
+ <td class="post-title">Open-source projects: The good, the bad, and the ugly</td>
105
+ <td class="post-category">General</td>
106
+ <td class="post-author">John Doe</td>
107
+ <td class="post-publish_date">23 days</td>
108
+ <td class="post-num_comments">-</td>
109
+ <td class="post-num_trackbacks">-</td>
110
+ </tr>
111
+ <tr class="post ui-collection-result ui-state-alternate">
112
+ <td class="post-title">5 reasons you should care about Rails</td>
113
+ <td class="post-category">Rails</td>
114
+ <td class="post-author">John Q. PUblic</td>
115
+ <td class="post-publish_date">21 days</td>
116
+ <td class="post-num_comments">-</td>
117
+ <td class="post-num_trackbacks">-</td>
118
+ </tr>
119
+ <tr class="post ui-collection-result">
120
+ <td class="post-title">Deprecation: Stop digging yourself a hole</td>
121
+ <td class="post-category">Rails</td>
122
+ <td class="post-author">Jane Doe</td>
123
+ <td class="post-publish_date">17 days</td>
124
+ <td class="post-num_comments">-</td>
125
+ <td class="post-num_trackbacks">-</td>
126
+ </tr>
127
+ <tr class="post ui-collection-result ui-state-alternate">
128
+ <td class="post-title">Jumpstart your Rails career at RailsConf 2007</td>
129
+ <td class="post-category">Conferences</td>
130
+ <td class="post-author">Jane Doe</td>
131
+ <td class="post-publish_date">4 days</td>
132
+ <td class="post-num_comments">-</td>
133
+ <td class="post-num_trackbacks">-</td>
134
+ </tr>
135
+ <tr class="post ui-collection-result">
136
+ <td class="post-title">Getting some REST</td>
137
+ <td class="post-category">Rails</td>
138
+ <td class="post-author">John Doe</td>
139
+ <td class="post-publish_date">about 18 hours</td>
140
+ <td class="post-num_comments">-</td>
141
+ <td class="post-num_trackbacks">-</td>
142
+ </tr>
143
+ </tbody>
144
+ <tfoot>
145
+ <tr>
146
+ <td class="post-num_comments">0</td>
147
+ <td class="post-num_trackbacks" colspan="5">0</td>
148
+ </tr>
149
+ </tfoot>
150
+ </table>
151
+
152
+ === Caveat Emptor
153
+
154
+ See the API for more information on syntax, options, and examples. You should only
155
+ use table_helper if it fits the needs of your application. Remember one of the key
156
+ principles of Rails, KISS (Keep It Simple Stupid). table_helper works really
157
+ well when you need to quickly output several of these types of summary tables.
158
+ If this is not the case, you may want to stick to using actual html.
159
+
160
+ == Testing
161
+
162
+ Before you can run any tests, the following gem must be installed:
163
+ * plugin_test_helper[http://github.com/pluginaweek/plugin_test_helper]
164
+
165
+ To run against a specific version of Rails:
166
+
167
+ rake test RAILS_FRAMEWORK_ROOT=/path/to/rails
168
+
169
+ == Dependencies
170
+
171
+ * Rails 2.0 or later
data/Rakefile ADDED
@@ -0,0 +1,96 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/contrib/sshpublisher'
5
+
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = 'table_helper'
8
+ s.version = '0.2.2'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'Adds a helper method for generating HTML tables from collections in Rails'
11
+ s.description = s.summary
12
+
13
+ s.files = FileList['{lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
14
+ s.require_path = 'lib'
15
+ s.has_rdoc = true
16
+ s.test_files = Dir['test/**/*_test.rb']
17
+
18
+ s.author = 'Aaron Pfeifer'
19
+ s.email = 'aaron@pluginaweek.org'
20
+ s.homepage = 'http://www.pluginaweek.org'
21
+ s.rubyforge_project = 'pluginaweek'
22
+ end
23
+
24
+ desc 'Default: run all tests.'
25
+ task :default => :test
26
+
27
+ desc "Test the #{spec.name} plugin."
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << 'lib'
30
+ t.test_files = spec.test_files
31
+ t.verbose = true
32
+ end
33
+
34
+ begin
35
+ require 'rcov/rcovtask'
36
+ namespace :test do
37
+ desc "Test the #{spec.name} plugin with Rcov."
38
+ Rcov::RcovTask.new(:rcov) do |t|
39
+ t.libs << 'lib'
40
+ t.test_files = spec.test_files
41
+ t.rcov_opts << '--exclude="^(?!lib/)"'
42
+ t.verbose = true
43
+ end
44
+ end
45
+ rescue LoadError
46
+ end
47
+
48
+ desc "Generate documentation for the #{spec.name} plugin."
49
+ Rake::RDocTask.new(:rdoc) do |rdoc|
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = spec.name
52
+ rdoc.template = '../rdoc_template.rb'
53
+ rdoc.options << '--line-numbers' << '--inline-source'
54
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
55
+ end
56
+
57
+ desc 'Generate a gemspec file.'
58
+ task :gemspec do
59
+ File.open("#{spec.name}.gemspec", 'w') do |f|
60
+ f.write spec.to_ruby
61
+ end
62
+ end
63
+
64
+ Rake::GemPackageTask.new(spec) do |p|
65
+ p.gem_spec = spec
66
+ p.need_tar = true
67
+ p.need_zip = true
68
+ end
69
+
70
+ desc 'Publish the beta gem.'
71
+ task :pgem => [:package] do
72
+ Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
73
+ end
74
+
75
+ desc 'Publish the API documentation.'
76
+ task :pdoc => [:rdoc] do
77
+ Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
78
+ end
79
+
80
+ desc 'Publish the API docs and gem'
81
+ task :publish => [:pgem, :pdoc, :release]
82
+
83
+ desc 'Publish the release files to RubyForge.'
84
+ task :release => [:gem, :package] do
85
+ require 'rubyforge'
86
+
87
+ ruby_forge = RubyForge.new.configure
88
+ ruby_forge.login
89
+
90
+ %w(gem tgz zip).each do |ext|
91
+ file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
92
+ puts "Releasing #{File.basename(file)}..."
93
+
94
+ ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
95
+ end
96
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'table_helper'
@@ -0,0 +1,211 @@
1
+ require 'table_helper/collection_table'
2
+
3
+ # Provides a set of methods for turning a collection into a table
4
+ module TableHelper
5
+ # Generates a new table for the given collection.
6
+ #
7
+ # == Basic Example
8
+ #
9
+ # This example shows the most basic usage of +collection_table+ which takes
10
+ # information about a collection, the objects in them, the columns defined
11
+ # for the class, and generates a table based on that.
12
+ #
13
+ # Suppose you have a table generated by a migration like so:
14
+ #
15
+ # class CreatePeople < ActiveRecord::Base
16
+ # def self.up
17
+ # create_table do |t|
18
+ # t.string :first_name
19
+ # t.string :last_name
20
+ # t.integer :company_id
21
+ # t.string :role
22
+ # end
23
+ # end
24
+ # end
25
+ #
26
+ # ...then invoking the helper within a view:
27
+ #
28
+ # <%= collection_table Person.find(:all) %>
29
+ #
30
+ # ...is compiled to (formatted here for the sake of sanity):
31
+ #
32
+ # <table cellpadding="0" cellspacing="0" class="posts ui-collection">
33
+ # <thead>
34
+ # <tr>
35
+ # <th class="person-first_name" scope="col">First Name</th>
36
+ # <th class="person-last_name" scope="col">Last Name</th>
37
+ # <th class="person-company_id" scope="col">Company</th>
38
+ # <th class="person-role" scope="col">Role</th>
39
+ # </tr>
40
+ # </thead>
41
+ # <tbody>
42
+ # <tr class="person ui-collection-result">
43
+ # <td class="person-first_name">John</td>
44
+ # <td class="person-last_name">Doe</td>
45
+ # <td class="person-company_id">1</td>
46
+ # <td class="person-role">President</td>
47
+ # </tr>
48
+ # <tr class="person ui-collection-result">
49
+ # <td class="first_name">Jane</td>
50
+ # <td class="last_name">Doe</td>
51
+ # <td class="company_id">1</td>
52
+ # <td class="role">Vice-President</td>
53
+ # </tr>
54
+ # </tbody>
55
+ # <table>
56
+ #
57
+ # == Advanced Example
58
+ #
59
+ # This example below shows how +collection_table+ can be customized to show
60
+ # specific headers, content, and footers.
61
+ #
62
+ # <%=
63
+ # collection_table(@posts, :id => 'posts', :class => 'summary') do |t|
64
+ # t.header :title
65
+ # t.header :category
66
+ # t.header :author
67
+ # t.header :publish_date, 'Date<br \>Published'
68
+ # t.header :num_comments, '# Comments'
69
+ # t.header :num_trackbacks, '# Trackbacks'
70
+ #
71
+ # t.rows.alternate = :odd
72
+ # t.rows.each do |row, post, index|
73
+ # row.category post.category.name
74
+ # row.author post.author.name
75
+ # row.publish_date time_ago_in_words(post.published_at)
76
+ # row.num_comments post.comments.empty? ? '-' : post.comments.size
77
+ # row.num_trackbacks post.trackbacks.empty? ? '-' : post.trackbacks.size
78
+ # end
79
+ # end
80
+ # %>
81
+ #
82
+ # ...is compiled to (formatted here for the sake of sanity):
83
+ #
84
+ # <table cellpadding="0" cellspacing="0" class="summary posts ui-collection" id="posts">
85
+ # <thead>
86
+ # <tr>
87
+ # <th class="post-title" scope="col">Title</th>
88
+ # <th class="post-category" scope="col">Category</th>
89
+ # <th class="post-author" scope="col">Author</th>
90
+ # <th class="post-publish_date" scope="col">Date<br \>Published</th>
91
+ # <th class="post-num_comments" scope="col"># Comments</th>
92
+ # <th class="post-num_trackbacks" scope="col"># Trackbacks</th>
93
+ # </tr>
94
+ # </thead>
95
+ # <tbody>
96
+ # <tr class="post ui-collection-result">
97
+ # <td class="post-title">Open-source projects: The good, the bad, and the ugly</td>
98
+ # <td class="post-category">General</td>
99
+ # <td class="post-author">John Doe</td>
100
+ # <td class="post-publish_date">23 days</td>
101
+ # <td class="post-num_comments">-</td>
102
+ # <td class="post-num_trackbacks">-</td>
103
+ # </tr>
104
+ # <tr class="post ui-collection-result ui-state-alternate">
105
+ # <td class="post-title">5 reasons you should care about Rails</td>
106
+ # <td class="post-category">Rails</td>
107
+ # <td class="author">John Q. Public</td>
108
+ # <td class="post-publish_date">21 days</td>
109
+ # <td class="post-num_comments">-</td>
110
+ # <td class="post-num_trackbacks">-</td>
111
+ # </tr>
112
+ # <tr class="post ui-collection-result">
113
+ # <td class="post-title">Deprecation: Stop digging yourself a hole</td>
114
+ # <td class="post-category">Rails</td>
115
+ # <td class="post-author">Jane Doe</td>
116
+ # <td class="post-publish_date">17 days</td>
117
+ # <td class="post-num_comments">-</td>
118
+ # <td class="post-num_trackbacks">-</td>
119
+ # </tr>
120
+ # <tr class="post ui-collection-result ui-state-alternate">
121
+ # <td class="post-title">Jumpstart your Rails career at RailsConf 2007</td>
122
+ # <td class="post-category">Conferences</td>
123
+ # <td class="post-author">Jane Doe</td>
124
+ # <td class="post-publish_date">4 days</td>
125
+ # <td class="post-num_comments">-</td>
126
+ # <td class="post-num_trackbacks">-</td>
127
+ # </tr>
128
+ # <tr class="post ui-collection-result">
129
+ # <td class="post-title">Getting some REST</td>
130
+ # <td class="post-category">Rails</td>
131
+ # <td class="post-author">John Doe</td>
132
+ # <td class="post-publish_date">about 18 hours</td>
133
+ # <td class="post-num_comments">-</td>
134
+ # <td class="post-num_trackbacks">-</td>
135
+ # </tr>
136
+ # </tbody>
137
+ # </table>
138
+ #
139
+ # == Creating footers
140
+ #
141
+ # Footers allow you to show some sort of summary information based on the
142
+ # data displayed in the body of the table. Below is an example:
143
+ #
144
+ # <%
145
+ # collection_table(@posts) do |t|
146
+ # t.header :title
147
+ # t.header :category
148
+ # t.header :author
149
+ # t.header :publish_date, 'Date<br \>Published'
150
+ # t.header :num_comments, '# Comments'
151
+ # t.header :num_trackbacks, '# Trackbacks'
152
+ #
153
+ # t.rows.alternate = :odd
154
+ # t.rows.each do |row, post, index|
155
+ # row.category post.category.name
156
+ # row.author post.author.name
157
+ # row.publish_date time_ago_in_words(post.published_at)
158
+ # row.num_comments post.comments.empty? ? '-' : post.comments.size
159
+ # row.num_trackbacks post.trackbacks.empty? ? '-' : post.trackbacks.size
160
+ # end
161
+ #
162
+ # t.footer :num_comments, @posts.inject(0) {|sum, post| sum += post.comments.size}
163
+ # t.footer :num_trackbacks, @posts.inject(0) {|sum, post| sum += post.trackbacks.size}
164
+ # end
165
+ # %>
166
+ #
167
+ # ...is compiled to:
168
+ #
169
+ # <table cellpadding="0" cellspacing="0" class="posts ui-collection">
170
+ # <thead>
171
+ # <tr>
172
+ # <th class="post-title" scope="col">Title</th>
173
+ # <th class="post-category" scope="col">Category</th>
174
+ # <th class="post-author" scope="col">Author</th>
175
+ # <th class="post-publish_date" scope="col">Date<br \>Published</th>
176
+ # <th class="post-num_comments" scope="col"># Comments</th>
177
+ # <th class="post-num_trackbacks" scope="col"># Trackbacks</th>
178
+ # </tr>
179
+ # </thead>
180
+ # <tbody>
181
+ # <tr class="post ui-collection-result">
182
+ # <td class="post-title">Open-source projects: The good, the bad, and the ugly</td>
183
+ # <td class="post-category">General</td>
184
+ # <td class="post-author">John Doe</td>
185
+ # <td class="post-publish_date">23 days</td>
186
+ # <td class="post-num_comments">-</td>
187
+ # <td class="post-num_trackbacks">-</td>
188
+ # </tr>
189
+ # <tr class="post ui-collection-result ui-state-alternate">
190
+ # <td class="post-title">5 reasons you should care about Rails</td>
191
+ # <td class="post-category">Rails</td><td class="author">John Q. Public</td>
192
+ # <td class="post-publish_date">21 days</td>
193
+ # <td class="post-num_comments">-</td>
194
+ # <td class="post-num_trackbacks">-</td>
195
+ # </tr>
196
+ # </tbody>
197
+ # <tfoot>
198
+ # <tr>
199
+ # <td class="post-num_comments">0</td>
200
+ # <td class="post-num_trackbacks" colspan="5">0</td>
201
+ # </tr>
202
+ # </tfoot>
203
+ # <table>
204
+ def collection_table(collection, klass = nil, html_options = {}, &block)
205
+ CollectionTable.new(collection, klass, html_options, &block).html
206
+ end
207
+ end
208
+
209
+ ActionController::Base.class_eval do
210
+ helper TableHelper
211
+ end