asset_pipeline_routes 0.0.3 → 0.0.4
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/README.md +12 -7
- data/lib/asset_pipeline_routes.rb +8 -7
- data/lib/asset_pipeline_routes/js_function_helper.rb +1 -0
- data/lib/asset_pipeline_routes/path.rb +51 -0
- data/lib/asset_pipeline_routes/routes.rb +34 -0
- data/lib/asset_pipeline_routes/routes_context.rb +2 -3
- data/lib/asset_pipeline_routes/version.rb +2 -1
- data/spec/asset_pipeline_routes_spec.rb +31 -13
- data/spec/path_spec.rb +32 -0
- data/spec/spec_helper.rb +2 -1
- metadata +12 -10
- data/lib/asset_pipeline_routes/routes_helper.rb +0 -26
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Getting your Rails routes into the Rails 3.2 asset pipeline is really easy. Just
|
4
4
|
`include Rails.application.routes.url_helpers` and you have all your routes available.
|
5
5
|
|
6
|
-
But except for hard-coded links this won't help you, because
|
6
|
+
But except for hard-coded links this won't help you, because in production you have to pass in resource parameters at compile-time, where they are not available.
|
7
7
|
|
8
8
|
Heh, you might think! Just call a route helper and pass in a dynamic parameter mapping, like
|
9
9
|
`user_path('{{id}}')`. Sadly this won't yield the desired result! Instead of `/users/{{id}}`, you'll be presented with `/users/%7B%7Bid%7D%7D` because you're mapping just got html_escaped!
|
@@ -21,25 +21,30 @@ Here's an example, assuming you got a routes.rb with
|
|
21
21
|
resources :users # => yields multiple routes, e.g. /users/:id(.:format)
|
22
22
|
|
23
23
|
in it. Then, in you're javascript file you'd call `r.users_path`. All path fragments are replaced with Mustache-style attribute bindings by default:
|
24
|
-
|
24
|
+
|
25
25
|
# application.js.coffee.erb
|
26
26
|
userPath = '<%= r.user_path %>' # => yields /users/{{id}}
|
27
27
|
usersPath = '<%= r.users_path %>' # => yields /users
|
28
28
|
|
29
29
|
You can even hook up member- or collection routes, whatever you like really. Just prefix your routes with `r.` and you can directly use them in your asset-pipeline!
|
30
30
|
|
31
|
-
All `_path`-methods take an arbitrary argument which is used to evaluate the final route.
|
31
|
+
All `_path`-methods take an arbitrary argument which is used to evaluate the final route.
|
32
32
|
So if you want a regexp matching all users-show actions, you can do it just like this:
|
33
33
|
|
34
34
|
# application.js.coffee.erb
|
35
35
|
usersPath = '<%= r.user_path '\d+' %>' # => yields /users/\d+
|
36
|
-
|
36
|
+
|
37
37
|
Sometimes you want to generate the URL for a given resource on the client-side entirely. That's possible as well:
|
38
38
|
|
39
|
+
# application.js.erb
|
40
|
+
var editUserRoute = <%= r.edit_user_path_method %>; // => yields anonymous function in js
|
41
|
+
var editUserPath = editUserRoute(42); // => yields '/users/42/edit'
|
42
|
+
|
43
|
+
# or, if you prefer CoffeeScript:
|
39
44
|
# application.js.coffee.erb
|
40
|
-
|
41
|
-
editUserPath = editUserRoute(42) # => yields /users/42/edit
|
42
|
-
|
45
|
+
editUserPath = <%= r.edit_user_path_method(:coffee) %>
|
46
|
+
editUserPath = editUserRoute(42) # => yields '/users/42/edit'
|
47
|
+
|
43
48
|
Now you have total control over your Rails routes.
|
44
49
|
|
45
50
|
# Addendum
|
@@ -1,16 +1,17 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require_relative "asset_pipeline_routes/version"
|
2
|
-
require_relative "asset_pipeline_routes/
|
3
|
+
require_relative "asset_pipeline_routes/routes"
|
3
4
|
|
4
5
|
module AssetPipelineRoutes
|
5
6
|
class Railtie < ::Rails::Railtie
|
6
7
|
initializer "asset_pipeline_routes.environment" do |app|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
ActiveSupport.on_load(:action_view) do
|
9
|
+
include ::AssetPipelineRoutes::RoutesContext
|
10
|
+
|
11
|
+
app.assets.context_class.instance_eval do
|
12
|
+
include ::AssetPipelineRoutes::RoutesContext
|
12
13
|
end
|
13
|
-
|
14
|
+
end
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module AssetPipelineRoutes
|
3
|
+
class Path
|
4
|
+
DEFAULT_REPLACEMENT = '{{\1}}'
|
5
|
+
|
6
|
+
attr_accessor :route
|
7
|
+
|
8
|
+
def self.proc_for_route route
|
9
|
+
proc { |id_replacement = DEFAULT_REPLACEMENT, *args|
|
10
|
+
proc { |route, replacement, *mapping|
|
11
|
+
Path.new(route.path.ast.to_s).build replacement, *mapping
|
12
|
+
}.curry[route].call(id_replacement, *args)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize route_str
|
17
|
+
@route = route_str
|
18
|
+
end
|
19
|
+
|
20
|
+
def apply_format options = {}
|
21
|
+
@route = @route.sub(/\(\.:\w+\)/,format(options))
|
22
|
+
end
|
23
|
+
|
24
|
+
def build *args
|
25
|
+
apply_format args.extract_options!
|
26
|
+
replacements(*args).inject(@route) { |route, param|
|
27
|
+
route.sub(/:(\w+)/, param.to_s)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def format options
|
32
|
+
str = options.fetch(:format) { '' }
|
33
|
+
str = ".#{str}" unless str.empty? && str[0] != '.'
|
34
|
+
str
|
35
|
+
end
|
36
|
+
|
37
|
+
def default_replacements
|
38
|
+
Array.new(number_of_replacements, DEFAULT_REPLACEMENT)
|
39
|
+
end
|
40
|
+
|
41
|
+
def replacements *args
|
42
|
+
defaults = default_replacements
|
43
|
+
defaults[0...args.length] = args
|
44
|
+
defaults
|
45
|
+
end
|
46
|
+
|
47
|
+
def number_of_replacements
|
48
|
+
@route.scan(/:(\w+)/).inject(0) { |sum, n| sum + 1 }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "active_support/core_ext/array/extract_options"
|
3
|
+
|
4
|
+
require_relative "routes_context"
|
5
|
+
require_relative "js_function_helper"
|
6
|
+
require_relative "path"
|
7
|
+
|
8
|
+
module AssetPipelineRoutes
|
9
|
+
class Routes
|
10
|
+
def initialize routes
|
11
|
+
define_application_routes routes
|
12
|
+
end
|
13
|
+
|
14
|
+
def define_application_routes routes
|
15
|
+
routes.select{ |route| named_route?(route) }.each do |route|
|
16
|
+
define_route route
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def define_route route
|
21
|
+
self.class.instance_eval do
|
22
|
+
define_method :"#{route.name}_path", Path.proc_for_route(route)
|
23
|
+
|
24
|
+
define_method :"#{route.name}_path_method" do |style = :js|
|
25
|
+
AssetPipelineRoutes::JsFunctionHelper::route_to_anonymous_function Path.new(route.path.ast.to_s).build(':\1'), style
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def named_route? route
|
31
|
+
!route.name.nil?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -4,60 +4,78 @@ def build_route name, path
|
|
4
4
|
OpenStruct.new({:name => name, :path => OpenStruct.new(:ast => path)})
|
5
5
|
end
|
6
6
|
|
7
|
-
describe AssetPipelineRoutes do
|
7
|
+
describe AssetPipelineRoutes::Routes do
|
8
8
|
# the @route property basically describes a RouteSet#routes object
|
9
9
|
# as Rails.application.routes.routes[:index] returns it
|
10
10
|
describe 'resources#index' do
|
11
11
|
before { @route = build_route 'users', '/users(.:format)' }
|
12
|
-
subject { AssetPipelineRoutes::
|
12
|
+
subject { AssetPipelineRoutes::Routes.new [@route] }
|
13
13
|
|
14
14
|
it { should respond_to(:users_path) }
|
15
15
|
its(:users_path) { should eql '/users'}
|
16
16
|
it { subject.users_path('\d+').should eql('/users') }
|
17
|
+
|
18
|
+
describe "with format" do
|
19
|
+
it { subject.users_path(format: 'json').should eql('/users.json') }
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
describe 'resources#show' do
|
20
24
|
before { @route = build_route 'user', '/users/:id(.:format)' }
|
21
|
-
subject { AssetPipelineRoutes::
|
25
|
+
subject { AssetPipelineRoutes::Routes.new [@route] }
|
22
26
|
|
23
27
|
it { should respond_to(:user_path) }
|
24
28
|
its(:user_path) { should eql('/users/{{id}}') }
|
25
29
|
it { subject.user_path('\d+').should eql('/users/\d+') }
|
30
|
+
|
31
|
+
describe "with format" do
|
32
|
+
it { subject.user_path('\d+', format: 'json').should eql('/users/\d+.json') }
|
33
|
+
it { subject.user_path(42, format: 'xml').should eql('/users/42.xml') }
|
34
|
+
end
|
26
35
|
end
|
27
36
|
|
28
37
|
describe 'resources#edit' do
|
29
38
|
before { @route = build_route 'edit_user', '/users/:id/edit(.:format)' }
|
30
|
-
subject { AssetPipelineRoutes::
|
39
|
+
subject { AssetPipelineRoutes::Routes.new [@route] }
|
31
40
|
|
32
41
|
it { should respond_to(:edit_user_path) }
|
33
42
|
its(:edit_user_path) { should eql('/users/{{id}}/edit') }
|
34
43
|
it { subject.edit_user_path('\d+').should eql('/users/\d+/edit') }
|
35
|
-
end
|
36
|
-
|
37
|
-
describe 'resources without name' do
|
38
|
-
before { @route = build_route nil, '/foo' }
|
39
|
-
subject { AssetPipelineRoutes::RoutesHelper.new [@route] }
|
40
44
|
|
41
|
-
|
45
|
+
describe "with format" do
|
46
|
+
it { subject.edit_user_path('\d+', format: 'json').should eql('/users/\d+/edit.json') }
|
47
|
+
it { subject.edit_user_path(42, format: 'xml').should eql('/users/42/edit.xml') }
|
48
|
+
end
|
42
49
|
end
|
43
50
|
|
44
51
|
describe 'nested routes' do
|
45
52
|
before { @route = build_route 'project_ticket', '/projects/:project_id/tickets/:id(.:format)' }
|
46
|
-
subject { AssetPipelineRoutes::
|
53
|
+
subject { AssetPipelineRoutes::Routes.new [@route] }
|
47
54
|
|
48
55
|
it { should respond_to(:project_ticket_path) }
|
49
|
-
its(:project_ticket_path) {
|
56
|
+
its(:project_ticket_path) {should eql('/projects/{{project_id}}/tickets/{{id}}') }
|
57
|
+
it { subject.project_ticket_path(1,'\d+').should eql('/projects/1/tickets/\d+') }
|
58
|
+
it { subject.project_ticket_path('\d+',2).should eql('/projects/\d+/tickets/2') }
|
59
|
+
it { subject.project_ticket_path(1,2).should eql('/projects/1/tickets/2') }
|
60
|
+
it { subject.project_ticket_path(1,2,3).should eql('/projects/1/tickets/2') }
|
61
|
+
|
62
|
+
describe "with format" do
|
63
|
+
it { subject.project_ticket_path("a","b",format: 'json').should eql('/projects/a/tickets/b.json') }
|
64
|
+
it { subject.project_ticket_path("a", format: 'json').should eql('/projects/a/tickets/{{id}}.json') }
|
65
|
+
end
|
50
66
|
end
|
51
67
|
|
52
68
|
describe 'javascript method generation' do
|
53
69
|
before { @route = build_route 'user', '/users/:id/edit(.:format)' }
|
54
|
-
subject { AssetPipelineRoutes::
|
70
|
+
subject { AssetPipelineRoutes::Routes.new [@route] }
|
55
71
|
|
56
72
|
it { should respond_to(:user_path_method) }
|
73
|
+
|
57
74
|
it "should generate JavaScript mapping method" do
|
58
75
|
js_method = "(function() { return function (id) { return '/users/' + id + '/edit' }; }).call(this);"
|
59
76
|
subject.edit_user_path_method.should eql(js_method)
|
60
77
|
end
|
78
|
+
|
61
79
|
it "should generate CoffeScript mapping method" do
|
62
80
|
coffee_method = "(-> (id) -> '/users/' + id + '/edit')(this)"
|
63
81
|
subject.edit_user_path_method(:coffee).should eql(coffee_method)
|
data/spec/path_spec.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AssetPipelineRoutes::Path do
|
4
|
+
subject { AssetPipelineRoutes::Path.new '/users/:id/edit(.:format)' }
|
5
|
+
|
6
|
+
describe 'apply_format' do
|
7
|
+
it { subject.apply_format({ format: 'json' }).should eql '/users/:id/edit.json' }
|
8
|
+
it { subject.apply_format({}).should eql '/users/:id/edit' }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'format' do
|
12
|
+
it { subject.format({ format: 'json' }).should == '.json' }
|
13
|
+
it { subject.format({}).should == '' }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'after applying formats' do
|
17
|
+
before { subject.apply_format }
|
18
|
+
|
19
|
+
describe 'number_of_replacements' do
|
20
|
+
it { subject.number_of_replacements.should == 1 }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'default_replacements' do
|
24
|
+
it { subject.default_replacements.should eql [AssetPipelineRoutes::Path::DEFAULT_REPLACEMENT]}
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'replacements' do
|
28
|
+
it { subject.replacements().should eql subject.default_replacements }
|
29
|
+
it { subject.replacements(1).should eql [1] }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asset_pipeline_routes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-03-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &70101206508480 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.2.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70101206508480
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
27
|
-
requirement: &
|
27
|
+
requirement: &70101206507700 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70101206507700
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70101206506900 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70101206506900
|
47
47
|
description: Add a routes helper for all asset pipeline needs
|
48
48
|
email:
|
49
49
|
- nicolai86@me.com
|
@@ -52,11 +52,13 @@ extensions: []
|
|
52
52
|
extra_rdoc_files: []
|
53
53
|
files:
|
54
54
|
- lib/asset_pipeline_routes/js_function_helper.rb
|
55
|
+
- lib/asset_pipeline_routes/path.rb
|
56
|
+
- lib/asset_pipeline_routes/routes.rb
|
55
57
|
- lib/asset_pipeline_routes/routes_context.rb
|
56
|
-
- lib/asset_pipeline_routes/routes_helper.rb
|
57
58
|
- lib/asset_pipeline_routes/version.rb
|
58
59
|
- lib/asset_pipeline_routes.rb
|
59
60
|
- spec/asset_pipeline_routes_spec.rb
|
61
|
+
- spec/path_spec.rb
|
60
62
|
- spec/spec_helper.rb
|
61
63
|
- README.md
|
62
64
|
- Rakefile
|
@@ -80,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
82
|
version: '0'
|
81
83
|
requirements: []
|
82
84
|
rubyforge_project: asset_pipeline_routes
|
83
|
-
rubygems_version: 1.8.
|
85
|
+
rubygems_version: 1.8.17
|
84
86
|
signing_key:
|
85
87
|
specification_version: 3
|
86
88
|
summary: Add a routes helper for all asset pipeline needs
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require_relative "routes_context"
|
2
|
-
require_relative "js_function_helper"
|
3
|
-
|
4
|
-
module AssetPipelineRoutes
|
5
|
-
class RoutesHelper
|
6
|
-
def initialize(routes, default_block = '{{\1}}')
|
7
|
-
routes.each do |route|
|
8
|
-
next if route.name.nil? # only handle named_routes
|
9
|
-
|
10
|
-
self.class.instance_eval do
|
11
|
-
define_method :"#{route.name}_path" do |id_replacement = default_block|
|
12
|
-
proc { |route, mapping| build_url route, mapping }.curry[route].call id_replacement
|
13
|
-
end
|
14
|
-
|
15
|
-
define_method :"#{route.name}_path_method" do |style = :js|
|
16
|
-
AssetPipelineRoutes::JsFunctionHelper::route_to_anonymous_function build_url(route, ':\1'), style
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def build_url route, mapping
|
23
|
-
route.path.ast.to_s.gsub(/\(\.:\w+\)/,'').gsub(/:(\w+)/, mapping).to_s
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|