flame 5.0.0.rc5 → 5.0.0.rc6

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.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +921 -0
  3. data/LICENSE.txt +19 -0
  4. data/README.md +135 -0
  5. data/lib/flame.rb +12 -5
  6. data/lib/flame/application.rb +47 -46
  7. data/lib/flame/config.rb +73 -0
  8. data/lib/flame/controller.rb +45 -78
  9. data/lib/flame/controller/actions.rb +122 -0
  10. data/lib/flame/{dispatcher → controller}/cookies.rb +8 -3
  11. data/lib/flame/controller/path_to.rb +34 -10
  12. data/lib/flame/dispatcher.rb +14 -17
  13. data/lib/flame/dispatcher/request.rb +25 -6
  14. data/lib/flame/dispatcher/routes.rb +22 -14
  15. data/lib/flame/dispatcher/static.rb +13 -9
  16. data/lib/flame/errors/argument_not_assigned_error.rb +3 -8
  17. data/lib/flame/errors/config_file_not_found_error.rb +17 -0
  18. data/lib/flame/errors/controller_not_found_error.rb +19 -0
  19. data/lib/flame/errors/route_arguments_order_error.rb +5 -10
  20. data/lib/flame/errors/route_extra_arguments_error.rb +10 -20
  21. data/lib/flame/errors/route_not_found_error.rb +3 -8
  22. data/lib/flame/errors/template_not_found_error.rb +2 -8
  23. data/lib/flame/path.rb +36 -18
  24. data/lib/flame/render.rb +13 -5
  25. data/lib/flame/router.rb +7 -157
  26. data/lib/flame/router/controller_finder.rb +56 -0
  27. data/lib/flame/router/route.rb +9 -0
  28. data/lib/flame/router/routes.rb +58 -8
  29. data/lib/flame/router/routes_refine.rb +144 -0
  30. data/lib/flame/router/routes_refine/mounting.rb +57 -0
  31. data/lib/flame/validators.rb +14 -10
  32. data/lib/flame/version.rb +1 -1
  33. metadata +91 -99
  34. data/bin/flame +0 -16
  35. data/lib/flame/application/config.rb +0 -49
  36. data/template/.editorconfig +0 -15
  37. data/template/.gitignore +0 -28
  38. data/template/.rubocop.yml +0 -14
  39. data/template/Gemfile +0 -55
  40. data/template/Rakefile +0 -824
  41. data/template/application.rb.erb +0 -10
  42. data/template/config.ru.erb +0 -72
  43. data/template/config/config.rb.erb +0 -56
  44. data/template/config/database.example.yml +0 -5
  45. data/template/config/deploy.example.yml +0 -2
  46. data/template/config/puma.rb +0 -56
  47. data/template/config/sequel.rb.erb +0 -22
  48. data/template/config/server.example.yml +0 -32
  49. data/template/config/session.example.yml +0 -7
  50. data/template/controllers/_controller.rb.erb +0 -14
  51. data/template/controllers/site/_controller.rb.erb +0 -18
  52. data/template/controllers/site/index_controller.rb.erb +0 -12
  53. data/template/db/.keep +0 -0
  54. data/template/filewatchers.yml +0 -12
  55. data/template/helpers/.keep +0 -0
  56. data/template/lib/.keep +0 -0
  57. data/template/locales/en.yml +0 -0
  58. data/template/models/.keep +0 -0
  59. data/template/public/.keep +0 -0
  60. data/template/server +0 -200
  61. data/template/services/.keep +0 -0
  62. data/template/views/.keep +0 -0
  63. data/template/views/site/index.html.erb.erb +0 -1
  64. data/template/views/site/layout.html.erb.erb +0 -10
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2015-2017 Alexander Popov (AlexWayfer)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"),
5
+ to deal in the Software without restriction, including without limitation
6
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
+ and/or sell copies of the Software, and to permit persons to whom
8
+ the Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included
11
+ in all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
+ DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,135 @@
1
+ <p align="center">
2
+ <img
3
+ src="https://raw.githubusercontent.com/AlexWayfer/flame/master/public/favicon.ico"
4
+ height="150"
5
+ alt="Flame Logo"
6
+ title="Logo from open-source Elusive-Iconfont (https://github.com/reduxframework/elusive-iconfont)"
7
+ />
8
+ </p>
9
+
10
+ <h1 align="center">Flame</h1>
11
+
12
+ <p align="center">
13
+ <a href="https://cirrus-ci.com/github/AlexWayfer/flame/master"><img
14
+ src="https://api.cirrus-ci.com/github/AlexWayfer/flame.svg?branch=master"
15
+ alt="Cirrus CI"
16
+ /></a>
17
+ <a href="https://codecov.io/gh/AlexWayfer/flame"><img
18
+ src="https://img.shields.io/codecov/c/github/AlexWayfer/flame.svg?style=flat-square"
19
+ alt="Codecov"
20
+ /></a>
21
+ <a href="https://codeclimate.com/github/AlexWayfer/flame"><img
22
+ src="https://img.shields.io/codeclimate/maintainability/AlexWayfer/flame.svg?style=flat-square"
23
+ alt="Code Climate"
24
+ /></a>
25
+ <a href="https://depfu.com/repos/AlexWayfer/flame"><img
26
+ src="https://img.shields.io/depfu/AlexWayfer/flame.svg?style=flat-square"
27
+ alt="Depfu"
28
+ /></a>
29
+ <a href="http://inch-ci.org/github/AlexWayfer/flame"><img
30
+ src="http://inch-ci.org/github/AlexWayfer/flame.svg?branch=master&style=flat-square"
31
+ alt="Docs"
32
+ /></a>
33
+ <a href="https://rubygems.org/gems/flame"><img
34
+ src="https://img.shields.io/gem/v/flame.svg?style=flat-square"
35
+ alt="Gem"
36
+ /></a>
37
+ <a href="https://github.com/AlexWayfer/flame/blob/master/LICENSE.txt"><img
38
+ src="https://img.shields.io/github/license/AlexWayfer/flame.svg?style=flat-square"
39
+ alt="MIT license"
40
+ /></a>
41
+ </p>
42
+
43
+ Flame is a small Ruby web framework, built on [Rack](https://github.com/rack/rack),
44
+ inspired by [Gin](https://github.com/0jcasts/gin) (which follows class-controllers style),
45
+ designed as a replacement [Sinatra](https://github.com/sinatra/sinatra)
46
+ or maybe even [Rails](https://github.com/rails/rails).
47
+
48
+ ## Why?
49
+
50
+ I didn't like class methods, especially for controller's hooks — OOP is prettier without it.
51
+ And I found a way to implement controller's hooks without using class methods,
52
+ but with the inheritance (including the including of modules).
53
+ Moreover, with class methods an insufficiently obvious order of hooks (especially with inheritance)
54
+ and complicated implementation of conditions are obtained.
55
+ In this framework everything is Ruby-native as it can be.
56
+
57
+ ## Installation
58
+
59
+ Using the built-in `gem`:
60
+
61
+ ```bash
62
+ $ gem install flame
63
+ ```
64
+
65
+ or with [Bundler](http://bundler.io/):
66
+
67
+ ```ruby
68
+ # Gemfile
69
+ gem 'flame'
70
+ ```
71
+
72
+ ## Usage
73
+
74
+ The simplest example:
75
+
76
+ ```ruby
77
+ # index_controller.rb
78
+
79
+ class IndexController < Flame::Controller
80
+ def index
81
+ view :index # or just `view`, Symbol as method-name by default
82
+ end
83
+
84
+ def hello_world
85
+ "Hello World!"
86
+ end
87
+
88
+ def goodbye
89
+ "Goodbye World!"
90
+ end
91
+ end
92
+
93
+ # app.rb
94
+
95
+ class App < Flame::Application
96
+ mount IndexController do
97
+ # all methods will be mounted automatically, it's just an example of refinement
98
+ get '/hello', :hello_world
99
+ end
100
+ end
101
+
102
+ # config.ru
103
+
104
+ require_relative './index_controller'
105
+
106
+ require_relative './app'
107
+
108
+ run App.new # or `run App`
109
+ ```
110
+
111
+ More at [Wiki](https://github.com/AlexWayfer/flame/wiki).
112
+
113
+ ## Benchmark
114
+
115
+ The last benchmark can be viewed [here](https://github.com/luislavena/bench-micro).
116
+
117
+ ## Development
118
+
119
+ After checking out the repo, run `bundle install` to install dependencies.
120
+
121
+ Then, run `toys rspec` to run the tests.
122
+
123
+ To install this gem onto your local machine, run `toys gem install`.
124
+
125
+ To release a new version, run `toys gem release %version%`.
126
+ See how it works [here](https://github.com/AlexWayfer/gem_toys#release).
127
+
128
+ ## Contributing
129
+
130
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/AlexWayfer/flame).
131
+
132
+ ## License
133
+
134
+ The gem is available as open source under the terms of the
135
+ [MIT License](https://opensource.org/licenses/MIT).
data/lib/flame.rb CHANGED
@@ -1,8 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'addressable'
4
- require 'rack'
3
+ require 'gorilla_patch/inflections'
5
4
 
6
- require_relative 'flame/application'
7
- require_relative 'flame/controller'
8
- require_relative 'flame/version'
5
+ ## Base module
6
+ module Flame
7
+ using GorillaPatch::Inflections
8
+
9
+ %i[Config Application Controller VERSION]
10
+ .each do |constant_name|
11
+ autoload(
12
+ constant_name, "#{__dir__}/flame/#{constant_name.to_s.underscore}"
13
+ )
14
+ end
15
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'application/config'
3
+ require 'addressable'
4
+
4
5
  require_relative 'router'
5
6
  require_relative 'dispatcher'
6
7
 
@@ -8,15 +9,25 @@ module Flame
8
9
  ## Core class, like Framework::Application
9
10
  class Application
10
11
  class << self
11
- attr_accessor :config
12
+ include Memery
13
+
14
+ ## Remember root directory when inherited
15
+ def inherited(app)
16
+ super
17
+ app.root_dir = File.dirname caller(2..2).first.split(':')[0]
18
+ end
19
+
20
+ memoize def config
21
+ Flame::Config.new root_dir
22
+ end
12
23
 
13
24
  ## Router for routing
14
- def router
15
- @router ||= Flame::Router.new(self)
25
+ memoize def router
26
+ Flame::Router.new(self)
16
27
  end
17
28
 
18
- def cached_tilts
19
- @cached_tilts ||= {}
29
+ memoize def cached_tilts
30
+ {}
20
31
  end
21
32
 
22
33
  ## Require project directories, exclude executable files
@@ -25,34 +36,20 @@ module Flame
25
36
  ## Flame::Application.require_dirs(
26
37
  ## %w[config lib models helpers mailers services controllers]
27
38
  ## )
28
- def require_dirs(dirs)
29
- caller_dir = File.dirname caller_file
39
+ def require_dirs(dirs, ignore: [])
30
40
  dirs.each do |dir|
31
- Dir[File.join(caller_dir, dir, '**/*.rb')]
32
- .reject { |file| File.executable?(file) }
33
- .sort_by { |s| [File.basename(s)[0], s] }
34
- .each { |file| require File.expand_path(file) }
41
+ require_dir File.join(root_dir, dir), ignore: ignore
35
42
  end
36
43
  end
37
44
 
38
- ## Generating application config when inherited
39
- def inherited(app)
40
- app.config = Config.new(
41
- app,
42
- default_config_dirs(
43
- root_dir: File.dirname(caller_file)
44
- ).merge(
45
- environment: ENV['RACK_ENV'] || 'development'
46
- )
47
- )
48
- end
49
-
50
45
  ## Make available `run Application` without `.new` for `rackup`
51
46
  def call(env)
52
47
  @app ||= new
53
48
  @app.call env
54
49
  end
55
50
 
51
+ using GorillaPatch::DeepDup
52
+
56
53
  ## Build a path to the given controller and action
57
54
  ##
58
55
  ## @param ctrl [Flame::Controller] class of controller
@@ -61,32 +58,45 @@ module Flame
61
58
  ## @return [String] path for requested method, controller and parameters
62
59
  ## @example Path for `show(id)` method of `ArticlesController`
63
60
  ## path_to ArticlesController, :show, id: 2 # => "/articles/show/2"
64
- ## @example Path for `new` method of `ArticlesController` with params
65
- ## path_to ArticlesController, :new, params: { author_id: 1 }
61
+ ## @example Path for `new` method of `ArticlesController` with query
62
+ ## path_to ArticlesController, :new, author_id: 1
66
63
  ## # => "/articles/new?author_id=1"
67
64
  def path_to(ctrl, action = :index, args = {})
68
65
  path = router.path_of(ctrl, action)
66
+
69
67
  raise Errors::RouteNotFoundError.new(ctrl, action) unless path
70
- query = Rack::Utils.build_nested_query args.delete(:params)
71
- query = nil if query&.empty?
68
+
69
+ args = args.deep_dup
72
70
  path = path.assign_arguments(args)
73
71
  path = '/' if path.empty?
72
+ query = Rack::Utils.build_nested_query args unless args.empty?
74
73
  Addressable::URI.new(path: path, query: query).to_s
75
74
  end
76
75
 
76
+ protected
77
+
78
+ attr_accessor :root_dir
79
+
77
80
  private
78
81
 
79
- ## Get filename from caller of method
80
- ## @return [String] filename of caller
81
- def caller_file
82
- caller(2..2).first.split(':')[0]
82
+ def require_dir(dir, ignore: [])
83
+ files =
84
+ Dir[File.join(dir, '**/*.rb')]
85
+ .reject do |file|
86
+ File.executable?(file) ||
87
+ ignore.any? { |regexp| regexp.match?(file) }
88
+ end
89
+ files.sort_by! do |file|
90
+ [File.basename(file).start_with?('_') ? 1 : 2, file]
91
+ end
92
+ files.each { |file| require File.expand_path(file) }
83
93
  end
84
94
 
85
95
  ## Mount controller in application class
86
96
  ## @param controller [Symbol] the snake-cased name of mounted controller
87
97
  ## (without `Controller` or `::IndexController` for namespaces)
88
98
  ## @param path [String, nil] root path for the mounted controller
89
- ## @yield refine defaults pathes for a methods of the mounted controller
99
+ ## @yield refine defaults paths for a methods of the mounted controller
90
100
  ## @example Mount controller with defaults
91
101
  ## mount :articles # ArticlesController
92
102
  ## @example Mount controller with specific path
@@ -101,38 +111,29 @@ module Flame
101
111
  ## mount :cabinet do # Cabinet::IndexController
102
112
  ## mount :articles # Cabinet::ArticlesController
103
113
  ## end
104
- def mount(controller_name, path = nil, &block)
114
+ def mount(controller, path = nil, nested: true, &block)
105
115
  ## Add routes from controller to glob array
106
116
  router.add Router::RoutesRefine.new(
107
- router, namespace, controller_name, path, &block
117
+ namespace_name, controller, path, nested: nested, &block
108
118
  )
109
119
  end
110
120
 
111
121
  using GorillaPatch::Namespace
112
122
 
113
- def namespace
123
+ def namespace_name
114
124
  namespace = self
115
125
  while namespace.name.nil? && namespace.superclass != Flame::Application
116
126
  namespace = superclass
117
127
  end
118
128
  namespace.deconstantize
119
129
  end
120
-
121
- ## Initialize default for config directories
122
- def default_config_dirs(root_dir:)
123
- result = { root_dir: File.realpath(root_dir) }
124
- %i[public views config tmp].each do |key|
125
- result[:"#{key}_dir"] = proc { File.join(config[:root_dir], key.to_s) }
126
- end
127
- result
128
- end
129
130
  end
130
131
 
131
132
  def initialize(app = nil)
132
133
  @app = app
133
134
  end
134
135
 
135
- ## Request recieving method
136
+ ## Request receiving method
136
137
  def call(env)
137
138
  @app.call(env) if @app.respond_to? :call
138
139
  Flame::Dispatcher.new(self.class, env).run!
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'errors/config_file_not_found_error'
4
+
5
+ module Flame
6
+ ## Class for application configuration
7
+ class Config < Hash
8
+ DEFAULT_DIRS =
9
+ %i[config log public tmp views].each_with_object({}) do |key, result|
10
+ result[:"#{key}_dir"] = proc { File.join(self[:root_dir], key.to_s) }
11
+ end.freeze
12
+
13
+ ## Create an instance of application config
14
+ ## @param app [Flame::Application] application
15
+ ## @param hash [Hash] config content
16
+ def initialize(root_dir)
17
+ super()
18
+ replace DEFAULT_DIRS.merge(
19
+ root_dir: File.realpath(root_dir),
20
+ environment: ENV['RACK_ENV'] || 'development'
21
+ )
22
+ end
23
+
24
+ ## Get config value by key
25
+ ## @param key [Symbol] config key
26
+ ## @return [Object] config value
27
+ def [](key)
28
+ result = super(key)
29
+ result = instance_exec(&result) if result.class <= Proc && result.parameters.empty?
30
+ result
31
+ end
32
+
33
+ ## Method for loading YAML-files from config directory
34
+ ## @param file [String, Symbol]
35
+ ## file name (typecast to String with '.yaml')
36
+ ## @param key [Symbol, String, nil]
37
+ ## key for allocating YAML in config Hash (typecast to Symbol)
38
+ ## @param set [Boolean] allocating YAML in Config Hash
39
+ ## @param require [Boolean] don't raise an error if file not found and not required
40
+ ## @example Load SMTP file from `config/smtp.yaml' to config[]
41
+ ## config.load_yaml('smtp.yaml')
42
+ ## @example Load SMTP file without extension, by Symbol
43
+ ## config.load_yaml(:smtp)
44
+ ## @example Load SMTP file with other key to config[:mail]
45
+ ## config.load_yaml('smtp.yaml', key: :mail)
46
+ ## @example Load SMTP file without allocating in config[]
47
+ ## config.load_yaml('smtp.yaml', set: false)
48
+ ## @example Try to load nonexistent SMTP file without raising an error
49
+ ## config.load_yaml('smtp.yaml', require: false)
50
+ def load_yaml(file, key: nil, set: true, required: true)
51
+ file = "#{file}.y{a,}ml" if file.is_a? Symbol
52
+
53
+ file_path = find_config_file file, required: required
54
+ return unless file_path
55
+
56
+ yaml = YAML.load_file(file_path)
57
+ key ||= File.basename(file, '.*')
58
+ self[key.to_sym] = yaml if set
59
+ yaml
60
+ end
61
+
62
+ private
63
+
64
+ def find_config_file(filename, required:)
65
+ file_path = Dir[File.join(self[:config_dir], filename)].first
66
+ return file_path if file_path || !required
67
+
68
+ raise Errors::ConfigFileNotFoundError.new(
69
+ filename, self[:config_dir].sub(self[:root_dir], '')
70
+ )
71
+ end
72
+ end
73
+ end
@@ -3,65 +3,48 @@
3
3
  require 'forwardable'
4
4
  require 'gorilla_patch/namespace'
5
5
 
6
+ require_relative 'router'
7
+
8
+ require_relative 'controller/actions'
9
+ require_relative 'controller/cookies'
6
10
  require_relative 'controller/path_to'
7
- require_relative 'render'
8
11
 
12
+ ## Just because of `autoload`
9
13
  module Flame
14
+ autoload :Render, "#{__dir__}/render"
15
+
10
16
  ## Class initialize when Dispatcher found route with it
11
17
  ## For new request and response
12
18
  class Controller
13
- extend Forwardable
19
+ extend Actions
20
+ include Memery
14
21
 
15
- ## Shortcut for not-inherited public methods: actions
16
- ## @return [Array<Symbol>] array of actions (public instance methods)
17
- def self.actions
18
- public_instance_methods(false)
19
- end
22
+ class << self
23
+ attr_accessor :path_arguments
24
+
25
+ def path
26
+ return self::PATH if const_defined?(:PATH)
20
27
 
21
- ## Re-define public instance methods (actions) from parent
22
- ## @param actions [Array<Symbol>] Actions for inheritance
23
- ## @param exclude [Array<Symbol>] Actions for excluding from inheritance
24
- ## @example Inherit all parent actions
25
- ## class MyController < BaseController
26
- ## inherit_actions
27
- ## end
28
- ## @example Inherit certain parent actions
29
- ## class MyController < BaseController
30
- ## inherit_actions :index, :show
31
- ## end
32
- ## @example Inherit all parent actions exclude certain
33
- ## class MyController < BaseController
34
- ## inherit_actions exclude: %i[edit update]
35
- ## end
36
- def self.inherit_actions(actions = superclass.actions, exclude: [])
37
- (actions - exclude).each do |public_method|
38
- um = superclass.public_instance_method(public_method)
39
- define_method public_method, um
28
+ default_path
40
29
  end
41
- end
42
30
 
43
- ## Re-define public instance method from module
44
- ## @example Define actions from module in controller
45
- ## class MyController < BaseController
46
- ## include with_actions Module1
47
- ## include with_actions Module2
48
- ## ....
49
- ## end
50
- def self.with_actions(mod, exclude: [])
51
- Module.new do
52
- @mod = mod
53
- @exclude = exclude
54
-
55
- def self.included(ctrl)
56
- ctrl.include @mod
57
-
58
- (@mod.public_instance_methods - @exclude).each do |meth|
59
- ctrl.send :define_method, meth, @mod.public_instance_method(meth)
60
- end
61
- end
31
+ private
32
+
33
+ using GorillaPatch::Inflections
34
+
35
+ ## Default root path of the controller for requests
36
+ def default_path
37
+ modules = underscore.split('/')
38
+ parts = modules.pop.split('_')
39
+ parts.shift if parts.first == 'index'
40
+ parts.pop if %w[controller ctrl].include? parts.last
41
+ parts = [modules.last] if parts.empty?
42
+ Flame::Path.merge nil, parts.join('_')
62
43
  end
63
44
  end
64
45
 
46
+ extend Forwardable
47
+
65
48
  def_delegators(
66
49
  :@dispatcher,
67
50
  :config, :request, :params, :halt, :session, :response, :status, :body,
@@ -74,6 +57,11 @@ module Flame
74
57
  @dispatcher = dispatcher
75
58
  end
76
59
 
60
+ ## Cookies object as Hash
61
+ memoize def cookies
62
+ Cookies.new(request.cookies, response)
63
+ end
64
+
77
65
  include Flame::Controller::PathTo
78
66
 
79
67
  ## Redirect for response
@@ -127,6 +115,7 @@ module Flame
127
115
  content_dis = 'Content-Disposition'
128
116
  response[content_dis] = disposition.to_s
129
117
  return unless filename
118
+
130
119
  response[content_dis] << "; filename=\"#{File.basename(filename)}\""
131
120
  ext = File.extname(filename)
132
121
  response.content_type = ext unless ext.empty?
@@ -157,13 +146,15 @@ module Flame
157
146
  end
158
147
 
159
148
  def not_found
160
- body default_body
149
+ default_body
161
150
  end
162
151
 
163
152
  ## Default method for Internal Server Error, can be inherited
164
153
  ## @param _exception [Exception] exception from code executing
165
154
  ## @return [String] content of exception page
166
- def server_error(_exception)
155
+ def server_error(exception)
156
+ raise exception if Object.const_defined?(:BetterErrors)
157
+
167
158
  body default_body
168
159
  end
169
160
 
@@ -184,6 +175,12 @@ module Flame
184
175
  body
185
176
  end
186
177
 
178
+ using GorillaPatch::Slice
179
+
180
+ def controller_arguments
181
+ params.slice(*self.class.path_arguments)
182
+ end
183
+
187
184
  def extract_params_for(action)
188
185
  ## Take parameters from action method
189
186
  parameters = method(action).parameters
@@ -198,35 +195,5 @@ module Flame
198
195
  ## Concat values
199
196
  req_values + opt_values
200
197
  end
201
-
202
- def add_controller_class(args)
203
- args.unshift(self.class) if args[0].is_a?(Symbol)
204
- args.insert(1, :index) if args[0].is_a?(Class) && !args[1].is_a?(Symbol)
205
- end
206
-
207
- class << self
208
- using GorillaPatch::Inflections
209
-
210
- ## Default root path of the controller for requests
211
- def default_path
212
- modules = underscore.split('/')
213
- parts = modules.pop.split('_')
214
- parts.shift if parts.first == 'index'
215
- parts.pop if %w[controller ctrl].include? parts.last
216
- parts = [modules.last] if parts.empty?
217
- Flame::Path.merge nil, parts.join('_')
218
- end
219
-
220
- def refined_http_methods
221
- @refined_http_methods ||= []
222
- end
223
-
224
- Flame::Router::HTTP_METHODS.each do |http_method|
225
- downcased_http_method = http_method.downcase
226
- define_method(downcased_http_method) do |action_path, action = nil|
227
- refined_http_methods << [downcased_http_method, action_path, action]
228
- end
229
- end
230
- end
231
198
  end
232
199
  end