rails-ext 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 (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'