tangofoxtrot-table_helper 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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