kelredd-useful 0.1.25 → 0.2.0

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.
Files changed (61) hide show
  1. data/README.rdoc +3 -2
  2. data/Rakefile +6 -7
  3. data/lib/useful/active_record_helpers/mysql_migration_helpers.rb +64 -65
  4. data/lib/useful/active_record_helpers.rb +1 -1
  5. data/lib/useful/cap_tasks/app_role_migrations.rb +41 -0
  6. data/lib/useful/cap_tasks/disable_migrate.rb +15 -0
  7. data/lib/useful/cap_tasks/git_query_revision_remote.rb +31 -0
  8. data/lib/useful/cap_tasks/passenger_deploy.rb +44 -0
  9. data/lib/useful/cap_tasks/rack_cache.rb +17 -0
  10. data/lib/useful/cap_tasks.rb +1 -3
  11. data/lib/useful/erb_helpers/common.rb +86 -0
  12. data/lib/useful/erb_helpers/forms.rb +118 -0
  13. data/lib/useful/erb_helpers/links.rb +156 -0
  14. data/lib/useful/erb_helpers/proper.rb +109 -0
  15. data/lib/useful/erb_helpers/tags.rb +64 -0
  16. data/lib/useful/erb_helpers.rb +3 -0
  17. data/lib/useful/rails_helpers/environment_tests.rb +59 -0
  18. data/lib/useful/rails_helpers/erb.rb +3 -0
  19. data/lib/useful/rails_helpers.rb +3 -0
  20. data/lib/useful/ruby_extensions/array.rb +33 -34
  21. data/lib/useful/ruby_extensions/date.rb +11 -11
  22. data/lib/useful/ruby_extensions/false_class.rb +16 -13
  23. data/lib/useful/ruby_extensions/fixnum.rb +50 -19
  24. data/lib/useful/ruby_extensions/hash.rb +157 -91
  25. data/lib/useful/ruby_extensions/nil_class.rb +26 -0
  26. data/lib/useful/ruby_extensions/numeric.rb +239 -229
  27. data/lib/useful/ruby_extensions/object.rb +126 -11
  28. data/lib/useful/ruby_extensions/string.rb +259 -33
  29. data/lib/useful/ruby_extensions/true_class.rb +16 -13
  30. data/lib/useful/ruby_extensions.rb +1 -1
  31. data/lib/useful/ruby_extensions_with_activesupport.rb +2 -0
  32. data/lib/useful/shoulda_macros/test_unit.rb +58 -0
  33. data/lib/useful/version.rb +2 -2
  34. data/lib/useful.rb +1 -1
  35. metadata +19 -38
  36. data/lib/useful/cap_tasks/cache.rb +0 -5
  37. data/lib/useful/cap_tasks/gemsconfig.rb +0 -14
  38. data/lib/useful/rails_extensions/environment_tests.rb +0 -60
  39. data/lib/useful/rails_extensions.rb +0 -3
  40. data/lib/useful/ruby_extensions_from_rails/date.rb +0 -244
  41. data/lib/useful/ruby_extensions_from_rails/duration.rb +0 -99
  42. data/lib/useful/ruby_extensions_from_rails/fixnum.rb +0 -32
  43. data/lib/useful/ruby_extensions_from_rails/hash.rb +0 -50
  44. data/lib/useful/ruby_extensions_from_rails/numeric.rb +0 -60
  45. data/lib/useful/ruby_extensions_from_rails/object.rb +0 -79
  46. data/lib/useful/ruby_extensions_from_rails/string.rb +0 -174
  47. data/lib/useful/ruby_extensions_from_rails/time.rb +0 -320
  48. data/lib/useful/ruby_extensions_from_rails.rb +0 -3
  49. data/lib/useful/sinatra_helpers/environment_tests.rb +0 -19
  50. data/lib/useful/sinatra_helpers/erb/error_pages.rb +0 -25
  51. data/lib/useful/sinatra_helpers/erb/forms.rb +0 -131
  52. data/lib/useful/sinatra_helpers/erb/helpers.rb +0 -45
  53. data/lib/useful/sinatra_helpers/erb/links.rb +0 -79
  54. data/lib/useful/sinatra_helpers/erb/partials.rb +0 -41
  55. data/lib/useful/sinatra_helpers/erb/tags.rb +0 -56
  56. data/lib/useful/sinatra_helpers/erb.rb +0 -3
  57. data/lib/useful/sinatra_helpers/mailer/base.rb +0 -89
  58. data/lib/useful/sinatra_helpers/mailer/exceptions.rb +0 -17
  59. data/lib/useful/sinatra_helpers/mailer/tls.rb +0 -73
  60. data/lib/useful/sinatra_helpers/mailer.rb +0 -3
  61. data/lib/useful/sinatra_helpers.rb +0 -3
data/README.rdoc CHANGED
@@ -3,7 +3,8 @@
3
3
  == Description
4
4
 
5
5
  A collection of useful helpers for various ruby things. Includes
6
- helpers for sinatra, ruby base classes, mysql, rails, erb, etc...
6
+ ruby extensions that play nice with activesupport, helpers for
7
+ sinatra/rails/activerecord/erb, etc...
7
8
 
8
9
  You probably never want them all, all the time, but just require in
9
10
  the pieces you are interested in.
@@ -20,8 +21,8 @@ the pieces you are interested in.
20
21
  == Usage
21
22
 
22
23
  require 'rubygems'
24
+ require 'useful/ruby_extensions'
23
25
  require 'useful/sinatra_helpers'
24
- require 'useful/mysql_helpers'
25
26
 
26
27
  == License
27
28
 
data/Rakefile CHANGED
@@ -20,19 +20,12 @@ spec = Gem::Specification.new do |s|
20
20
  # s.executables = ['useful']
21
21
 
22
22
  s.add_dependency('json')
23
- s.add_dependency('tmail')
24
23
  end
25
24
 
26
25
  Rake::GemPackageTask.new(spec) do |pkg|
27
26
  pkg.gem_spec = spec
28
27
  end
29
28
 
30
- Rake::TestTask.new do |t|
31
- t.libs << 'test'
32
- t.test_files = FileList["test/**/*_test.rb"]
33
- t.verbose = true
34
- end
35
-
36
29
  desc 'Generate the gemspec to serve this Gem from Github'
37
30
  task :gemspec do
38
31
  file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
@@ -40,6 +33,12 @@ task :gemspec do
40
33
  puts "Created gemspec: #{file}"
41
34
  end
42
35
 
36
+ Rake::TestTask.new do |t|
37
+ t.libs << 'test'
38
+ t.test_files = FileList["test/**/*_test.rb"]
39
+ t.verbose = true
40
+ end
41
+
43
42
  require 'cucumber'
44
43
  require 'cucumber/rake/task'
45
44
 
@@ -1,82 +1,81 @@
1
- module Useful
2
- module ActiveRecordHelpers
3
- module MysqlMigrationHelpers
4
-
5
- module ClassMethods
1
+ module Useful; end
2
+ module Useful::ActiveRecordHelpers; end
6
3
 
7
- def foreign_key(from_table, from_column, to_table, opts={})
8
- opts[:destination_key] = 'id' unless opts[:destination_key]
9
- constraint_name = "fk_#{from_table}_#{from_column}"
10
- execute %{alter table #{from_table}
11
- add constraint #{constraint_name}
12
- foreign key (#{from_column})
13
- references #{to_table}(#{opts[:destination_key]})}
14
- end
4
+ module Useful::ActiveRecordHelpers::MysqlMigrationHelpers
5
+
6
+ module ClassMethods
15
7
 
16
- def drop_foreign_key(from_table, *from_columns)
17
- from_columns.each { |from_column|
18
- constraint_name = "fk_#{from_table}_#{from_column}"
19
- execute %{alter table #{from_table} drop FOREIGN KEY #{constraint_name}}
20
- }
21
- end
8
+ def foreign_key(from_table, from_column, to_table, opts={})
9
+ opts[:destination_key] = 'id' unless opts[:destination_key]
10
+ constraint_name = "fk_#{from_table}_#{from_column}"
11
+ execute %{alter table #{from_table}
12
+ add constraint #{constraint_name}
13
+ foreign key (#{from_column})
14
+ references #{to_table}(#{opts[:destination_key]})}
15
+ end
22
16
 
23
- def remove_column_with_fk(table, column)
24
- drop_foreign_key(table, column)
25
- remove_column(table, column)
26
- end
17
+ def drop_foreign_key(from_table, *from_columns)
18
+ from_columns.each { |from_column|
19
+ constraint_name = "fk_#{from_table}_#{from_column}"
20
+ execute %{alter table #{from_table} drop FOREIGN KEY #{constraint_name}}
21
+ }
22
+ end
27
23
 
28
- def safe_drop_table(table_name)
29
- execute "drop table if exists #{table_name}"
30
- end
24
+ def remove_column_with_fk(table, column)
25
+ drop_foreign_key(table, column)
26
+ remove_column(table, column)
27
+ end
31
28
 
32
- def unique_constraint(table_name, columns)
33
- execute %{ALTER TABLE #{table_name} ADD CONSTRAINT uniq_#{columns.join('_')} UNIQUE KEY (#{columns.join(", ")})}
34
- end
29
+ def safe_drop_table(table_name)
30
+ execute "drop table if exists #{table_name}"
31
+ end
35
32
 
36
- def set_auto_increment(table, number)
37
- execute %{ALTER TABLE #{table} AUTO_INCREMENT = #{number}}
38
- end
33
+ def unique_constraint(table_name, columns)
34
+ execute %{ALTER TABLE #{table_name} ADD CONSTRAINT uniq_#{columns.join('_')} UNIQUE KEY (#{columns.join(", ")})}
35
+ end
39
36
 
40
- def clear_table(table_to_clear)
41
- execute %{delete from #{table_to_clear}}
42
- end
37
+ def set_auto_increment(table, number)
38
+ execute %{ALTER TABLE #{table} AUTO_INCREMENT = #{number}}
39
+ end
43
40
 
44
- def create_view(view_name,sql_query_definition)
45
- execute %{
46
- CREATE SQL SECURITY INVOKER VIEW #{view_name.to_s} AS
47
- #{sql_query_definition}
48
- }
49
- end
41
+ def clear_table(table_to_clear)
42
+ execute %{delete from #{table_to_clear}}
43
+ end
50
44
 
51
- def drop_view(view_name)
52
- execute %{
53
- DROP VIEW #{view_name}
54
- }
55
- end
45
+ def create_view(view_name,sql_query_definition)
46
+ execute %{
47
+ CREATE SQL SECURITY INVOKER VIEW #{view_name.to_s} AS
48
+ #{sql_query_definition}
49
+ }
50
+ end
56
51
 
57
- def alter_view(view_name,sql_query_definition)
58
- execute %{
59
- ALTER SQL SECURITY INVOKER VIEW #{view_name.to_s} AS
60
- #{sql_query_definition}
61
- }
62
- end
52
+ def drop_view(view_name)
53
+ execute %{
54
+ DROP VIEW #{view_name}
55
+ }
56
+ end
63
57
 
64
- def raise_err(msg = '')
65
- raise ActiveRecord::IrreversibleMigration, msg
66
- end
58
+ def alter_view(view_name,sql_query_definition)
59
+ execute %{
60
+ ALTER SQL SECURITY INVOKER VIEW #{view_name.to_s} AS
61
+ #{sql_query_definition}
62
+ }
63
+ end
67
64
 
68
- end
69
-
70
- module InstanceMethods
71
- end
72
-
73
- def self.included(receiver)
74
- receiver.extend ClassMethods
75
- receiver.send :include, InstanceMethods
76
- end
65
+ def raise_err(msg = '')
66
+ raise ActiveRecord::IrreversibleMigration, msg
67
+ end
77
68
 
78
- end
79
69
  end
70
+
71
+ module InstanceMethods
72
+ end
73
+
74
+ def self.included(receiver)
75
+ receiver.extend ClassMethods
76
+ receiver.send :include, InstanceMethods
77
+ end
78
+
80
79
  end
81
80
 
82
81
  module ActiveRecord
@@ -1,3 +1,3 @@
1
1
  Dir[File.join(File.dirname(__FILE__), "active_record_helpers" ,"*.rb")].each do |file|
2
- require file
2
+ require "useful/active_record_helpers/#{File.basename(file, ".rb")}"
3
3
  end
@@ -0,0 +1,41 @@
1
+ unless Capistrano::Configuration.respond_to?(:instance)
2
+ abort "useful/cap_tasks requires Capistrano 2"
3
+ end
4
+
5
+ Capistrano::Configuration.instance.load do
6
+
7
+ namespace :deploy do
8
+
9
+ # These tasks override the default cap migration tasks
10
+ # => allows for running your migrations on the primary app server only
11
+
12
+ desc "_: (#{application}) Bring down site, deploy with migrations on primary app server only, bring site back up."
13
+ task :migrations, :roles => :app, :only => { :primary => true } do
14
+ stop
15
+ update
16
+ migrate
17
+ start
18
+ end
19
+
20
+ # Copied from http://github.com/jamis/capistrano/blob/df0935c4c135207582da343aacdd4cf080fcfed0/lib/capistrano/recipes/deploy.rb
21
+ # => changed :roles => :db to :roles => :app so that migrations will run on the primary app server only
22
+ # => also added , :pty => false as an argument on the run command
23
+ desc "_: (#{application}) port of default cap task to only run on primary app server"
24
+ task :migrate, :roles => :app, :only => { :primary => true } do
25
+ rake = fetch(:rake, "rake")
26
+ rails_env = fetch(:rails_env, "production")
27
+ migrate_env = fetch(:migrate_env, "")
28
+ migrate_target = fetch(:migrate_target, :latest)
29
+
30
+ directory = case migrate_target.to_sym
31
+ when :current then current_path
32
+ when :latest then current_release
33
+ else raise ArgumentError, "unknown migration target #{migrate_target.inspect}"
34
+ end
35
+
36
+ run "cd #{directory}; #{rake} RAILS_ENV=#{rails_env} #{migrate_env} db:migrate", :pty => false
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,15 @@
1
+ unless Capistrano::Configuration.respond_to?(:instance)
2
+ abort "useful/cap_tasks requires Capistrano 2"
3
+ end
4
+
5
+ Capistrano::Configuration.instance.load do
6
+
7
+ namespace :deploy do
8
+
9
+ desc "_: (#{application}) no migrating needed, this one does nothing..."
10
+ task :migrate, :roles => :app, :only => { :primary => true } do
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,31 @@
1
+ unless Capistrano::Configuration.respond_to?(:instance)
2
+ abort "useful/cap_tasks requires Capistrano 2"
3
+ end
4
+
5
+ Capistrano::Configuration.instance.load do
6
+
7
+ namespace :deploy do
8
+
9
+ task :before_update_code, :except => { :no_release => true } do
10
+
11
+ # Set the branch name to current git HEAD if this stage is configured that way
12
+ set :branch, run_locally("git symbolic-ref HEAD 2>/dev/null").split('/').last.strip if branch == :current_git_branch
13
+
14
+ # hack to remotely lookup the revision sending the config'd scm_password
15
+ # => prevents having to enter it locally
16
+ set :real_revision, source.local.query_revision(revision) { |cmd|
17
+ with_env("LC_ALL", "C") {
18
+ result = nil
19
+ run cmd do |ch, stream, out|
20
+ ch.send_data(scm_password)
21
+ ch.send_data("\n")
22
+ result = out
23
+ end
24
+ result
25
+ }
26
+ }
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,44 @@
1
+ unless Capistrano::Configuration.respond_to?(:instance)
2
+ abort "useful/cap_tasks requires Capistrano 2"
3
+ end
4
+
5
+ Capistrano::Configuration.instance.load do
6
+
7
+ namespace :deploy do
8
+
9
+ task :after_deploy, :except => { :no_release => true } do
10
+ web.enable
11
+ cleanup
12
+ end
13
+
14
+ desc "_: (#{application}) Start app from cold state."
15
+ task :start, :roles => :app, :except => { :no_release => true } do
16
+ restart
17
+ web.enable
18
+ end
19
+
20
+ desc "_: (#{application}) Stop app and put in cold state."
21
+ task :stop, :roles => :app, :except => { :no_release => true } do
22
+ web.disable
23
+ end
24
+
25
+ desc "_: (#{application}) Restart app from hot state."
26
+ task :restart, :roles => :app, :except => { :no_release => true } do
27
+ run "touch #{current_path}/tmp/restart.txt"
28
+ end
29
+
30
+ end
31
+
32
+ namespace :web do
33
+ desc "_: (#{application}) Enable app and remove down page."
34
+ task :enable, :roles => :app, :except => { :no_release => true } do
35
+ run "rm #{current_path}/public/#{down_html}.html"
36
+ end
37
+
38
+ desc "_: (#{application}) Put up down page and disable app"
39
+ task :disable, :roles => :app, :except => { :no_release => true } do
40
+ run "cp #{shared_path}/#{down_html}.html #{current_path}/public/#{down_html}.html"
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,17 @@
1
+ unless Capistrano::Configuration.respond_to?(:instance)
2
+ abort "useful/cap_tasks requires Capistrano 2"
3
+ end
4
+
5
+ Capistrano::Configuration.instance.load do
6
+
7
+ namespace :cache do
8
+
9
+ desc "Clear the Rack cache"
10
+ task :xrack, :roles => :app, :except => { :no_release => true } do
11
+ run "rm -rf #{shared_path}/cache-rack/body/*"
12
+ run "rm -rf #{shared_path}/cache-rack/meta/*"
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -1,3 +1 @@
1
- Dir[File.join(File.dirname(__FILE__), "cap_tasks" ,"*.rb")].each do |file|
2
- require file
3
- end
1
+ require 'useful/cap_tasks/globals'
@@ -0,0 +1,86 @@
1
+ # Note: these helpers are designed to be namespaced and actionpack safe
2
+ # => these helpers are included in the useful/rails_extensions/erb
3
+ # => don't put any actionpack helpers in this module
4
+
5
+ module Useful; end
6
+ module Useful::ErbHelpers; end
7
+
8
+ module Useful::ErbHelpers::Common
9
+
10
+ OPTIONS = {
11
+ :disabled => 'disabled',
12
+ :checked => 'checked',
13
+ :multiple => 'multiple',
14
+ :multipart => 'multipart/form-data',
15
+ :default_submit_value => "Save changes"
16
+ }.freeze
17
+
18
+ def erb_helper_clear_output_buffer
19
+ @_out_buf = ""
20
+ end
21
+
22
+ protected
23
+
24
+ def erb_helper_common_safe_id(id)
25
+ id.gsub(/\[\]/, '').gsub(/\[/, '_').gsub(/\]/, '').gsub(/\W/,'')
26
+ end
27
+
28
+ def erb_helper_common_capture(*args, &block)
29
+ erb_helper_common_with_output_buffer { block.call(*args) }
30
+ end
31
+
32
+ def erb_helper_common_with_output_buffer(buf = '') #:nodoc:
33
+ @_out_buf, old_buffer = buf, @_out_buf
34
+ result = yield
35
+ @_out_but.blank? ? result : @_out_buf
36
+ ensure
37
+ @_out_buf = old_buffer
38
+ end
39
+
40
+ def erb_helper_convert_options_to_javascript!(options)
41
+ confirm, popup = options.delete(:confirm), options.delete(:popup)
42
+ if confirm || popup
43
+ options[:onclick] = case
44
+ when confirm && popup
45
+ "javascript: if (#{erb_helper_confirm_javascript(confirm)}) { #{erb_helper_popup_javascript(popup)} }; return false;"
46
+ when confirm
47
+ "javascript: return #{erb_helper_confirm_javascript(confirm)};"
48
+ when popup
49
+ "javascript: #{erb_helper_popup_javascript(popup)} return false;"
50
+ else
51
+ "javascript: return false;" # should never case to this b/c of if statement
52
+ end
53
+ end
54
+ end
55
+
56
+ def erb_helper_confirm_javascript(confirm)
57
+ "confirm('#{escape_javascript(confirm)}')"
58
+ end
59
+
60
+ def erb_helper_popup_javascript(popup)
61
+ popup.kind_of?(::Array) ? "window.open(this.href,'#{popup.first}','#{popup.last}');" : "window.open(this.href);"
62
+ end
63
+
64
+ def erb_helper_disable_with_javascript(disable_with)
65
+ "javascript: this.disabled=true; this.value='#{escape_javascript(disable_with)}'; this.form.submit();"
66
+ end
67
+
68
+ JS_ESCAPE_MAP = {
69
+ '\\' => '\\\\',
70
+ '</' => '<\/',
71
+ "\r\n" => '\n',
72
+ "\n" => '\n',
73
+ "\r" => '\n',
74
+ '"' => '\\"',
75
+ "'" => "\\'"
76
+ }.freeze
77
+ # Escape carrier returns and single and double quotes for JavaScript segments.
78
+ def escape_javascript(javascript)
79
+ if javascript
80
+ javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { JS_ESCAPE_MAP[$1] }
81
+ else
82
+ ''
83
+ end
84
+ end
85
+
86
+ end
@@ -0,0 +1,118 @@
1
+ # Note: these helpers are NOT actionpack safe
2
+ # => these helpers should NOT be included in the useful/rails_extensions/erb
3
+ # => these helpers are designed to emulate their corresponding actionpack helpers
4
+
5
+ require 'useful/erb_helpers/common'
6
+ require 'useful/erb_helpers/tags'
7
+ require 'useful/ruby_extensions/string' unless ::String.new.respond_to?('humanize') && ::String.new.respond_to?('ends_with?')
8
+ require 'useful/ruby_extensions/object' unless ::Object.new.respond_to?('true?')
9
+
10
+ module Useful; end
11
+ module Useful::ErbHelpers; end
12
+
13
+ module Useful::ErbHelpers::Forms
14
+
15
+ include Useful::ErbHelpers::Common
16
+
17
+ def form_tag(url, options={}, &block)
18
+ options[:method] = 'post' unless ['get','post','put','delete'].include?(options[:method])
19
+ options.update :action => url
20
+ if multipart = options.delete(:multipart)
21
+ options[:enctype] = OPTIONS[:multipart]
22
+ end
23
+ if block_given?
24
+ @_out_buf ||= ''
25
+ @_out_buf << tag(:form, options) { erb_helper_common_capture(&block) }
26
+ else
27
+ tag(:form, options)
28
+ end
29
+ end
30
+
31
+ def field_set_tag(legend=nil, options={}, &block)
32
+ legend_html = legend.nil? ? '' : tag(:legend) { legend.to_s }
33
+ if block_given?
34
+ @_out_buf ||= ''
35
+ @_out_buf << tag(:fieldset, options) { legend_html + erb_helper_common_capture(&block) }
36
+ else
37
+ tag(:fieldset, options) { legend_html }
38
+ end
39
+ end
40
+
41
+ def label_tag(name, value=nil, options={})
42
+ value ||= name.to_s.gsub(/\[/, '_').gsub(/\]/, '').humanize
43
+ options[:for] ||= erb_helper_common_safe_id(name)
44
+ tag(:label, options) { value }
45
+ end
46
+
47
+ def hidden_field_tag(name, value=nil, options={})
48
+ input_tag('hidden', name, value, options)
49
+ end
50
+
51
+ def text_field_tag(name, value=nil, options={})
52
+ input_tag('text', name, value, options)
53
+ end
54
+
55
+ def password_field_tag(name="password", value=nil, options={})
56
+ input_tag('password', name, value, options)
57
+ end
58
+
59
+ def file_field_tag(name, options={})
60
+ input_tag('file', name, nil, options)
61
+ end
62
+
63
+ # Special options:
64
+ # => :disable_with - string
65
+ # => will add js onclick event to first disable submit, setting text to value, and then submitting form
66
+ # => :confirm - string
67
+ # => will add js confirm confirmation before submitting
68
+ def submit_tag(value=OPTIONS[:default_submit_value], options={})
69
+ options[:onclick] = erb_helper_disable_with_javascript(options.delete(:disabled_with)) if options.has_key?(:disabled_with)
70
+ if options.has_key?(:confirm)
71
+ options[:onclick] ||= 'return true;'
72
+ options[:onclick] = "if (!#{erb_helper_confirm_javascript(options.delete(:confirm))}) return false; #{options[:onclick]}"
73
+ end
74
+ input_tag('submit', 'commit', value, options)
75
+ end
76
+
77
+ # Special options:
78
+ # => :confirm - string
79
+ # => will add js confirm confirmation before submitting
80
+ def image_submit_tag(source, options={})
81
+ options[:src] = ['/'].include?(source[0..0]) ? source : "/images/#{source}"
82
+ options[:alt] ||= OPTIONS[:default_submit_value]
83
+ if options.has_key?(:confirm)
84
+ options[:onclick] ||= 'return true;'
85
+ options[:onclick] = "if (!#{erb_helper_confirm_javascript(options.delete(:confirm))}) return false; #{options[:onclick]}"
86
+ end
87
+ input_tag('image', nil, nil, options)
88
+ end
89
+
90
+ # Special options:
91
+ # => :size - A string specifying the dimensions (columns by rows) of the textarea (e.g., "25x10").
92
+ # => :rows - Specify the number of rows in the textarea
93
+ # => :cols - Specify the number of columns in the textarea
94
+ # => :escape - By default, the contents of the text input are HTML escaped. If you need unescaped contents, set this to false.
95
+ def text_area_tag(name, content=nil, options={})
96
+ options[:tag] = 'textarea'
97
+ if size = options.delete(:size)
98
+ options[:cols], options[:rows] = size.split("x") if size.respond_to?(:split)
99
+ end
100
+ unless options.has_key?(:escape) && options.delete(:escape).false?
101
+ content = escape_html(content)
102
+ end
103
+ input_tag(nil, name, nil, options) { content || '' }
104
+ end
105
+
106
+ # Note: purposely left out:
107
+ # => select_tag
108
+ # => check_box_tag
109
+ # => radio_button_tag
110
+ # Not going to reinvent the inferior actionpack versions here.
111
+ # => prefer, instead, the corresponding 'proper' versions
112
+ # => see useful/erb_helpers/proper.rb (which is included in useful/rails_extensions/erb)
113
+
114
+ def self.included(receiver)
115
+ receiver.send :include, Useful::ErbHelpers::Tags
116
+ end
117
+
118
+ end