astaire 0.0.1 → 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/README.md +72 -0
- data/lib/astaire/railtie.rb +27 -0
- data/lib/astaire.rb +67 -12
- metadata +5 -4
- data/README +0 -3
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
## Astaire: The basic Sinatra DSL for your Rails 3 apps
|
2
|
+
|
3
|
+
Astaire allows the use of the basic Sinatra get / post / put / delete
|
4
|
+
DSL inside of Rails controllers. This allows defining quick actions without
|
5
|
+
having to update config/routes.rb. For example:
|
6
|
+
|
7
|
+
class ContactController < ActionController::Base
|
8
|
+
|
9
|
+
get "/contact" do
|
10
|
+
render :contact_form
|
11
|
+
end
|
12
|
+
|
13
|
+
post "/contact" do
|
14
|
+
# handle form input
|
15
|
+
redirect_to homepage_path
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
### Installation
|
21
|
+
|
22
|
+
Add the following to your application's Gemfile
|
23
|
+
|
24
|
+
gem "astaire"
|
25
|
+
|
26
|
+
Then, run `bundle install` and you are good to go.
|
27
|
+
|
28
|
+
### Usage
|
29
|
+
|
30
|
+
Currently, Astaire provides 4 class level methods available in the
|
31
|
+
controller: `#get`, `#post`, `#put`, and `#delete`. With these methods
|
32
|
+
you can define actions and routes all at once.
|
33
|
+
|
34
|
+
class MyController < ActionController::Base
|
35
|
+
|
36
|
+
# Get the contact form
|
37
|
+
get "/contact" do
|
38
|
+
render :contact_form
|
39
|
+
end
|
40
|
+
|
41
|
+
# The paths can also have named parameters and
|
42
|
+
# optional segments
|
43
|
+
#
|
44
|
+
# /say/hello => "I say: hello"
|
45
|
+
# /say/hello/world => "I say: hello world"
|
46
|
+
#
|
47
|
+
get "/say/:one(/:two)" do
|
48
|
+
words = [params[:one], params[:two]].compact.join(' ')
|
49
|
+
render :text => "I say: #{words}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
It is possible to name actions such that regular URL helpers can generate them.
|
54
|
+
|
55
|
+
class MyController < ActionController::Base
|
56
|
+
|
57
|
+
# Will output /hello
|
58
|
+
def index
|
59
|
+
render :text => hello_path
|
60
|
+
end
|
61
|
+
|
62
|
+
get "/hello", :as => :hello do
|
63
|
+
render :text => "hello"
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
### TODO
|
69
|
+
|
70
|
+
I guess, at this point I'm just putting what I have into the wild. Next
|
71
|
+
steps will be determined by feedback that I get. One thing that I would
|
72
|
+
like to add is Sinatra's inline template feature.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Astaire
|
2
|
+
class Rails < Rails::Railtie
|
3
|
+
config.to_prepare do
|
4
|
+
ApplicationController.class_eval { include Astaire::DSL }
|
5
|
+
end
|
6
|
+
|
7
|
+
initializer "astaire.cascade_routing" do |app|
|
8
|
+
# A lambda is needed here to ensure that the constant is reloaded
|
9
|
+
# after each request (in development mode)
|
10
|
+
astaire_app = proc { |env| ApplicationController.call(env) }
|
11
|
+
app.middleware.use ActionDispatch::Cascade, lambda { astaire_app }
|
12
|
+
end
|
13
|
+
|
14
|
+
# Controllers must be preloaded in order for Astaire's routing
|
15
|
+
# to be hooked up
|
16
|
+
initializer "astaire.preload_controllers" do |app|
|
17
|
+
config.to_prepare do
|
18
|
+
app.config.paths.app.controllers.each do |load_path|
|
19
|
+
matcher = /\A#{Regexp.escape(load_path)}\/(.*)\.rb\Z/
|
20
|
+
Dir["#{load_path}/**/*_controller.rb"].each do |file|
|
21
|
+
require_dependency file.sub(matcher, '\1')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/astaire.rb
CHANGED
@@ -1,38 +1,93 @@
|
|
1
1
|
require 'active_support/concern'
|
2
2
|
require 'action_controller'
|
3
|
+
require 'astaire/railtie' if defined?(Rails)
|
3
4
|
|
4
5
|
module Astaire
|
5
6
|
module DSL
|
6
7
|
extend ActiveSupport::Concern
|
7
8
|
|
9
|
+
include AbstractController::Helpers
|
10
|
+
|
8
11
|
included do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
class_attribute :_astaire_router
|
13
|
+
self._astaire_router = ActionDispatch::Routing::RouteSet.new
|
14
|
+
|
15
|
+
class_attribute :_astaire_helpers
|
16
|
+
self._astaire_helpers = url_helper_module
|
17
|
+
|
18
|
+
include _astaire_helpers
|
19
|
+
helper _astaire_helpers
|
14
20
|
end
|
15
21
|
|
16
22
|
module ClassMethods
|
17
23
|
def call(env)
|
18
|
-
|
19
|
-
rescue ActionController::RoutingError
|
20
|
-
[404, {'Content-Type' => 'text/html', 'X-Cascade' => 'pass'}, []]
|
24
|
+
_astaire_router.call(env)
|
21
25
|
end
|
22
26
|
|
23
27
|
def mapper
|
24
|
-
@mapper ||= ActionDispatch::Routing::Mapper.new(
|
28
|
+
@mapper ||= ActionDispatch::Routing::Mapper.new(_astaire_router)
|
25
29
|
end
|
26
30
|
|
27
31
|
%w(get post put delete).each do |method|
|
28
32
|
class_eval <<-R, __FILE__, __LINE__+1
|
29
33
|
def #{method}(path, opts = {}, &blk)
|
30
|
-
|
31
|
-
define_method action_name, &blk
|
32
|
-
mapper.match(path, :via => '#{method}', :to => action(action_name))
|
34
|
+
map_astaire_action "#{method}", path, opts, blk
|
33
35
|
end
|
34
36
|
R
|
35
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def map_astaire_action(method, path, opts, blk)
|
42
|
+
action_name = "[#{method}] #{path}"
|
43
|
+
define_method action_name, &blk
|
44
|
+
opts.merge! :via => method, :to => action(action_name)
|
45
|
+
|
46
|
+
mapper.match(path, opts)
|
47
|
+
make_url_helper(opts[:as]) if opts[:as]
|
48
|
+
end
|
49
|
+
|
50
|
+
def url_helper_module
|
51
|
+
Module.new do
|
52
|
+
def _astaire_url_opts_from_args(name, route, args, only_path)
|
53
|
+
opts = args.extract_options!
|
54
|
+
|
55
|
+
if args.any?
|
56
|
+
opts[:_positional_args] = args
|
57
|
+
opts[:_positional_keys] = route.segment_keys
|
58
|
+
end
|
59
|
+
|
60
|
+
opts = url_options.merge(opts)
|
61
|
+
opts.merge!(:use_route => name, :only_path => only_path)
|
62
|
+
|
63
|
+
if path_segments = opts[:_path_segments]
|
64
|
+
path_segments.delete(:controller)
|
65
|
+
path_segments.delete(:action)
|
66
|
+
end
|
67
|
+
|
68
|
+
opts
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def make_url_helper(name)
|
74
|
+
name = name.to_sym
|
75
|
+
router = _astaire_router
|
76
|
+
|
77
|
+
_astaire_helpers.module_eval do
|
78
|
+
define_method "#{name}_path" do |*args|
|
79
|
+
route = router.named_routes[name]
|
80
|
+
opts = _astaire_url_opts_from_args(name, route, args, true)
|
81
|
+
router.url_for(opts)
|
82
|
+
end
|
83
|
+
|
84
|
+
define_method "#{name}_url" do |*args|
|
85
|
+
route = router.named_routes[name]
|
86
|
+
opts = _astaire_url_opts_from_args(name, route, args, false)
|
87
|
+
router.url_for(opts)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
36
91
|
end
|
37
92
|
end
|
38
93
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 2
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.1
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Carl Lerche
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-05-03 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -41,8 +41,9 @@ extensions: []
|
|
41
41
|
extra_rdoc_files: []
|
42
42
|
|
43
43
|
files:
|
44
|
-
- README
|
44
|
+
- README.md
|
45
45
|
- LICENSE
|
46
|
+
- lib/astaire/railtie.rb
|
46
47
|
- lib/astaire.rb
|
47
48
|
has_rdoc: true
|
48
49
|
homepage: http://github.com/carllerche/astaire
|
data/README
DELETED