racket-mvc 0.4.0 → 0.5.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.
- 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
|