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 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 all resource links dynamic params at compile-time to work, like `{:id => 42}`. Without supplying them you won't get anywhere.
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
- editUserRoute = `<%= r.edit_user_method %>` # => yields anonymous function
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/routes_helper"
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
- ActiveSupport.on_load(:action_view) do
8
- include ::AssetPipelineRoutes::RoutesContext
9
-
10
- app.assets.context_class.instance_eval do
11
- include ::AssetPipelineRoutes::RoutesContext
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
- end
14
+ end
14
15
  end
15
16
  end
16
17
  end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  require 'active_support/core_ext/string/inflections'
2
3
 
3
4
  module AssetPipelineRoutes
@@ -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
@@ -1,9 +1,8 @@
1
+ # encoding: UTF-8
1
2
  module AssetPipelineRoutes
2
3
  module RoutesContext
3
-
4
4
  def r
5
- @r ||= ::AssetPipelineRoutes::RoutesHelper.new(Rails.application.routes.routes)
5
+ @r ||= ::AssetPipelineRoutes::Routes.new(Rails.application.routes.routes)
6
6
  end
7
-
8
7
  end
9
8
  end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module AssetPipelineRoutes
2
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
3
4
  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::RoutesHelper.new [@route] }
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::RoutesHelper.new [@route] }
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::RoutesHelper.new [@route] }
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
- it { subject.should_not_receive(:build_url) }
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::RoutesHelper.new [@route] }
53
+ subject { AssetPipelineRoutes::Routes.new [@route] }
47
54
 
48
55
  it { should respond_to(:project_ticket_path) }
49
- its(:project_ticket_path) { should eql('/projects/{{project_id}}/tickets/{{id}}') }
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::RoutesHelper.new [@route] }
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
@@ -2,6 +2,7 @@ ENV["RAILS_ENV"] = "test"
2
2
 
3
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
4
 
5
- require 'asset_pipeline_routes/routes_helper'
5
+ require 'asset_pipeline_routes/routes'
6
+ require 'asset_pipeline_routes/path'
6
7
  require 'rspec'
7
8
  require 'ostruct'
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.3
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-02-04 00:00:00.000000000 Z
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: &70170979291500 !ruby/object:Gem::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: *70170979291500
24
+ version_requirements: *70101206508480
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &70170979291080 !ruby/object:Gem::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: *70170979291080
35
+ version_requirements: *70101206507700
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70170979290620 !ruby/object:Gem::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: *70170979290620
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.15
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