flipper-ui 0.2.0.beta1
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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/Gemfile +17 -0
- data/Guardfile +26 -0
- data/LICENSE +22 -0
- data/README.md +101 -0
- data/Rakefile +7 -0
- data/examples/basic.ru +44 -0
- data/examples/flipper.html +14 -0
- data/examples/flipper.png +0 -0
- data/flipper-ui.gemspec +21 -0
- data/lib/flipper-ui.rb +1 -0
- data/lib/flipper/ui.rb +23 -0
- data/lib/flipper/ui/action.rb +172 -0
- data/lib/flipper/ui/action_collection.rb +20 -0
- data/lib/flipper/ui/actions/features.rb +21 -0
- data/lib/flipper/ui/actions/file.rb +17 -0
- data/lib/flipper/ui/actions/gate.rb +143 -0
- data/lib/flipper/ui/actions/index.rb +17 -0
- data/lib/flipper/ui/assets/javascripts/application.coffee +305 -0
- data/lib/flipper/ui/assets/javascripts/spine/ajax.coffee +223 -0
- data/lib/flipper/ui/assets/javascripts/spine/list.coffee +43 -0
- data/lib/flipper/ui/assets/javascripts/spine/local.coffee +16 -0
- data/lib/flipper/ui/assets/javascripts/spine/manager.coffee +83 -0
- data/lib/flipper/ui/assets/javascripts/spine/relation.coffee +148 -0
- data/lib/flipper/ui/assets/javascripts/spine/route.coffee +146 -0
- data/lib/flipper/ui/assets/javascripts/spine/spine.coffee +542 -0
- data/lib/flipper/ui/assets/javascripts/spine/version +1 -0
- data/lib/flipper/ui/assets/stylesheets/application.scss +237 -0
- data/lib/flipper/ui/decorators/feature.rb +37 -0
- data/lib/flipper/ui/decorators/gate.rb +36 -0
- data/lib/flipper/ui/error.rb +10 -0
- data/lib/flipper/ui/eruby.rb +11 -0
- data/lib/flipper/ui/middleware.rb +66 -0
- data/lib/flipper/ui/public/css/application.css +183 -0
- data/lib/flipper/ui/public/css/images/animated-overlay.gif +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-icons_222222_256x240.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-icons_228ef1_256x240.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-icons_ef8c08_256x240.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-icons_ffd27a_256x240.png +0 -0
- data/lib/flipper/ui/public/css/images/ui-icons_ffffff_256x240.png +0 -0
- data/lib/flipper/ui/public/css/jquery-ui-1.10.3.slider.min.css +5 -0
- data/lib/flipper/ui/public/images/logo.png +0 -0
- data/lib/flipper/ui/public/images/remove.png +0 -0
- data/lib/flipper/ui/public/js/application.js +544 -0
- data/lib/flipper/ui/public/js/handlebars.js +1992 -0
- data/lib/flipper/ui/public/js/jquery-ui-1.10.3.slider.min.js +6 -0
- data/lib/flipper/ui/public/js/jquery.js +9555 -0
- data/lib/flipper/ui/public/js/jquery.min.js +4 -0
- data/lib/flipper/ui/public/js/jquery.min.map +1 -0
- data/lib/flipper/ui/public/js/spine/ajax.js +320 -0
- data/lib/flipper/ui/public/js/spine/list.js +72 -0
- data/lib/flipper/ui/public/js/spine/local.js +29 -0
- data/lib/flipper/ui/public/js/spine/manager.js +157 -0
- data/lib/flipper/ui/public/js/spine/relation.js +260 -0
- data/lib/flipper/ui/public/js/spine/route.js +223 -0
- data/lib/flipper/ui/public/js/spine/spine.js +927 -0
- data/lib/flipper/ui/util.rb +12 -0
- data/lib/flipper/ui/version.rb +5 -0
- data/lib/flipper/ui/views/index.erb +9 -0
- data/lib/flipper/ui/views/layout.erb +161 -0
- data/script/bootstrap +21 -0
- data/script/server +19 -0
- data/script/test +30 -0
- data/spec/flipper/ui/decorators/feature_spec.rb +59 -0
- data/spec/flipper/ui/decorators/gate_spec.rb +47 -0
- data/spec/flipper/ui/util_spec.rb +18 -0
- data/spec/flipper/ui_spec.rb +470 -0
- data/spec/helper.rb +35 -0
- metadata +168 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 8e9d451a699e2b1acd1697ffea82cace549570b2
|
|
4
|
+
data.tar.gz: 012aa58d86f51d10b433a48ad0a7503d601b948d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a2911695881ddf0c229fbf06bd1249e0f6439d0703c8783c702bbf7bf4715070ed48b61b902ef9fc4c6d97f0d17ebea4ec7172048f1ca586c0a7ddeb89623d47
|
|
7
|
+
data.tar.gz: 5d110e6a66dac9408c36ae2a3222598893a57254e88e11cddce3977dadb70f10f74139464ef76340623973354ccc0172ba9e9a4a3003abbe9ed69ffe0b27ca01
|
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/Gemfile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
gemspec
|
|
3
|
+
|
|
4
|
+
gem 'rake'
|
|
5
|
+
gem 'shotgun'
|
|
6
|
+
gem 'rspec'
|
|
7
|
+
gem 'rack-test'
|
|
8
|
+
gem 'activesupport'
|
|
9
|
+
|
|
10
|
+
group(:guard) do
|
|
11
|
+
gem 'guard'
|
|
12
|
+
gem 'guard-rspec'
|
|
13
|
+
gem 'guard-bundler'
|
|
14
|
+
gem 'guard-coffeescript'
|
|
15
|
+
gem 'guard-sass'
|
|
16
|
+
gem 'rb-fsevent'
|
|
17
|
+
end
|
data/Guardfile
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# A sample Guardfile
|
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
|
3
|
+
|
|
4
|
+
guard 'bundler' do
|
|
5
|
+
watch('Gemfile')
|
|
6
|
+
watch(/^.+\.gemspec/)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
guard 'rspec' do
|
|
10
|
+
watch(%r{^spec/.+_spec\.rb$}) { "spec" }
|
|
11
|
+
watch(%r{^lib/(.+)\.rb$}) { "spec" }
|
|
12
|
+
watch('spec/helper.rb') { "spec" }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
coffee_options = {
|
|
16
|
+
:input => 'lib/flipper/ui/assets/javascripts',
|
|
17
|
+
:output => 'lib/flipper/ui/public/js',
|
|
18
|
+
:all_on_start => false,
|
|
19
|
+
}
|
|
20
|
+
guard 'coffeescript', coffee_options
|
|
21
|
+
|
|
22
|
+
sass_options = {
|
|
23
|
+
:input => 'lib/flipper/ui/assets/stylesheets',
|
|
24
|
+
:output => 'lib/flipper/ui/public/css',
|
|
25
|
+
}
|
|
26
|
+
guard 'sass', sass_options
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2012 John Nunemaker
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Flipper::UI
|
|
2
|
+
|
|
3
|
+
UI for the [Flipper](https://github.com/jnunemaker/flipper) gem. __Note__: This is not fully functional yet. The end product will look like this:
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add this line to your application's Gemfile:
|
|
10
|
+
|
|
11
|
+
gem 'flipper-ui'
|
|
12
|
+
|
|
13
|
+
And then execute:
|
|
14
|
+
|
|
15
|
+
$ bundle
|
|
16
|
+
|
|
17
|
+
Or install it yourself as:
|
|
18
|
+
|
|
19
|
+
$ gem install flipper-ui
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Rails
|
|
24
|
+
|
|
25
|
+
Given that you've already initialized `Flipper` as per the [flipper](https://github.com/jnunemaker/flipper) readme:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
# config/initializers/flipper.rb
|
|
29
|
+
$flipper = Flipper.new(...)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
you can mount `Flipper::UI` to a route of your choice:
|
|
33
|
+
```ruby
|
|
34
|
+
# config/routes.rb
|
|
35
|
+
|
|
36
|
+
YourRailsApp::Application.routes.draw do
|
|
37
|
+
mount Flipper::UI.app($flipper) => '/flipper'
|
|
38
|
+
end
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
#### Security
|
|
42
|
+
|
|
43
|
+
You almost certainly want to limit access when using Flipper::UI in production. Using [routes constraints](http://guides.rubyonrails.org/routing.html#request-based-constraints) is one way to achieve this:
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
# config/routes.rb
|
|
47
|
+
|
|
48
|
+
flipper_constraint = lambda { |request| request.remote_ip == '127.0.0.1' }
|
|
49
|
+
constraints flipper_constraint do
|
|
50
|
+
mount Flipper::UI.app($flipper) => '/flipper'
|
|
51
|
+
end
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Another example of a route constrain using the current_user when using Devise or another warden based authentication system:
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
# initializers/admin_access.rb
|
|
58
|
+
|
|
59
|
+
class CanAccessFlipperUI
|
|
60
|
+
def self.matches?(request)
|
|
61
|
+
current_user = request.env['warden'].user
|
|
62
|
+
|
|
63
|
+
return current_user.present? && current_user.respond_to?(:is_admin?) && current_user.is_admin?
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# config/routes.rb
|
|
68
|
+
|
|
69
|
+
constraints CanAccessFlipperUI do
|
|
70
|
+
mount Flipper::UI.app($flipper) => '/flipper'
|
|
71
|
+
end
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
### Standalone
|
|
76
|
+
|
|
77
|
+
Minimal example for Rack:
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
# config.ru
|
|
81
|
+
|
|
82
|
+
require 'flipper-ui'
|
|
83
|
+
require 'flipper/adapters/memory'
|
|
84
|
+
|
|
85
|
+
adapter = Flipper::Adapters::Memory.new
|
|
86
|
+
flipper = Flipper.new(adapter)
|
|
87
|
+
|
|
88
|
+
run Flipper::UI.app(flipper)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
See [examples/basic.ru](https://github.com/jnunemaker/flipper-ui/blob/master/examples/basic.ru) for a more full example
|
|
92
|
+
|
|
93
|
+
## Contributing
|
|
94
|
+
|
|
95
|
+
1. Fork it
|
|
96
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
97
|
+
3. **Fire up the app** (`script/server`)
|
|
98
|
+
4. **Start up guard** (`bundle exec guard` for automatic coffeescript/sass compilation and such).
|
|
99
|
+
5. Commit your changes (`git commit -am 'Added some feature'`)
|
|
100
|
+
6. Push to the branch (`git push origin my-new-feature`)
|
|
101
|
+
7. Create new Pull Request
|
data/Rakefile
ADDED
data/examples/basic.ru
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Usage:
|
|
3
|
+
# bundle exec rackup examples/basic.ru
|
|
4
|
+
# http://localhost:9292/
|
|
5
|
+
#
|
|
6
|
+
require 'pp'
|
|
7
|
+
require 'logger'
|
|
8
|
+
require 'pathname'
|
|
9
|
+
|
|
10
|
+
root_path = Pathname(__FILE__).dirname.join('..').expand_path
|
|
11
|
+
lib_path = root_path.join('lib')
|
|
12
|
+
$:.unshift(lib_path)
|
|
13
|
+
|
|
14
|
+
require 'flipper-ui'
|
|
15
|
+
require 'flipper/adapters/memory'
|
|
16
|
+
|
|
17
|
+
Flipper.register(:admins) { |actor|
|
|
18
|
+
actor.respond_to?(:admin?) && actor.admin?
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Flipper.register(:early_access) { |actor|
|
|
22
|
+
actor.respond_to?(:early?) && actor.early?
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# Setup logging of flipper calls.
|
|
26
|
+
require 'flipper/instrumentation/log_subscriber'
|
|
27
|
+
Flipper::Instrumentation::LogSubscriber.logger = Logger.new(STDOUT)
|
|
28
|
+
|
|
29
|
+
adapter = Flipper::Adapters::Memory.new({})
|
|
30
|
+
flipper = Flipper.new(adapter, :instrumenter => ActiveSupport::Notifications)
|
|
31
|
+
|
|
32
|
+
Actor = Struct.new(:flipper_id)
|
|
33
|
+
|
|
34
|
+
flipper[:search_performance_another_long_thing].enable
|
|
35
|
+
flipper[:gauges_tracking].enable
|
|
36
|
+
flipper[:unused].disable
|
|
37
|
+
flipper[:suits].enable Actor.new('1')
|
|
38
|
+
flipper[:suits].enable Actor.new('6')
|
|
39
|
+
flipper[:secrets].enable flipper.group(:admins)
|
|
40
|
+
flipper[:secrets].enable flipper.group(:early_access)
|
|
41
|
+
flipper[:logging].enable flipper.random(5)
|
|
42
|
+
flipper[:new_cache].enable flipper.actors(15)
|
|
43
|
+
|
|
44
|
+
run Flipper::UI.app(flipper)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<title>Flipper</title>
|
|
5
|
+
<link rel="stylesheet" type="text/css" href="/css/application.css">
|
|
6
|
+
<style type="text/css">
|
|
7
|
+
* { margin:0; padding:0; }
|
|
8
|
+
body {text-align:center;}
|
|
9
|
+
</style>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<img src="flipper.png" />
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
Binary file
|
data/flipper-ui.gemspec
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require File.expand_path('../lib/flipper/ui/version', __FILE__)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |gem|
|
|
5
|
+
gem.authors = ["John Nunemaker"]
|
|
6
|
+
gem.email = ["nunemaker@gmail.com"]
|
|
7
|
+
gem.description = %q{UI for the Flipper gem}
|
|
8
|
+
gem.summary = %q{UI for the Flipper gem}
|
|
9
|
+
gem.homepage = "https://github.com/jnunemaker/flipper-ui"
|
|
10
|
+
|
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
14
|
+
gem.name = "flipper-ui"
|
|
15
|
+
gem.require_paths = ["lib"]
|
|
16
|
+
gem.version = Flipper::UI::VERSION
|
|
17
|
+
|
|
18
|
+
gem.add_dependency 'rack'
|
|
19
|
+
gem.add_dependency 'flipper', '~> 0.7.0.beta1'
|
|
20
|
+
gem.add_dependency 'erubis'
|
|
21
|
+
end
|
data/lib/flipper-ui.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'flipper/ui'
|
data/lib/flipper/ui.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'rack'
|
|
3
|
+
require 'flipper'
|
|
4
|
+
require 'multi_json'
|
|
5
|
+
|
|
6
|
+
module Flipper
|
|
7
|
+
module UI
|
|
8
|
+
def self.root
|
|
9
|
+
@root ||= Pathname(__FILE__).dirname.expand_path.join('ui')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.app(flipper)
|
|
13
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/html'}, ['']] }
|
|
14
|
+
builder = Rack::Builder.new
|
|
15
|
+
yield builder if block_given?
|
|
16
|
+
builder.use Middleware, flipper
|
|
17
|
+
builder.run app
|
|
18
|
+
builder
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
require 'flipper/ui/middleware'
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
require 'forwardable'
|
|
2
|
+
require 'flipper/ui/error'
|
|
3
|
+
require 'flipper/ui/eruby'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module Flipper
|
|
7
|
+
module UI
|
|
8
|
+
class Action
|
|
9
|
+
extend Forwardable
|
|
10
|
+
|
|
11
|
+
# Public: Call this in subclasses so the action knows its route.
|
|
12
|
+
#
|
|
13
|
+
# regex - The Regexp that this action should run for.
|
|
14
|
+
#
|
|
15
|
+
# Returns nothing.
|
|
16
|
+
def self.route(regex)
|
|
17
|
+
@regex = regex
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Internal: Initializes and runs an action for a given request.
|
|
21
|
+
#
|
|
22
|
+
# flipper - The Flipper::DSL instance.
|
|
23
|
+
# request - The Rack::Request that was sent.
|
|
24
|
+
#
|
|
25
|
+
# Returns result of Action#run.
|
|
26
|
+
def self.run(flipper, request)
|
|
27
|
+
new(flipper, request).run
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Internal: The regex that matches which routes this action will work for.
|
|
31
|
+
def self.regex
|
|
32
|
+
@regex || raise("#{name}.route is not set")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Private: The path to the views folder.
|
|
36
|
+
def self.views_path
|
|
37
|
+
@views_path ||= Flipper::UI.root.join('views')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Private: The path to the public folder.
|
|
41
|
+
def self.public_path
|
|
42
|
+
@public_path ||= Flipper::UI.root.join('public')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Public: The instance of the Flipper::DSL the middleware was
|
|
46
|
+
# initialized with.
|
|
47
|
+
attr_reader :flipper
|
|
48
|
+
|
|
49
|
+
# Public: The Rack::Request to provide a response for.
|
|
50
|
+
attr_reader :request
|
|
51
|
+
|
|
52
|
+
# Public: The params for the request.
|
|
53
|
+
def_delegator :@request, :params
|
|
54
|
+
|
|
55
|
+
def initialize(flipper, request)
|
|
56
|
+
@flipper, @request = flipper, request
|
|
57
|
+
@code = 200
|
|
58
|
+
@headers = {}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Public: Runs the request method for the provided request.
|
|
62
|
+
#
|
|
63
|
+
# Returns whatever the request method returns in the action.
|
|
64
|
+
def run
|
|
65
|
+
if respond_to?(request_method_name)
|
|
66
|
+
catch(:halt) { send(request_method_name) }
|
|
67
|
+
else
|
|
68
|
+
raise UI::RequestMethodNotSupported, "#{self.class} does not support request method #{request_method_name.inspect}"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Public: Runs another action from within the request method of a
|
|
73
|
+
# different action.
|
|
74
|
+
#
|
|
75
|
+
# action_class - The class of the other action to run.
|
|
76
|
+
#
|
|
77
|
+
# Examples
|
|
78
|
+
#
|
|
79
|
+
# run_other_action Index
|
|
80
|
+
# # => result of running Index action
|
|
81
|
+
#
|
|
82
|
+
# Returns result of other action.
|
|
83
|
+
def run_other_action(action_class)
|
|
84
|
+
action_class.new(flipper, request).run
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Public: Call this with a response to immediately stop the current action
|
|
88
|
+
# and respond however you want.
|
|
89
|
+
#
|
|
90
|
+
# response - The response you would like to return.
|
|
91
|
+
def halt(response)
|
|
92
|
+
throw :halt, response
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Public: Compiles a view and returns rack response with that as the body.
|
|
96
|
+
#
|
|
97
|
+
# name - The Symbol name of the view.
|
|
98
|
+
#
|
|
99
|
+
# Returns a response.
|
|
100
|
+
def view_response(name)
|
|
101
|
+
header 'Content-Type', 'text/html'
|
|
102
|
+
body = view_with_layout { view_without_layout name }
|
|
103
|
+
[@code, @headers, [body]]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Public: Dumps an object as json and returns rack response with that as
|
|
107
|
+
# the body. Automatically sets Content-Type to "application/json".
|
|
108
|
+
#
|
|
109
|
+
# object - The Object that should be dumped as json.
|
|
110
|
+
#
|
|
111
|
+
# Returns a response.
|
|
112
|
+
def json_response(object)
|
|
113
|
+
header 'Content-Type', 'application/json'
|
|
114
|
+
body = JSON.dump(object)
|
|
115
|
+
[@code, @headers, [body]]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Public: Set the status code for the response.
|
|
119
|
+
#
|
|
120
|
+
# code - The Integer code you would like the response to return.
|
|
121
|
+
def status(code)
|
|
122
|
+
@code = code.to_i
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Public: Set a header.
|
|
126
|
+
#
|
|
127
|
+
# name - The String name of the header.
|
|
128
|
+
# value - The value of the header.
|
|
129
|
+
def header(name, value)
|
|
130
|
+
@headers[name] = value
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Private
|
|
134
|
+
def view_with_layout(&block)
|
|
135
|
+
view :layout, &block
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Private
|
|
139
|
+
def view_without_layout(name)
|
|
140
|
+
view name
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Private
|
|
144
|
+
def view(name)
|
|
145
|
+
path = views_path.join("#{name}.erb")
|
|
146
|
+
contents = path.read
|
|
147
|
+
compiled = Eruby.new(contents)
|
|
148
|
+
compiled.result Proc.new {}.binding
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Internal: The path the app is mounted at.
|
|
152
|
+
def script_name
|
|
153
|
+
request.env['SCRIPT_NAME']
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Private
|
|
157
|
+
def views_path
|
|
158
|
+
self.class.views_path
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Private
|
|
162
|
+
def public_path
|
|
163
|
+
self.class.public_path
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Private: Returns the request method converted to an action method.
|
|
167
|
+
def request_method_name
|
|
168
|
+
@request_method_name ||= @request.request_method.downcase
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|