racket-mvc 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -5
- data/lib/racket.rb +25 -7
- data/lib/racket/application.rb +70 -136
- data/lib/racket/controller.rb +95 -38
- data/lib/racket/current.rb +1 -1
- data/lib/racket/helpers/file.rb +7 -5
- data/lib/racket/helpers/routing.rb +5 -5
- data/lib/racket/helpers/sass.rb +11 -11
- data/lib/racket/helpers/view.rb +8 -5
- data/lib/racket/plugins/base.rb +1 -1
- data/lib/racket/plugins/sass.rb +1 -1
- data/lib/racket/request.rb +3 -3
- data/lib/racket/response.rb +1 -1
- data/lib/racket/router.rb +31 -12
- data/lib/racket/session.rb +3 -3
- data/lib/racket/settings/application.rb +27 -33
- data/lib/racket/settings/base.rb +19 -8
- data/lib/racket/settings/controller.rb +9 -7
- data/lib/racket/settings/defaults.rb +81 -0
- data/lib/racket/utils.rb +19 -15
- data/lib/racket/utils/application.rb +4 -114
- data/lib/racket/utils/application/handler_stack.rb +163 -0
- data/lib/racket/utils/application/logger.rb +72 -0
- data/lib/racket/utils/application/registry_builder.rb +88 -0
- data/lib/racket/utils/application/stateless_services.rb +73 -0
- data/lib/racket/utils/exceptions.rb +3 -3
- data/lib/racket/utils/file_system.rb +75 -47
- data/lib/racket/utils/helpers.rb +35 -13
- data/lib/racket/utils/routing.rb +62 -46
- data/lib/racket/utils/views.rb +19 -187
- data/lib/racket/utils/views/renderer.rb +75 -0
- data/lib/racket/utils/views/template_cache.rb +126 -0
- data/lib/racket/utils/views/template_locator.rb +83 -0
- data/lib/racket/utils/views/template_resolver.rb +112 -0
- data/lib/racket/version.rb +2 -2
- data/lib/racket/view_manager.rb +12 -4
- data/rake/utils.rb +5 -5
- data/spec/_custom.rb +69 -19
- data/spec/_default.rb +60 -44
- data/spec/_plugin.rb +12 -14
- data/spec/_template_cache.rb +176 -0
- data/spec/racket.rb +10 -13
- data/spec/test_custom_app/controllers/sub1/custom_sub_controller_1.rb +1 -1
- data/spec/test_custom_app/controllers/sub3/custom_sub_controller_3.rb +19 -1
- data/spec/test_custom_app/controllers/sub5/custom_sub_controller_5.rb +8 -0
- data/spec/test_custom_app/files/stuff.rb +3 -0
- data/spec/test_custom_app/files/triplet.erb +5 -0
- data/spec/test_custom_app/templates/sub5/text.erb +3 -0
- data/spec/test_default_app/controllers/default_root_controller.rb +3 -0
- data/spec/test_default_app/controllers/sub1/default_sub_controller_1.rb +1 -1
- metadata +52 -11
data/lib/racket/current.rb
CHANGED
data/lib/racket/helpers/file.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -23,8 +23,9 @@ module Racket
|
|
23
23
|
module File
|
24
24
|
# Class for sending files.
|
25
25
|
class Response
|
26
|
-
def initialize(file, options)
|
27
|
-
@
|
26
|
+
def initialize(utils, file, options)
|
27
|
+
@utils = utils
|
28
|
+
@file = @utils.build_path(file)
|
28
29
|
@options = options
|
29
30
|
@response = Racket::Response.new
|
30
31
|
build
|
@@ -40,7 +41,7 @@ module Racket
|
|
40
41
|
private
|
41
42
|
|
42
43
|
def build
|
43
|
-
if Utils.file_readable?(@file) then build_success
|
44
|
+
if Racket::Utils::FileSystem.file_readable?(@file) then build_success
|
44
45
|
else build_failure
|
45
46
|
end
|
46
47
|
end
|
@@ -82,7 +83,8 @@ module Racket
|
|
82
83
|
# @param [Hash] options
|
83
84
|
# @return [Array]
|
84
85
|
def send_file(file, options = {})
|
85
|
-
|
86
|
+
response = Response.new(Controller.context.utils, file, options).to_a
|
87
|
+
respond!(*response)
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -28,10 +28,10 @@ module Racket
|
|
28
28
|
# @param [Array] params
|
29
29
|
# @return [String]
|
30
30
|
def route(controller, action = nil, *params)
|
31
|
-
|
31
|
+
controller.get_route(action, params)
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
alias r route
|
35
35
|
|
36
36
|
# Returns a route to an action within the current controller.
|
37
37
|
#
|
@@ -39,10 +39,10 @@ module Racket
|
|
39
39
|
# @param [Array] params
|
40
40
|
# @return [String]
|
41
41
|
def route_self(action = nil, *params)
|
42
|
-
|
42
|
+
self.class.get_route(action, params)
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
alias rs route_self
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
data/lib/racket/helpers/sass.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -26,24 +26,24 @@ module Racket
|
|
26
26
|
# @param [Symbol] sym
|
27
27
|
# @return [String]
|
28
28
|
def css(sym)
|
29
|
-
route =
|
29
|
+
route = self.class.get_route
|
30
30
|
route = '' if route == '/' # Special case for root controller
|
31
31
|
"/css#{route}/#{sym}.css"
|
32
32
|
end
|
33
33
|
|
34
|
-
def self.add_template_location(route)
|
35
|
-
|
36
|
-
sass_dir =
|
37
|
-
css_dir =
|
34
|
+
def self.add_template_location(klass, route)
|
35
|
+
utils = klass.context.utils
|
36
|
+
sass_dir = utils.build_path('sass', route).to_s
|
37
|
+
css_dir = utils.build_path('public', 'css', route).to_s
|
38
38
|
::Sass::Plugin.add_template_location(sass_dir, css_dir)
|
39
39
|
sass_dir
|
40
40
|
end
|
41
41
|
|
42
|
-
def self.add_warmup_urls(sass_dir, route)
|
42
|
+
def self.add_warmup_urls(klass, sass_dir, route)
|
43
43
|
Dir.chdir(sass_dir) do
|
44
44
|
basedir = route.empty? ? '/css' : "/css/#{route}"
|
45
45
|
Dir.glob('*.s[ac]ss').each do |file|
|
46
|
-
|
46
|
+
klass.settings.fetch(:warmup_urls) << "#{basedir}/#{::File.basename(file, '.*')}.css"
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -54,9 +54,9 @@ module Racket
|
|
54
54
|
# @param [Class] klass
|
55
55
|
# @return [nil]
|
56
56
|
def self.included(klass)
|
57
|
-
route =
|
58
|
-
sass_dir = add_template_location(route)
|
59
|
-
add_warmup_urls(sass_dir, route)
|
57
|
+
route = klass.get_route.slice(1..-1) # Remove leading slash
|
58
|
+
sass_dir = add_template_location(klass, route)
|
59
|
+
add_warmup_urls(klass, sass_dir, route)
|
60
60
|
nil
|
61
61
|
end
|
62
62
|
|
data/lib/racket/helpers/view.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -26,10 +26,13 @@ module Racket
|
|
26
26
|
# @param [String] template
|
27
27
|
# @param [Object] context
|
28
28
|
# @return [String|nil]
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
# @todo Allow user to specify template options
|
30
|
+
def render_template(template, context = self, template_settings = nil)
|
31
|
+
utils = Controller.context.utils
|
32
|
+
template = utils.build_path(template)
|
33
|
+
return nil unless Racket::Utils::FileSystem.file_readable?(template)
|
34
|
+
settings = ::Racket::Utils::Views.extract_template_settings(context, template_settings)
|
35
|
+
Tilt.new(template, nil, settings).render(context)
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
data/lib/racket/plugins/base.rb
CHANGED
data/lib/racket/plugins/sass.rb
CHANGED
data/lib/racket/request.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -27,7 +27,7 @@ module Racket
|
|
27
27
|
undef_method :session, :session_options
|
28
28
|
|
29
29
|
# Redefine methods for handling GET parameters
|
30
|
-
|
30
|
+
alias get_params GET
|
31
31
|
undef_method :GET
|
32
32
|
|
33
33
|
# Returns a value from the GET parameter hash.
|
@@ -40,7 +40,7 @@ module Racket
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# Redefine methods for handling POST parameters
|
43
|
-
|
43
|
+
alias post_params POST
|
44
44
|
undef_method :POST
|
45
45
|
|
46
46
|
# Returns a value from the POST parameter hash.
|
data/lib/racket/response.rb
CHANGED
data/lib/racket/router.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -16,6 +16,7 @@
|
|
16
16
|
# You should have received a copy of the GNU Affero General Public License
|
17
17
|
# along with Racket. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
|
19
|
+
require 'ostruct'
|
19
20
|
require 'set'
|
20
21
|
|
21
22
|
require 'http_router'
|
@@ -34,13 +35,31 @@ module Racket
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
attr_reader :action_cache
|
38
38
|
attr_reader :routes
|
39
39
|
|
40
|
-
|
40
|
+
# Returns a service proc that can be used by the registry.
|
41
|
+
#
|
42
|
+
# @param [Hash] _options (unused)
|
43
|
+
# @return [Proc]
|
44
|
+
def self.service(_options = {})
|
45
|
+
lambda do |reg|
|
46
|
+
new(
|
47
|
+
action_cache: reg.action_cache,
|
48
|
+
dev_mode: reg.application_settings.mode == :dev,
|
49
|
+
logger: reg.application_logger
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Racket::Utils::Routing::ActionCache]
|
55
|
+
def action_cache
|
56
|
+
@options.action_cache
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(options)
|
60
|
+
@options = OpenStruct.new(options)
|
41
61
|
@router = HttpRouter.new
|
42
62
|
@routes = {}
|
43
|
-
@action_cache = Utils::Routing::ActionCache.new
|
44
63
|
end
|
45
64
|
|
46
65
|
# Returns a route to the specified controller/action/parameter combination.
|
@@ -50,7 +69,7 @@ module Racket
|
|
50
69
|
# @param [Array] params
|
51
70
|
# @return [String]
|
52
71
|
def get_route(controller_class, action, params)
|
53
|
-
|
72
|
+
raise "Cannot find controller #{controller_class}" unless @routes.key?(controller_class)
|
54
73
|
params.flatten!
|
55
74
|
Route.new(@routes[controller_class], action, params).to_s
|
56
75
|
end
|
@@ -63,13 +82,13 @@ module Racket
|
|
63
82
|
def map(path, controller_class)
|
64
83
|
map_controller(path.empty? ? '/' : path, controller_class)
|
65
84
|
@router.add("#{path}(/*params)").to(controller_class)
|
66
|
-
|
85
|
+
action_cache.add(controller_class)
|
67
86
|
end
|
68
87
|
|
69
88
|
# @todo: Allow the user to set custom handlers for different errors
|
70
89
|
def render_error(status, error = nil)
|
71
90
|
# If running in dev mode, let Rack::ShowExceptions handle the error.
|
72
|
-
|
91
|
+
raise error if error && @options.dev_mode
|
73
92
|
|
74
93
|
# Not running in dev mode, let us handle the error ourselves.
|
75
94
|
Response.generate_error_response(status)
|
@@ -83,7 +102,7 @@ module Racket
|
|
83
102
|
catch :response do # Catches early exits from Controller.respond.
|
84
103
|
# Ensure that that a controller will respond to the request. If not, send a 404.
|
85
104
|
return render_error(404) unless (target_info = target_info(env))
|
86
|
-
Utils.
|
105
|
+
Racket::Utils::Routing::Dispatcher.new(env, target_info).dispatch
|
87
106
|
end
|
88
107
|
rescue => err
|
89
108
|
render_error(500, err)
|
@@ -92,7 +111,7 @@ module Racket
|
|
92
111
|
private
|
93
112
|
|
94
113
|
def map_controller(base_path, controller_class)
|
95
|
-
|
114
|
+
@options.logger.inform_dev("Mapping #{controller_class} to #{base_path}.")
|
96
115
|
@routes[controller_class] = base_path
|
97
116
|
end
|
98
117
|
|
@@ -105,10 +124,10 @@ module Racket
|
|
105
124
|
matching_route = @router.recognize(env).first
|
106
125
|
# Exit early if no controller is responsible for the route
|
107
126
|
return nil unless matching_route
|
108
|
-
# Some controller is claiming to be responsible for the route
|
109
|
-
result = Utils.extract_target(matching_route.first)
|
127
|
+
# Some controller is claiming to be responsible for the route, find out which one.
|
128
|
+
result = Racket::Utils::Routing::Dispatcher.extract_target(matching_route.first)
|
110
129
|
# Exit early if action is not available on target
|
111
|
-
return nil unless
|
130
|
+
return nil unless action_cache.present?(result.first, result.last)
|
112
131
|
result
|
113
132
|
end
|
114
133
|
end
|
data/lib/racket/session.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -29,7 +29,7 @@ module Racket
|
|
29
29
|
def inspect
|
30
30
|
"#<#{self.class}:#{object_id}>"
|
31
31
|
end
|
32
|
-
|
33
|
-
|
32
|
+
alias to_s inspect
|
33
|
+
alias to_str inspect
|
34
34
|
end
|
35
35
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -16,39 +16,31 @@
|
|
16
16
|
# You should have received a copy of the GNU Affero General Public License
|
17
17
|
# along with Racket. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
|
19
|
-
require 'logger'
|
20
|
-
|
21
19
|
require_relative 'base.rb'
|
20
|
+
require_relative 'defaults.rb'
|
22
21
|
|
23
22
|
module Racket
|
24
23
|
module Settings
|
25
24
|
# Class for storing application settings.
|
26
25
|
class Application < Base
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
setting(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
old_secret: SecureRandom.hex(16),
|
43
|
-
secret: SecureRandom.hex(16)
|
44
|
-
}
|
45
|
-
]
|
46
|
-
)
|
47
|
-
setting(:root_dir, nil) # Will be set automatically by constructor.
|
48
|
-
setting(:warmup_urls, Set.new)
|
26
|
+
@defaults = Defaults.application_defaults
|
27
|
+
|
28
|
+
[
|
29
|
+
:default_action, :default_content_type, :default_controller_helpers,
|
30
|
+
:default_layout, :default_view, :logger, :middleware, :mode, :plugins,
|
31
|
+
:session_handler, :root_dir, :template_settings, :warmup_urls
|
32
|
+
].each { |key| setting(key) }
|
33
|
+
|
34
|
+
# Returns a service proc that can be used by the registry.
|
35
|
+
#
|
36
|
+
# @param [Hash] options
|
37
|
+
# @return [Proc]
|
38
|
+
def self.service(options = {})
|
39
|
+
->(reg) { new(reg.utils, options) }
|
40
|
+
end
|
49
41
|
|
50
|
-
def initialize(defaults = {})
|
51
|
-
|
42
|
+
def initialize(utils, defaults = {})
|
43
|
+
@utils = utils
|
52
44
|
super(defaults)
|
53
45
|
end
|
54
46
|
|
@@ -66,15 +58,17 @@ module Racket
|
|
66
58
|
define_method symbol do
|
67
59
|
instance_variable_set(ivar, directory) unless instance_variables.include?(ivar)
|
68
60
|
return nil unless (value = instance_variable_get(ivar))
|
69
|
-
|
61
|
+
@utils.build_path(value)
|
70
62
|
end
|
71
63
|
end
|
72
64
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
65
|
+
{
|
66
|
+
controller_dir: 'controllers',
|
67
|
+
helper_dir: 'helpers',
|
68
|
+
layout_dir: 'layouts',
|
69
|
+
public_dir: 'public',
|
70
|
+
view_dir: 'views'
|
71
|
+
}.each_pair { |key, value| directory_setting(key, value) }
|
78
72
|
|
79
73
|
private_class_method :define_directory_method
|
80
74
|
end
|
data/lib/racket/settings/base.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Racket - The noisy Rack MVC framework
|
2
|
-
# Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
|
2
|
+
# Copyright (C) 2015-2016 Lars Olsson <lasso@lassoweb.se>
|
3
3
|
#
|
4
4
|
# This file is part of Racket.
|
5
5
|
#
|
@@ -36,8 +36,8 @@ module Racket
|
|
36
36
|
# @param [Symbol] key
|
37
37
|
# @return [nil]
|
38
38
|
def delete(key)
|
39
|
-
|
40
|
-
|
39
|
+
raise ArgumentErrpr,
|
40
|
+
"Cannot delete standard setting #{key}" if respond_to?(key.to_sym)
|
41
41
|
@custom.delete(key) && nil
|
42
42
|
end
|
43
43
|
|
@@ -68,20 +68,31 @@ module Racket
|
|
68
68
|
# @param [Object] value
|
69
69
|
# @return [nil]
|
70
70
|
def store(key, value)
|
71
|
-
|
72
|
-
|
71
|
+
raise ArgumentError,
|
72
|
+
"Cannot overwrite standard setting #{key}" if respond_to?("#{key}=".to_sym)
|
73
73
|
(@custom[key] = value) && nil
|
74
74
|
end
|
75
75
|
|
76
|
+
# Returns a default value for a key. Default values are stored in @defaults, which is a
|
77
|
+
# Racket::Registry object.
|
78
|
+
#
|
79
|
+
# @param [Symbol] symbol
|
80
|
+
# @return [Object]
|
81
|
+
def self.default_value(symbol)
|
82
|
+
return nil unless defined?(@defaults) && @defaults.respond_to?(symbol)
|
83
|
+
@defaults.send(symbol)
|
84
|
+
end
|
85
|
+
|
76
86
|
# Creates a setting with a default value.
|
77
87
|
#
|
78
88
|
# @param [Symbol] symbol
|
79
|
-
# @param [Object] default
|
80
89
|
# @return [nil]
|
81
|
-
def self.setting(symbol
|
90
|
+
def self.setting(symbol)
|
91
|
+
klass = self
|
82
92
|
ivar = "@#{symbol}".to_sym
|
83
93
|
define_method symbol do
|
84
|
-
instance_variable_set(ivar,
|
94
|
+
instance_variable_set(ivar, klass.default_value(symbol)) unless
|
95
|
+
instance_variables.include?(ivar)
|
85
96
|
instance_variable_get(ivar)
|
86
97
|
end
|
87
98
|
attr_writer(symbol) && nil
|