kelredd-useful 0.1.25 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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