rails-ext 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. data/.git/COMMIT_EDITMSG +1 -0
  2. data/.git/HEAD +1 -0
  3. data/.git/config +12 -0
  4. data/.git/description +1 -0
  5. data/.git/hooks/applypatch-msg.sample +15 -0
  6. data/.git/hooks/commit-msg.sample +24 -0
  7. data/.git/hooks/post-commit.sample +8 -0
  8. data/.git/hooks/post-receive.sample +15 -0
  9. data/.git/hooks/post-update.sample +8 -0
  10. data/.git/hooks/pre-applypatch.sample +14 -0
  11. data/.git/hooks/pre-commit.sample +46 -0
  12. data/.git/hooks/pre-rebase.sample +169 -0
  13. data/.git/hooks/prepare-commit-msg.sample +36 -0
  14. data/.git/hooks/update.sample +128 -0
  15. data/.git/index +0 -0
  16. data/.git/info/exclude +6 -0
  17. data/.git/logs/HEAD +6 -0
  18. data/.git/logs/refs/heads/master +6 -0
  19. data/.git/logs/refs/remotes/origin/master +5 -0
  20. data/.git/objects/02/469b717b4bd61ad27a3fe664ce0646a8325399 +2 -0
  21. data/.git/objects/06/c3225bad9d5b80e7b3bde79ff3c2da591722bf +5 -0
  22. data/.git/objects/07/f7d26527e58caa2fa99e33b29a7791b9eb8b3e +0 -0
  23. data/.git/objects/09/20505d42c0044b31ff7b1f86cec6e282e13414 +0 -0
  24. data/.git/objects/0b/e101a0586410212b4ee5905881ad726b7b4907 +0 -0
  25. data/.git/objects/10/bfe1230b9d96e23600091cc8b4b9d378068101 +0 -0
  26. data/.git/objects/13/882df4f2ef911454bf3b69a85742b372723366 +2 -0
  27. data/.git/objects/15/3f845625a0f605a2a35487a32038d0349bc386 +0 -0
  28. data/.git/objects/18/77033b90ed3dd55a3034b7e3ca1c5c9f66868d +0 -0
  29. data/.git/objects/19/1f68644a3646d774f2546c4cd49ac7d66f4cc2 +0 -0
  30. data/.git/objects/1d/d49713de2942dc974e55adc3684f55b2b817e2 +0 -0
  31. data/.git/objects/1e/6374b23c71a07b0e414e80912fd45503bd3daf +0 -0
  32. data/.git/objects/29/7a2c413b11f78b69dd8caa4f334c9536088f8a +3 -0
  33. data/.git/objects/29/b1f8abaed4aea1da8f8bd5f1bd81c26058c41a +3 -0
  34. data/.git/objects/2a/04524c8458b2d0cd9bcec579f9d54368a9d35f +0 -0
  35. data/.git/objects/2d/043376f1bc26b2dad3e79fc72ea14341ea437d +0 -0
  36. data/.git/objects/2e/3e3fc8e46949a9b944da3c36207c444aa2c9b7 +0 -0
  37. data/.git/objects/30/69d4978bbdfacf4402c4339438b29657275f2c +0 -0
  38. data/.git/objects/36/9902ca51d5820a02ccccbf1cac6ed09051941d +0 -0
  39. data/.git/objects/3a/03b9d44de43472689300120ffb2a0a9a74f27f +0 -0
  40. data/.git/objects/3a/797683953be7e6d0ffa0e34514f3e8e9c3ceb0 +3 -0
  41. data/.git/objects/3f/3db6bb5a5204ae58e303959c4c0da3a70d8b35 +1 -0
  42. data/.git/objects/40/215c0554202fc46dc2fca94ed21e2920ce1e84 +0 -0
  43. data/.git/objects/4b/2bdb2dc6330ba9bafd9058ec8eaa925ef53f91 +0 -0
  44. data/.git/objects/4d/991a018b0c697fa119efe7aaf55df0a1c7af8e +0 -0
  45. data/.git/objects/4f/fa8f1c9b7e3fdbb23ab600722d1011dcb48cec +2 -0
  46. data/.git/objects/55/d1f1efc344266d472094b1fd2f247b97de1c8b +0 -0
  47. data/.git/objects/57/8a722fd66124331e07123e3a0de2b6b50a581b +3 -0
  48. data/.git/objects/59/0ef6ba9931d75fbddc7a940044dbaaa50efc76 +0 -0
  49. data/.git/objects/5a/35fa85474278f3c817aa59d07b725428c41a28 +0 -0
  50. data/.git/objects/60/a681e873ca0ae0b7da3f37dbc5701f6e42b970 +1 -0
  51. data/.git/objects/61/32f3f8005ce5b88165162ac5542e54d0472a82 +3 -0
  52. data/.git/objects/65/51094fa3b996ff25b88d7ddb21d21a811d53fc +2 -0
  53. data/.git/objects/67/850cf1ede94d80c9b07ceace074a4d62f15249 +0 -0
  54. data/.git/objects/68/8ce506ac4f7c160bd6880d8507820761a3b3b7 +0 -0
  55. data/.git/objects/6d/f725e3519872a75bc763045f00d8844eb890cf +0 -0
  56. data/.git/objects/71/e6b43e9d41f9903992fd86d483b7d3e4dd28cd +0 -0
  57. data/.git/objects/75/d0b250bcdf241d981313b1d6eb153b96e4b05f +2 -0
  58. data/.git/objects/7d/978ee312ca2119dc84e40431182b8f68e42f53 +1 -0
  59. data/.git/objects/87/fc827fd223cac6b4e55d823a9ea86bb0726a3b +0 -0
  60. data/.git/objects/8d/4dcde8df4da8f53f5f5313757b907e9aa1af66 +0 -0
  61. data/.git/objects/8e/69b6cf3ec8b49270091b4a206ccf326679dc20 +0 -0
  62. data/.git/objects/92/e1c250edfca72ed0932934257ef3cfc7122ec5 +0 -0
  63. data/.git/objects/92/e1f3936e7c33007d0a466b836804450992a1eb +1 -0
  64. data/.git/objects/93/f9a6b596879347290cde161b03052bb22021de +5 -0
  65. data/.git/objects/94/72f3ac9e890231482aadd774bdc1c9ba742497 +0 -0
  66. data/.git/objects/a7/6c4944dc009628cb65b4962464a8eb484d6a71 +0 -0
  67. data/.git/objects/ac/92bcf6c74d23824c3c7ce341f667507592c7f9 +0 -0
  68. data/.git/objects/b0/2c48116db702256abf27fab4236c84bd2d2dbc +2 -0
  69. data/.git/objects/b0/39fcd38009980eb74d6bcef22d11e02639a530 +0 -0
  70. data/.git/objects/b2/cd852090540d0b2450b901397edd924d8c0ba9 +0 -0
  71. data/.git/objects/b4/228251babf3a84ac181d462fdd383816bd23b8 +0 -0
  72. data/.git/objects/b5/edd343ceb8e87d1a73922612aec210b393f839 +0 -0
  73. data/.git/objects/bb/23236d2e8340087cc495c66310e6eb90d6fe0a +0 -0
  74. data/.git/objects/bc/90a06dd2f2257e8da49989738db5747e2b78d8 +4 -0
  75. data/.git/objects/bd/eab0ec8a914cdd8c9341340191c116a4bf2d3e +0 -0
  76. data/.git/objects/c0/724bc45e241d336d6376f14d9b258c2e4744d4 +0 -0
  77. data/.git/objects/c1/3cf3c2ea85ec40544fe31702b2cfe6091aed6e +0 -0
  78. data/.git/objects/c5/64ac68ebc8e0db7a6355a45f3299829ef2a825 +0 -0
  79. data/.git/objects/ca/c13b06411cdb70ac35d51ecf9efb0907645bd1 +0 -0
  80. data/.git/objects/d1/38a420782e818f3f87c6c8c0a0a135639a30d9 +0 -0
  81. data/.git/objects/d2/85be6e2891e063625d4904c9bcca42bf6f0b83 +0 -0
  82. data/.git/objects/d4/1e2336bcd3ce3d09a9fa6c3af3270c29bd8457 +1 -0
  83. data/.git/objects/d5/86dc7698c6ec37db86e9f36a16bd671e0005ab +0 -0
  84. data/.git/objects/d5/a2b441718a88aa08fa937352a6d80319bc91c0 +0 -0
  85. data/.git/objects/e0/d8e7ab5a565d95d44f2a9a6246be6003a3de7b +0 -0
  86. data/.git/objects/e2/bc2615d3aa154bba2897c562a15ed19136d518 +0 -0
  87. data/.git/objects/e3/a7cacb84225125a2bc91b42394e7de7de7b205 +0 -0
  88. data/.git/objects/e3/cde2715e3e3870a5d7312cac9bbf6e24259e0f +0 -0
  89. data/.git/objects/e4/d7cacac2d7e66df5a7c21eaae71c0a90f1439d +0 -0
  90. data/.git/objects/e7/f4b26a3258b7788ffe2665773387e19c01095a +3 -0
  91. data/.git/objects/ea/50407bf8daef694d22268540dd55eb3a739bad +4 -0
  92. data/.git/objects/eb/9701e2dbe8fb606315f9514d789188160bdd67 +2 -0
  93. data/.git/objects/ee/ccaf0d272346a1dcc672a4131ba692a0027049 +2 -0
  94. data/.git/objects/f2/196f15b2d432b2a2d641aed4ae5afe7190edb9 +1 -0
  95. data/.git/objects/f3/3573a82a9e7dbf9bc7f5b3feded4c223701d1f +0 -0
  96. data/.git/objects/f3/7784042bc99c16c02fd104dda82aafa42d4c9c +0 -0
  97. data/.git/objects/f5/91a5c39e03e2102c9101db957b48c8c76e194c +0 -0
  98. data/.git/objects/f9/8d0f95460a7a3f63ab4c08ad5508fd32d1b5c2 +0 -0
  99. data/.git/objects/pack/pack-c7edd4d292858ed6a37a55c1b6ceb35f65f4587e.idx +0 -0
  100. data/.git/objects/pack/pack-c7edd4d292858ed6a37a55c1b6ceb35f65f4587e.pack +0 -0
  101. data/.git/packed-refs +2 -0
  102. data/.git/refs/heads/master +1 -0
  103. data/.git/refs/remotes/origin/HEAD +1 -0
  104. data/.git/refs/remotes/origin/master +1 -0
  105. data/.gitignore +5 -0
  106. data/README.rdoc +14 -0
  107. data/Rakefile +63 -0
  108. data/lib/rails_ext/action_controller.rb +19 -0
  109. data/lib/rails_ext/action_controller_ext.rb +29 -0
  110. data/lib/rails_ext/action_view.rb +5 -0
  111. data/lib/rails_ext/active_record.rb +7 -0
  112. data/lib/rails_ext/active_record_ext.rb +15 -0
  113. data/lib/rails_ext/basic.rb +7 -0
  114. data/lib/rails_ext/common_helper.rb +83 -0
  115. data/lib/rails_ext/config_files/safe_hash.rb +96 -0
  116. data/lib/rails_ext/config_files.rb +18 -0
  117. data/lib/rails_ext/create_public_symlinks.rb +9 -0
  118. data/lib/rails_ext/defer_javascript.rb +51 -0
  119. data/lib/rails_ext/email_config.rb +8 -0
  120. data/lib/rails_ext/global_path_prefix.rb +56 -0
  121. data/lib/rails_ext/hacks/ajax_flash.rb +9 -0
  122. data/lib/rails_ext/hacks/ajax_redirect_to.rb +19 -0
  123. data/lib/rails_ext/hacks/defer_javascript.rb +17 -0
  124. data/lib/rails_ext/hacks/global_path_prefix.rb +33 -0
  125. data/lib/rails_ext/hacks/link_to.rb +106 -0
  126. data/lib/rails_ext/hacks/merge_default_scope.rb +20 -0
  127. data/lib/rails_ext/hacks/persistent_params.rb +16 -0
  128. data/lib/rails_ext/hacks/rjs_layout.rb +2 -0
  129. data/lib/rails_ext/handy_environment.rb +45 -0
  130. data/lib/rails_ext/i18n_helper.rb +125 -0
  131. data/lib/rails_ext/merge_default_scope/hash_poser.rb +40 -0
  132. data/lib/rails_ext/merge_default_scope.rb +16 -0
  133. data/lib/rails_ext/model.rb +1 -0
  134. data/lib/rails_ext/persistent_params.rb +88 -0
  135. data/lib/rails_ext/redirect_helper.rb +14 -0
  136. data/lib/rails_ext/reload_page.rb +7 -0
  137. data/lib/rails_ext/user_error.rb +12 -0
  138. data/lib/rails_ext.rb +21 -0
  139. data/spec/safe_hash_spec.rb +71 -0
  140. data/spec/spec.opts +3 -0
  141. metadata +203 -0
@@ -0,0 +1,56 @@
1
+ #
2
+ # Global path prefix (hack with relative_url_root)
3
+ #
4
+ GLOBAL_PATH_PREFIX_DELIMITER = '-'
5
+ ActionController::Base.send :class_eval do
6
+ def self.global_path_prefix
7
+ @global_path_prefix ||= []
8
+ end
9
+
10
+ def self.global_path_prefix= list
11
+ @global_path_prefix = list.collect{|v| v.to_s}
12
+ end
13
+
14
+ cattr_accessor :_relative_url_root
15
+ end
16
+ ActionController::Base._relative_url_root = ActionController::Base.relative_url_root || ""
17
+
18
+ #
19
+ # Generation
20
+ #
21
+
22
+ # routes
23
+ ActionController::Base.send :class_eval do
24
+ around_filter :hack_relative_url_root
25
+ protected
26
+
27
+ # preparing relative_url_root from params
28
+ def hack_relative_url_root
29
+ begin
30
+ update_relative_url_root!
31
+ yield
32
+ ensure
33
+ ActionController::Base.relative_url_root = ActionController::Base._relative_url_root
34
+ end
35
+ end
36
+
37
+ def update_relative_url_root!
38
+ prefix_params = []
39
+ ActionController::Base.global_path_prefix.each do |name|
40
+ unless (param = params[name]).blank?
41
+ prefix_params << [name, CGI.escape(param)]
42
+ end
43
+ end
44
+ prefix = prefix_params.collect{|name, param| "#{param}#{GLOBAL_PATH_PREFIX_DELIMITER}#{name}"}.join('/')
45
+ ActionController::Base.relative_url_root = ActionController::Base._relative_url_root + (prefix.blank? ? "" : "/" + prefix)
46
+ end
47
+ end
48
+
49
+ #
50
+ # Usability
51
+ # allows to install a global_path_prefix to the route set by calling: map.global_path_prefix 'locale'
52
+ ActionController::Routing::RouteSet::Mapper.class_eval do
53
+ def global_path_prefix *args
54
+ ActionController::Base.global_path_prefix = args
55
+ end
56
+ end
@@ -0,0 +1,9 @@
1
+ #
2
+ # ordinary and ajax flash[:info] (othervise it appears twice with ajax requests)
3
+ #
4
+ ActionController::Base.class_eval do
5
+ def flash_with_ajax
6
+ request.xhr? ? flash_without_ajax.now : flash_without_ajax
7
+ end
8
+ alias_method_chain :flash, :ajax
9
+ end
@@ -0,0 +1,19 @@
1
+ ActionController::Base.send :class_eval do
2
+ protected
3
+ def redirect_to_with_ajax *args
4
+ if request.xhr?
5
+ preserve_flash_for_ajax_page_update
6
+ render :inline => "window.location = '#{url_for *args}';", :layout => 'application'
7
+ else
8
+ redirect_to_without_ajax *args
9
+ end
10
+ end
11
+ alias_method_chain :redirect_to, :ajax
12
+
13
+ private
14
+ def preserve_flash_for_ajax_page_update
15
+ # save flash.now (that are marked as used) with ajax redirect
16
+ used = flash_without_ajax.instance_variable_get '@used'
17
+ used.clear
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ ActionView::Helpers::JavaScriptHelper.class_eval do
2
+ def javascript_cdata_section_with_defer content
3
+ if defer_scripts?
4
+ raise "Deferred scripts already called!" if Thread.current[:deferred_scripts_called]
5
+ content = <<END
6
+ deferred.push(function(){
7
+
8
+ #{content}
9
+
10
+ });
11
+ END
12
+ end
13
+
14
+ javascript_cdata_section_without_defer content
15
+ end
16
+ alias_method_chain :javascript_cdata_section, :defer
17
+ end
@@ -0,0 +1,33 @@
1
+ # asset_path
2
+ ActionView::Helpers::AssetTagHelper.class_eval do
3
+ private
4
+ def compute_public_path_with_global_prefix *args, &block
5
+ tmp = ActionController::Base.relative_url_root
6
+ begin
7
+ ActionController::Base.relative_url_root = ActionController::Base._relative_url_root
8
+ compute_public_path_without_global_prefix *args, &block
9
+ ensure
10
+ ActionController::Base.relative_url_root = tmp
11
+ end
12
+ end
13
+ alias_method_chain :compute_public_path, :global_prefix
14
+ end
15
+
16
+ #
17
+ # Recognition
18
+ # delete global_path_prefix from path before rails recognition
19
+ ActionController::Routing::RouteSet.send :class_eval do
20
+ def recognize_path_with_global_prefix path, environment={}
21
+ prefix_params = {}
22
+ new_path = path.clone
23
+ ActionController::Base.global_path_prefix.each do |name|
24
+ new_path.gsub! /\A\/.+?#{GLOBAL_PATH_PREFIX_DELIMITER}#{name}/ do |value|
25
+ prefix_params[name] = CGI.unescape value[1..-(name.size + GLOBAL_PATH_PREFIX_DELIMITER.size + 1)]
26
+ ""
27
+ end
28
+ end
29
+ params = recognize_path_without_global_prefix new_path, environment
30
+ return params.merge prefix_params
31
+ end
32
+ alias_method_chain :recognize_path, :global_prefix
33
+ end
@@ -0,0 +1,106 @@
1
+ #
2
+ # link_to without form creating mess
3
+ # and link_to with ajax support
4
+ #
5
+ String.send :class_eval do
6
+ attr_accessor :_url_format
7
+ end
8
+
9
+ ActionController::UrlRewriter.send :class_eval do
10
+ def rewrite(options = {})
11
+ url = rewrite_url(options)
12
+
13
+ # needed for link_to with ajax
14
+ url._url_format = options[:format] if options[:format]
15
+ url
16
+ end
17
+ end
18
+
19
+ ActionView::Helpers::UrlHelper.send :class_eval do
20
+ AJAX_FORMATS = ['js', 'json']
21
+
22
+ def url_for(options = {})
23
+ options ||= {}
24
+ url = case options
25
+ when String
26
+ escape = true
27
+ options
28
+ when Hash
29
+ options = { :only_path => options[:host].nil? }.update(options.symbolize_keys)
30
+ escape = options.key?(:escape) ? options.delete(:escape) : true
31
+ @controller.send(:url_for, options)
32
+ when :back
33
+ escape = false
34
+ @controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
35
+ else
36
+ escape = false
37
+ polymorphic_path(options)
38
+ end
39
+
40
+ # changes begins here
41
+ if escape
42
+ _url_format = url._url_format
43
+ url = escape_once(url)
44
+ url._url_format = _url_format
45
+ end
46
+ url
47
+ end
48
+
49
+ def link_to(*args, &block)
50
+ if block_given?
51
+ options = args.first || {}
52
+ html_options = args.second
53
+ concat(link_to(capture(&block), options, html_options))
54
+ else
55
+ name = args.first
56
+ options = args.second || {}
57
+ html_options = args.third
58
+
59
+ url = url_for(options)
60
+
61
+ # html_options
62
+ html_options ||= {}
63
+ html_options = html_options.stringify_keys
64
+
65
+ html_options['ajax'] ||= (url._url_format and AJAX_FORMATS.include? url._url_format.to_s)
66
+
67
+ href = html_options['href']
68
+ convert_options_to_javascript!(html_options, url)
69
+ tag_options = tag_options(html_options)
70
+
71
+ href_attr = "href=\"#{url}\"" unless href
72
+ "<a #{href_attr}#{tag_options}>#{name || url}</a>"
73
+ end
74
+ end
75
+
76
+ private
77
+ def convert_options_to_javascript!(html_options, url = '')
78
+ confirm, ajax = html_options.delete("confirm"), (html_options.delete('ajax') || false)
79
+
80
+ method, href = html_options.delete("method"), html_options['href']
81
+
82
+ onclick = if ajax
83
+ method ||= :get
84
+ %{$(this).link_to({method: '#{method}', ajax: true}); return false;}
85
+ elsif method
86
+ %{$(this).link_to({method: '#{method}'}); return false;}
87
+ else
88
+ nil
89
+ end
90
+
91
+ if onclick and ActionController::Base.defer_scripts?
92
+ html_options['class'] ||= ""
93
+ html_options['class'] << "_deferred"
94
+ end
95
+
96
+ if confirm
97
+ onclick = if onclick
98
+ "if (#{confirm_javascript_function(confirm)}) { #{onclick} };return false;"
99
+ else
100
+ "return #{confirm_javascript_function(confirm)};"
101
+ end
102
+ end
103
+
104
+ html_options["onclick"] = onclick if onclick
105
+ end
106
+ end
@@ -0,0 +1,20 @@
1
+ # Merges default_scopes and accepts blocks
2
+ if defined?(ActiveRecord)
3
+ ActiveRecord::Base.class_eval do
4
+ class << self
5
+ def default_scoping
6
+ hash_poser = HashPoser.new do
7
+ hashes = merged_default_scopes.collect do |scope|
8
+ scope = scope.is_a?(Proc) ? scope.call : scope
9
+ scope[:create] ||= {}
10
+ scope
11
+ end
12
+
13
+ merged = hashes.inject({}, :deep_merge)
14
+ { :find => merged, :create => (merged[:conditions] || {})}
15
+ end
16
+ [hash_poser]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ # By default Rails optimizes named routes and doesn't adds default_url_options, so we fix this.
2
+ ActionController::Base.send :helper_method, :default_url_options
3
+
4
+ ActionController::Routing::Optimisation::PositionalArguments.send :class_eval do
5
+ def guard_conditions_with_def_url_opt
6
+ guard_conditions_without_def_url_opt << "default_url_options(nil).blank?"
7
+ end
8
+ alias_method_chain :guard_conditions, :def_url_opt
9
+ end
10
+
11
+ ActionController::Routing::Optimisation::PositionalArgumentsWithAdditionalParams.send :class_eval do
12
+ def guard_conditions_with_def_url_opt
13
+ guard_conditions_without_def_url_opt << "default_url_options(nil).blank?"
14
+ end
15
+ alias_method_chain :guard_conditions, :def_url_opt
16
+ end
@@ -0,0 +1,2 @@
1
+ # Allow layout for RJS
2
+ ActionView::Template.send(:class_variable_set, :@@exempt_from_layout, Set.new)
@@ -0,0 +1,45 @@
1
+ module Rails
2
+ class << self
3
+ def development?
4
+ RAILS_ENV == 'development'
5
+ end
6
+
7
+ def test?
8
+ RAILS_ENV == 'test'
9
+ end
10
+
11
+ def production?
12
+ RAILS_ENV == 'production'
13
+ end
14
+
15
+ def development *args, &block
16
+ if development?
17
+ if block
18
+ block.call
19
+ else
20
+ return *args
21
+ end
22
+ end
23
+ end
24
+
25
+ def test *args, &block
26
+ if test?
27
+ if block
28
+ block.call
29
+ else
30
+ return *args
31
+ end
32
+ end
33
+ end
34
+
35
+ def production *args, &block
36
+ if production?
37
+ if block
38
+ block.call
39
+ else
40
+ return *args
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,125 @@
1
+ begin
2
+ Globalize # should be defined
3
+
4
+ # Russian pluralization
5
+ I18n.backend.add_pluralizer :ru, lambda{|n|
6
+ # Правило плюрализации для русского языка, взято из CLDR, http://unicode.org/cldr/
7
+ #
8
+ #
9
+ # Russian language pluralization rules, taken from CLDR project, http://unicode.org/cldr/
10
+ #
11
+ # one -> n mod 10 is 1 and n mod 100 is not 11;
12
+ # few -> n mod 10 in 2..4 and n mod 100 not in 12..14;
13
+ # many -> n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14;
14
+ # other -> everything else
15
+ #
16
+ # Пример
17
+ #
18
+ # :one = 1, 21, 31, 41, 51, 61...
19
+ # :few = 2-4, 22-24, 32-34...
20
+ # :many = 0, 5-20, 25-30, 35-40...
21
+ # :other = 1.31, 2.31, 5.31...
22
+ n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other
23
+ }
24
+
25
+ # t() and t_scope()
26
+ list = [Object, ActionController::Base, ActionView::Base, ActionMailer::Base]
27
+ list << ActiveRecord::Base if defined?(ActiveRecord)
28
+ list.each do |_class|
29
+ _class.class_eval do
30
+
31
+ # def self.t_scope_value; end # hack, becouse of rails method_missing magic it causes error
32
+ # def t_scope_value; end # hack, becouse of rails method_missing magic it causes error
33
+
34
+ def self.t_scope *scope
35
+ class_inheritable_accessor :t_scope_value
36
+ self.t_scope_value = scope
37
+ end
38
+
39
+ # finding translation in all class hierarchy
40
+ def t message, params = {}
41
+ result = nil
42
+
43
+ aclass = self.is_a?(Class) ? self : self.class
44
+ list = aclass.ancestors
45
+ list.unshift self unless self.is_a?(Class) # hack for ActionView and ActionMailer
46
+
47
+ list.each do |c|
48
+ begin
49
+ next unless t_scope = c.respond_to(:t_scope_value)
50
+ rescue NameError # hack for rails method_missing magic
51
+ next
52
+ end
53
+
54
+ t_scope.each do |ts|
55
+ begin
56
+ result = I18n.t "#{ts}.#{message}", params.merge(:raise => true)
57
+ rescue I18n::MissingTranslationData
58
+ end
59
+ break if result
60
+ end
61
+
62
+ break if result
63
+ end
64
+
65
+ result ||= I18n.t message, params
66
+ result.to_s # Globalize2 uses Translation::Static instead of String
67
+ end
68
+ end
69
+ end
70
+
71
+ # ActionController::Base.class_eval do
72
+ # # Becouse we need to transfer @t_scope also to View
73
+ # def initialize_with_t_scope *args, &block
74
+ # initialize_without_t_scope *args, &block
75
+ # t_scope = self.class.t_scope_value
76
+ # @t_scope_value = t_scope if t_scope
77
+ # end
78
+ # alias_method_chain :initialize, :t_scope
79
+ # end
80
+
81
+ ActionView::Base.class_eval do
82
+ def t_scope_value
83
+ controller.class.t_scope_value if controller.class.respond_to? :t_scope_value
84
+ end
85
+ end
86
+
87
+ ActionMailer::Base.class_eval do
88
+ def t_scope_value
89
+ controller.class.t_scope_value if controller.class.respond_to? :t_scope_value
90
+ end
91
+ # def t_scope scope
92
+ # raise 'stub! use the same'
93
+ # @t_scope = scope
94
+ # @body[:t_scope] = @t_scope
95
+ # end
96
+ end
97
+
98
+ # Prepare locale in Controller
99
+ module ActionController
100
+ module Acts
101
+ module Localized
102
+ def self.included(base)
103
+ base.extend(ClassMethods)
104
+ end
105
+
106
+ module ClassMethods
107
+ def acts_as_localized
108
+ include ActionController::Acts::Localized::InstanceMethods
109
+
110
+ before_filter :prepare_locale
111
+ end
112
+ end
113
+
114
+ module InstanceMethods
115
+ def prepare_locale
116
+ I18n.locale = params[:l] unless params[:l].blank?
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ ActionController::Base.send :include, ActionController::Acts::Localized
123
+ # rescue NameError
124
+ # puts "i18n_helper (from rails_commons) disabled"
125
+ end
@@ -0,0 +1,40 @@
1
+ # Hack to use dynamic default_scope
2
+ class HashPoser < Proc
3
+ include Enumerable
4
+
5
+ attr_accessor :proc
6
+
7
+ def initialize &b
8
+ @proc = b
9
+ super &b
10
+ end
11
+
12
+ def [](key)
13
+ call[key]
14
+ end
15
+
16
+ def each(*a, &b)
17
+ call.each(*a, &b)
18
+ end
19
+
20
+ def fetch(key)
21
+ call.fetch(key)
22
+ end
23
+
24
+ def keys
25
+ call.keys
26
+ end
27
+
28
+ def merge(*a, &b)
29
+ call.merge(*a, &b)
30
+ end
31
+
32
+ def to_hash
33
+ call
34
+ end
35
+
36
+ def to_s
37
+ "#<HashPoser: #{call.inspect}>"
38
+ end
39
+ alias_method :inspect, :to_s
40
+ end
@@ -0,0 +1,16 @@
1
+ # Merges default_scopes and accepts blocks
2
+ if defined?(ActiveRecord)
3
+ ActiveRecord::Base.class_eval do
4
+ class_inheritable_accessor :merged_default_scopes
5
+ self.merged_default_scopes = []
6
+
7
+ class << self
8
+ def default_scope options = nil, &block
9
+ self.merged_default_scopes << (options || block).should_not!(:be_nil)
10
+ end
11
+
12
+ # open with_exclusive_scope
13
+ public :with_exclusive_scope
14
+ end
15
+ end
16
+ end
@@ -0,0 +1 @@
1
+ STRONG_NAME = /\A[a-zA-Z_][a-zA-Z_0-9]*\Z/
@@ -0,0 +1,88 @@
1
+ ActionController::Base.send :class_eval do
2
+ protected
3
+
4
+ DO_NOT_PERSIST = ['_', '_method']
5
+
6
+ def default_url_options options = {}
7
+ persistent_params = {}
8
+
9
+ if options and (Thread.current[:persist_params] or options.delete(:persist))
10
+ options = options.stringify_keys
11
+ params.each do |key, value|
12
+ persist = (
13
+ (key =~ /^_/) and
14
+ !(options.include?(key) or DO_NOT_PERSIST.include?(key))
15
+ )
16
+
17
+ persistent_params[key] = value if persist
18
+ end
19
+ end
20
+
21
+ global_persistent_params.merge persistent_params
22
+ end
23
+
24
+ def persist_params &block
25
+ before = Thread.current[:persist_params]
26
+ begin
27
+ Thread.current[:persist_params] = true
28
+ block.call
29
+ ensure
30
+ Thread.current[:persist_params] = before
31
+ end
32
+ end
33
+ helper_method :persist_params
34
+
35
+ def do_not_persist_params &block
36
+ before = Thread.current[:persist_params]
37
+ begin
38
+ Thread.current[:persist_params] = false
39
+ block.call
40
+ ensure
41
+ Thread.current[:persist_params] = before
42
+ end
43
+ end
44
+ helper_method :do_not_persist_params
45
+
46
+ def prepare_global_persistent_params
47
+ persistent_params = ActionController::Base.global_persistent_params
48
+ prefix_params = ActionController::Base.global_path_prefix
49
+ params = self.params.stringify_keys
50
+ params.each do |key, value|
51
+ if persistent_params.include?(key) and !prefix_params.include?(key)
52
+ global_persistent_params[key] = value
53
+ end
54
+ end
55
+ end
56
+ def global_persistent_params
57
+ @global_persistent_params ||= {}
58
+ end
59
+ before_filter :prepare_global_persistent_params
60
+
61
+ class << self
62
+ def global_persistent_params= params
63
+ @global_persistent_params = params.collect &:to_s
64
+ end
65
+
66
+ def global_persistent_params
67
+ @global_persistent_params ||= []
68
+ end
69
+
70
+ def persist_params *args
71
+ if args.empty?
72
+ around_filter :persist_params
73
+ elsif args.first.is_a? Hash
74
+ # args.first.should! :be_a, Hash
75
+ around_filter :persist_params, args.first
76
+ else
77
+ around_filter :persist_params, :only => args.first
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ # allows to install a global_persistent_params to the route set by calling: map.global_persistent_params 'locale'
84
+ ActionController::Routing::RouteSet::Mapper.class_eval do
85
+ def global_persistent_params *args
86
+ ActionController::Base.global_persistent_params = args
87
+ end
88
+ end
@@ -0,0 +1,14 @@
1
+ ActionController::Base.send :class_eval do
2
+ protected
3
+ def default_path options = {}
4
+ url_for_path SETTING.default_path!, options.merge(:no_prefix => true)
5
+ end
6
+
7
+ def return_to_path options = {}
8
+ do_not_persist_params do
9
+ url_for_path params[:_return_to] || session[:return_to] || SETTING.default_path!, options.merge(:no_prefix => true)
10
+ end
11
+ end
12
+
13
+ helper_method :default_path, :return_to_path
14
+ end
@@ -0,0 +1,7 @@
1
+ ActionController::Base.send :class_eval do
2
+ protected
3
+ def reload_page
4
+ preserve_flash_for_ajax_page_update
5
+ render :inline => "window.location.reload();", :layout => 'application'
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ class UserError < RuntimeError
2
+ end
3
+
4
+ Object.send :class_eval do
5
+ def raise_user_error msg
6
+ raise UserError, msg
7
+ end
8
+
9
+ def self.raise_user_error msg
10
+ raise UserError, msg
11
+ end
12
+ end
data/lib/rails_ext.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'activesupport'
2
+
3
+ require 'rails_ext/action_controller'
4
+ require 'rails_ext/action_view'
5
+ require 'rails_ext/active_record'
6
+
7
+ require 'rails_ext/model'
8
+
9
+ require 'rails_ext/config_files/safe_hash'
10
+ require 'rails_ext/config_files'
11
+
12
+ require 'rails_ext/defer_javascript'
13
+ require 'rails_ext/hacks/defer_javascript'
14
+
15
+ require 'rails_ext/email_config'
16
+
17
+ require 'rails_ext/create_public_symlinks'
18
+
19
+ # right now globalize2 not accessible as gem (it's broken)
20
+ # so, we need to include it as rails plugin and include this in initializer.
21
+ # require 'rails_ext/i18n_helper'