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.
- 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'
|