rails-ext 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.git/COMMIT_EDITMSG +1 -0
- data/.git/HEAD +1 -0
- data/.git/config +12 -0
- data/.git/description +1 -0
- data/.git/hooks/applypatch-msg.sample +15 -0
- data/.git/hooks/commit-msg.sample +24 -0
- data/.git/hooks/post-commit.sample +8 -0
- data/.git/hooks/post-receive.sample +15 -0
- data/.git/hooks/post-update.sample +8 -0
- data/.git/hooks/pre-applypatch.sample +14 -0
- data/.git/hooks/pre-commit.sample +46 -0
- data/.git/hooks/pre-rebase.sample +169 -0
- data/.git/hooks/prepare-commit-msg.sample +36 -0
- data/.git/hooks/update.sample +128 -0
- data/.git/index +0 -0
- data/.git/info/exclude +6 -0
- data/.git/logs/HEAD +6 -0
- data/.git/logs/refs/heads/master +6 -0
- data/.git/logs/refs/remotes/origin/master +5 -0
- data/.git/objects/02/469b717b4bd61ad27a3fe664ce0646a8325399 +2 -0
- data/.git/objects/06/c3225bad9d5b80e7b3bde79ff3c2da591722bf +5 -0
- data/.git/objects/07/f7d26527e58caa2fa99e33b29a7791b9eb8b3e +0 -0
- data/.git/objects/09/20505d42c0044b31ff7b1f86cec6e282e13414 +0 -0
- data/.git/objects/0b/e101a0586410212b4ee5905881ad726b7b4907 +0 -0
- data/.git/objects/10/bfe1230b9d96e23600091cc8b4b9d378068101 +0 -0
- data/.git/objects/13/882df4f2ef911454bf3b69a85742b372723366 +2 -0
- data/.git/objects/15/3f845625a0f605a2a35487a32038d0349bc386 +0 -0
- data/.git/objects/18/77033b90ed3dd55a3034b7e3ca1c5c9f66868d +0 -0
- data/.git/objects/19/1f68644a3646d774f2546c4cd49ac7d66f4cc2 +0 -0
- data/.git/objects/1d/d49713de2942dc974e55adc3684f55b2b817e2 +0 -0
- data/.git/objects/1e/6374b23c71a07b0e414e80912fd45503bd3daf +0 -0
- data/.git/objects/29/7a2c413b11f78b69dd8caa4f334c9536088f8a +3 -0
- data/.git/objects/29/b1f8abaed4aea1da8f8bd5f1bd81c26058c41a +3 -0
- data/.git/objects/2a/04524c8458b2d0cd9bcec579f9d54368a9d35f +0 -0
- data/.git/objects/2d/043376f1bc26b2dad3e79fc72ea14341ea437d +0 -0
- data/.git/objects/2e/3e3fc8e46949a9b944da3c36207c444aa2c9b7 +0 -0
- data/.git/objects/30/69d4978bbdfacf4402c4339438b29657275f2c +0 -0
- data/.git/objects/36/9902ca51d5820a02ccccbf1cac6ed09051941d +0 -0
- data/.git/objects/3a/03b9d44de43472689300120ffb2a0a9a74f27f +0 -0
- data/.git/objects/3a/797683953be7e6d0ffa0e34514f3e8e9c3ceb0 +3 -0
- data/.git/objects/3f/3db6bb5a5204ae58e303959c4c0da3a70d8b35 +1 -0
- data/.git/objects/40/215c0554202fc46dc2fca94ed21e2920ce1e84 +0 -0
- data/.git/objects/4b/2bdb2dc6330ba9bafd9058ec8eaa925ef53f91 +0 -0
- data/.git/objects/4d/991a018b0c697fa119efe7aaf55df0a1c7af8e +0 -0
- data/.git/objects/4f/fa8f1c9b7e3fdbb23ab600722d1011dcb48cec +2 -0
- data/.git/objects/55/d1f1efc344266d472094b1fd2f247b97de1c8b +0 -0
- data/.git/objects/57/8a722fd66124331e07123e3a0de2b6b50a581b +3 -0
- data/.git/objects/59/0ef6ba9931d75fbddc7a940044dbaaa50efc76 +0 -0
- data/.git/objects/5a/35fa85474278f3c817aa59d07b725428c41a28 +0 -0
- data/.git/objects/60/a681e873ca0ae0b7da3f37dbc5701f6e42b970 +1 -0
- data/.git/objects/61/32f3f8005ce5b88165162ac5542e54d0472a82 +3 -0
- data/.git/objects/65/51094fa3b996ff25b88d7ddb21d21a811d53fc +2 -0
- data/.git/objects/67/850cf1ede94d80c9b07ceace074a4d62f15249 +0 -0
- data/.git/objects/68/8ce506ac4f7c160bd6880d8507820761a3b3b7 +0 -0
- data/.git/objects/6d/f725e3519872a75bc763045f00d8844eb890cf +0 -0
- data/.git/objects/71/e6b43e9d41f9903992fd86d483b7d3e4dd28cd +0 -0
- data/.git/objects/75/d0b250bcdf241d981313b1d6eb153b96e4b05f +2 -0
- data/.git/objects/7d/978ee312ca2119dc84e40431182b8f68e42f53 +1 -0
- data/.git/objects/87/fc827fd223cac6b4e55d823a9ea86bb0726a3b +0 -0
- data/.git/objects/8d/4dcde8df4da8f53f5f5313757b907e9aa1af66 +0 -0
- data/.git/objects/8e/69b6cf3ec8b49270091b4a206ccf326679dc20 +0 -0
- data/.git/objects/92/e1c250edfca72ed0932934257ef3cfc7122ec5 +0 -0
- data/.git/objects/92/e1f3936e7c33007d0a466b836804450992a1eb +1 -0
- data/.git/objects/93/f9a6b596879347290cde161b03052bb22021de +5 -0
- data/.git/objects/94/72f3ac9e890231482aadd774bdc1c9ba742497 +0 -0
- data/.git/objects/a7/6c4944dc009628cb65b4962464a8eb484d6a71 +0 -0
- data/.git/objects/ac/92bcf6c74d23824c3c7ce341f667507592c7f9 +0 -0
- data/.git/objects/b0/2c48116db702256abf27fab4236c84bd2d2dbc +2 -0
- data/.git/objects/b0/39fcd38009980eb74d6bcef22d11e02639a530 +0 -0
- data/.git/objects/b2/cd852090540d0b2450b901397edd924d8c0ba9 +0 -0
- data/.git/objects/b4/228251babf3a84ac181d462fdd383816bd23b8 +0 -0
- data/.git/objects/b5/edd343ceb8e87d1a73922612aec210b393f839 +0 -0
- data/.git/objects/bb/23236d2e8340087cc495c66310e6eb90d6fe0a +0 -0
- data/.git/objects/bc/90a06dd2f2257e8da49989738db5747e2b78d8 +4 -0
- data/.git/objects/bd/eab0ec8a914cdd8c9341340191c116a4bf2d3e +0 -0
- data/.git/objects/c0/724bc45e241d336d6376f14d9b258c2e4744d4 +0 -0
- data/.git/objects/c1/3cf3c2ea85ec40544fe31702b2cfe6091aed6e +0 -0
- data/.git/objects/c5/64ac68ebc8e0db7a6355a45f3299829ef2a825 +0 -0
- data/.git/objects/ca/c13b06411cdb70ac35d51ecf9efb0907645bd1 +0 -0
- data/.git/objects/d1/38a420782e818f3f87c6c8c0a0a135639a30d9 +0 -0
- data/.git/objects/d2/85be6e2891e063625d4904c9bcca42bf6f0b83 +0 -0
- data/.git/objects/d4/1e2336bcd3ce3d09a9fa6c3af3270c29bd8457 +1 -0
- data/.git/objects/d5/86dc7698c6ec37db86e9f36a16bd671e0005ab +0 -0
- data/.git/objects/d5/a2b441718a88aa08fa937352a6d80319bc91c0 +0 -0
- data/.git/objects/e0/d8e7ab5a565d95d44f2a9a6246be6003a3de7b +0 -0
- data/.git/objects/e2/bc2615d3aa154bba2897c562a15ed19136d518 +0 -0
- data/.git/objects/e3/a7cacb84225125a2bc91b42394e7de7de7b205 +0 -0
- data/.git/objects/e3/cde2715e3e3870a5d7312cac9bbf6e24259e0f +0 -0
- data/.git/objects/e4/d7cacac2d7e66df5a7c21eaae71c0a90f1439d +0 -0
- data/.git/objects/e7/f4b26a3258b7788ffe2665773387e19c01095a +3 -0
- data/.git/objects/ea/50407bf8daef694d22268540dd55eb3a739bad +4 -0
- data/.git/objects/eb/9701e2dbe8fb606315f9514d789188160bdd67 +2 -0
- data/.git/objects/ee/ccaf0d272346a1dcc672a4131ba692a0027049 +2 -0
- data/.git/objects/f2/196f15b2d432b2a2d641aed4ae5afe7190edb9 +1 -0
- data/.git/objects/f3/3573a82a9e7dbf9bc7f5b3feded4c223701d1f +0 -0
- data/.git/objects/f3/7784042bc99c16c02fd104dda82aafa42d4c9c +0 -0
- data/.git/objects/f5/91a5c39e03e2102c9101db957b48c8c76e194c +0 -0
- data/.git/objects/f9/8d0f95460a7a3f63ab4c08ad5508fd32d1b5c2 +0 -0
- data/.git/objects/pack/pack-c7edd4d292858ed6a37a55c1b6ceb35f65f4587e.idx +0 -0
- data/.git/objects/pack/pack-c7edd4d292858ed6a37a55c1b6ceb35f65f4587e.pack +0 -0
- data/.git/packed-refs +2 -0
- data/.git/refs/heads/master +1 -0
- data/.git/refs/remotes/origin/HEAD +1 -0
- data/.git/refs/remotes/origin/master +1 -0
- data/.gitignore +5 -0
- data/README.rdoc +14 -0
- data/Rakefile +63 -0
- data/lib/rails_ext/action_controller.rb +19 -0
- data/lib/rails_ext/action_controller_ext.rb +29 -0
- data/lib/rails_ext/action_view.rb +5 -0
- data/lib/rails_ext/active_record.rb +7 -0
- data/lib/rails_ext/active_record_ext.rb +15 -0
- data/lib/rails_ext/basic.rb +7 -0
- data/lib/rails_ext/common_helper.rb +83 -0
- data/lib/rails_ext/config_files/safe_hash.rb +96 -0
- data/lib/rails_ext/config_files.rb +18 -0
- data/lib/rails_ext/create_public_symlinks.rb +9 -0
- data/lib/rails_ext/defer_javascript.rb +51 -0
- data/lib/rails_ext/email_config.rb +8 -0
- data/lib/rails_ext/global_path_prefix.rb +56 -0
- data/lib/rails_ext/hacks/ajax_flash.rb +9 -0
- data/lib/rails_ext/hacks/ajax_redirect_to.rb +19 -0
- data/lib/rails_ext/hacks/defer_javascript.rb +17 -0
- data/lib/rails_ext/hacks/global_path_prefix.rb +33 -0
- data/lib/rails_ext/hacks/link_to.rb +106 -0
- data/lib/rails_ext/hacks/merge_default_scope.rb +20 -0
- data/lib/rails_ext/hacks/persistent_params.rb +16 -0
- data/lib/rails_ext/hacks/rjs_layout.rb +2 -0
- data/lib/rails_ext/handy_environment.rb +45 -0
- data/lib/rails_ext/i18n_helper.rb +125 -0
- data/lib/rails_ext/merge_default_scope/hash_poser.rb +40 -0
- data/lib/rails_ext/merge_default_scope.rb +16 -0
- data/lib/rails_ext/model.rb +1 -0
- data/lib/rails_ext/persistent_params.rb +88 -0
- data/lib/rails_ext/redirect_helper.rb +14 -0
- data/lib/rails_ext/reload_page.rb +7 -0
- data/lib/rails_ext/user_error.rb +12 -0
- data/lib/rails_ext.rb +21 -0
- data/spec/safe_hash_spec.rb +71 -0
- data/spec/spec.opts +3 -0
- 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,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,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
|
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'
|