racket-mvc 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 001d50b469610f255ddd267d79ee2d0a0a2a2968
4
- data.tar.gz: 04d8c1b0abad0ae5737f3f5cc7a9083aec28bd04
3
+ metadata.gz: 63921b5e05aa5980041e8817c71bcd43b015834d
4
+ data.tar.gz: 1f98ea84f965aa6c36707dd515c16b9d7ff7ae29
5
5
  SHA512:
6
- metadata.gz: 20570ca234fddaa3bd24ebd40346d5b4d26cc6332768257b22c3a5d4167adfa6e7a2860abaf74a331018a456b1b457489b1f85a1b109e51c89ceb0917b9503ed
7
- data.tar.gz: ca1f23f9ea53cc2d0e63b5627ba36118cca99da29093d213d00cec9cab65b9be2f45506bb044c332b040fc710060e0244f9bb591a3c4cc3f3e60bddca3d8f634
6
+ metadata.gz: 306ae0910122403e2adff6a1cab12d01bea39e17d7142e7b07a2ef0aa1a48e1b61c38e1debf2f2ffff3f38bebc1d9d12cd3f2770dd0509ac44e0bdb2e95c92c2
7
+ data.tar.gz: 3fdeac0f87e45d5cefda65f18ebc61d831028a09ce75ffe371f2024838e6b5f06087fe655f64fb8d405fc1e0515167d27b42f74c5c8bcf472c0371ebf05bd11a
@@ -33,6 +33,12 @@ module Racket
33
33
  @application ||= Utils.build_application(self)
34
34
  end
35
35
 
36
+ def self.calculate_url_path(file)
37
+ url_path = "/#{file.relative_path_from(@settings.controller_dir).dirname}"
38
+ url_path = '' if url_path == '/.'
39
+ url_path
40
+ end
41
+
36
42
  # Called whenever Rack sends a request to the application.
37
43
  #
38
44
  # @param [Hash] env Rack environment
@@ -111,9 +117,7 @@ module Racket
111
117
  def self.load_controllers
112
118
  inform_dev('Loading controllers.')
113
119
  @settings.store(:last_added_controller, [])
114
- Utils.paths_by_longest_path(@settings.controller_dir, File.join('**', '*.rb')).each do |path|
115
- load_controller_file(path)
116
- end
120
+ load_controller_files
117
121
  @settings.delete(:last_added_controller)
118
122
  inform_dev('Done loading controllers.') && nil
119
123
  end
@@ -124,9 +128,15 @@ module Racket
124
128
  # @return nil
125
129
  def self.load_controller_file(file)
126
130
  ::Kernel.require file
127
- url_path = "/#{file.relative_path_from(@settings.controller_dir).dirname}"
128
- url_path = '' if url_path == '/.'
129
- @router.map(url_path, @settings.fetch(:last_added_controller).pop) && nil
131
+ klass = @settings.fetch(:last_added_controller).pop
132
+ Utils.apply_helpers(klass)
133
+ @router.map(calculate_url_path(file), klass) && nil
134
+ end
135
+
136
+ def self.load_controller_files
137
+ Utils.paths_by_longest_path(@settings.controller_dir, File.join('**', '*.rb')).each do |path|
138
+ load_controller_file(path)
139
+ end
130
140
  end
131
141
 
132
142
  # Reloads the application, making any changes to the controller configuration visible
@@ -195,7 +205,8 @@ module Racket
195
205
  @view_manager ||= ViewManager.new(@settings.layout_dir, @settings.view_dir)
196
206
  end
197
207
 
198
- private_class_method :application, :inform, :init, :load_controller_file, :load_controllers,
199
- :setup_routes, :setup_static_server
208
+ private_class_method :application, :calculate_url_path, :inform, :init, :load_controller_file,
209
+ :load_controller_files, :load_controllers, :setup_routes,
210
+ :setup_static_server
200
211
  end
201
212
  end
@@ -37,13 +37,22 @@ module Racket
37
37
  # @param [Proc] blk
38
38
  # @return [nil]
39
39
  def self.__register_hook(type, methods, blk)
40
- key = "#{type}_hooks".to_sym
41
40
  meths = public_instance_methods(false)
42
41
  meths &= methods.map(&:to_sym) unless methods.empty?
43
- hooks = settings.fetch(key, {})
42
+ __update_hooks("#{type}_hooks".to_sym, meths, blk)
43
+ Application.inform_dev("Adding #{type} hook #{blk} for actions #{meths} for #{self}.")
44
+ end
45
+
46
+ # Updates hooks in settings object.
47
+ #
48
+ # @param [Symbol] hook_key
49
+ # @param [Array] meths
50
+ # @param [Proc] blk
51
+ # @return [nil]
52
+ def self.__update_hooks(hook_key, meths, blk)
53
+ hooks = settings.fetch(hook_key, {})
44
54
  meths.each { |meth| hooks[meth] = blk }
45
- setting(key, hooks)
46
- nil
55
+ setting(hook_key, hooks) && nil
47
56
  end
48
57
 
49
58
  # Adds a before hook to one or more actions. Actions should be given as a list of symbols.
@@ -73,6 +82,7 @@ module Racket
73
82
  #
74
83
  # @param [Array] helpers An array of symbols representing classes living in the Racket::Helpers
75
84
  # namespace.
85
+ # @return [nil]
76
86
  def self.helper(*helpers)
77
87
  helper_modules = {}
78
88
  unless settings.fetch(:helpers)
@@ -82,10 +92,19 @@ module Racket
82
92
  )
83
93
  end
84
94
  # Load new helpers
85
- helpers.map!(&:to_sym)
95
+ __load_helpers(helpers.map(&:to_sym), helper_modules)
96
+ end
97
+
98
+ # Loads new helpers and stores the list of helpers associated with the currenct controller
99
+ # in the settings.
100
+ #
101
+ # @param [Array] helpers Requested helpers
102
+ # @param [Array] helper_modules Helper modules already loaded
103
+ # @return nil
104
+ def self.__load_helpers(helpers, helper_modules)
86
105
  helpers.reject! { |helper| helper_modules.key?(helper) }
87
106
  helper_modules.merge!(__helper_cache.load_helpers(helpers))
88
- setting(:helpers, helper_modules)
107
+ setting(:helpers, helper_modules) && nil
89
108
  end
90
109
 
91
110
  # :nodoc:
@@ -109,7 +128,7 @@ module Racket
109
128
  settings.store(key, value)
110
129
  end
111
130
 
112
- private_class_method :__helper_cache, :__register_hook
131
+ private_class_method :__helper_cache, :__load_helpers, :__register_hook, :__update_hooks
113
132
 
114
133
  # Returns the settings for a controller instance.
115
134
  #
@@ -27,23 +27,14 @@ module Racket
27
27
 
28
28
  # Called whenever a new request needs to be processed.
29
29
  #
30
- # @param [Hash] env Rack environment
31
- # @param [Class] klass Target klass, needed because we are copying stuff from the class to the
32
- # instance.
33
- # @param [Symbol] action Keeps track of which action was called on the controller
34
- # @param [Array] params Parameters sent to the action
30
+ # @param [RouterParams] router_params
35
31
  # @return [Module] A module encapsulating all state relating to the current request
36
- def self.init(env, klass, action, params)
37
- settings = klass.settings
38
- klass.helper unless settings.fetch(:helpers) # Makes sure default helpers are loaded.
39
- helpers = settings.fetch(:helpers)
40
- properties = init_properties(action, params, env)
41
- init_module(helpers, properties)
32
+ def self.init(router_params)
33
+ init_module(init_properties(*router_params.to_a))
42
34
  end
43
35
 
44
- def self.init_module(helpers, properties)
36
+ def self.init_module(properties)
45
37
  Module.new do
46
- helpers.each_value { |helper| include helper }
47
38
  properties.each_pair { |key, value| define_method(key) { value } }
48
39
  end
49
40
  end
@@ -19,5 +19,14 @@
19
19
  module Racket
20
20
  # Represents a response from the application
21
21
  class Response < Rack::Response
22
+ # Generates a basic error response.
23
+ #
24
+ # @param [Fixnum] status
25
+ # @return [Array]
26
+ def self.generate_error_response(status)
27
+ response = new([], status, 'Content-Type' => 'text/plain')
28
+ response.write("#{status} #{Rack::Utils::HTTP_STATUS_CODES[status]}")
29
+ response.finish
30
+ end
22
31
  end
23
32
  end
@@ -72,9 +72,7 @@ module Racket
72
72
  fail(error) if error && Application.dev_mode?
73
73
 
74
74
  # Not running in dev mode, let us handle the error ourselves.
75
- response = Response.new([], status, 'Content-Type' => 'text/plain')
76
- response.write("#{status} #{Rack::Utils::HTTP_STATUS_CODES[status]}")
77
- response.finish
75
+ Response.generate_error_response(status)
78
76
  end
79
77
 
80
78
  # Routes a request and renders it.
@@ -56,13 +56,16 @@ module Racket
56
56
  # @param [String] directory
57
57
  # @return [nil]
58
58
  def self.directory_setting(symbol, directory)
59
- ivar = "@#{symbol}".to_sym
59
+ define_directory_method(symbol, "@#{symbol}".to_sym, directory)
60
+ attr_writer(symbol) && nil
61
+ end
62
+
63
+ def self.define_directory_method(symbol, ivar, directory)
60
64
  define_method symbol do
61
65
  instance_variable_set(ivar, directory) unless instance_variables.include?(ivar)
62
66
  return nil unless (value = instance_variable_get(ivar))
63
67
  Utils.build_path(value)
64
68
  end
65
- attr_writer(symbol) && nil
66
69
  end
67
70
 
68
71
  directory_setting(:controller_dir, 'controllers')
@@ -70,6 +73,8 @@ module Racket
70
73
  directory_setting(:layout_dir, 'layouts')
71
74
  directory_setting(:public_dir, 'public')
72
75
  directory_setting(:view_dir, 'views')
76
+
77
+ private_class_method :define_directory_method
73
78
  end
74
79
  end
75
80
  end
@@ -69,6 +69,27 @@ module Racket
69
69
  helper_module
70
70
  end
71
71
  end
72
+
73
+ # Applies helpers to a controller class by including the modules in the class.
74
+ #
75
+ # @param [Class] klass
76
+ def self.apply_helpers(klass)
77
+ klass.helper unless klass.settings.fetch(:helpers) # Makes sure default helpers are loaded.
78
+ __apply_helpers(klass)
79
+ nil
80
+ end
81
+
82
+ def self.__apply_helpers(klass)
83
+ klass.settings.fetch(:helpers).reverse_each do |pair|
84
+ helper_key, helper = pair
85
+ ::Racket::Application.inform_dev(
86
+ "Adding helper module #{helper_key.inspect} to #{klass}"
87
+ )
88
+ klass.send(:include, helper)
89
+ end
90
+ end
91
+
92
+ private_class_method :__apply_helpers
72
93
  end
73
94
  end
74
95
  end
@@ -20,6 +20,9 @@ module Racket
20
20
  module Utils
21
21
  # Utility functions for routing.
22
22
  module Routing
23
+ # Struct for keeping track router parameters.
24
+ RouterParams = Struct.new(:action, :params, :env)
25
+
23
26
  # Class for caching actions
24
27
  class ActionCache
25
28
  attr_reader :items
@@ -96,7 +99,10 @@ module Racket
96
99
  update_path_info(env, params.length)
97
100
 
98
101
  # Initialize and render target
99
- call_controller(controller_class, Current.init(env, controller_class, action, params))
102
+ call_controller(
103
+ controller_class,
104
+ Current.init(RouterParams.new(action, params, env))
105
+ )
100
106
  end
101
107
 
102
108
  # Updates the PATH_INFO environment variable.
@@ -22,15 +22,31 @@ module Racket
22
22
  module Utils
23
23
  # Utility functions for views.
24
24
  module Views
25
+ # Cache for storing templates
26
+ class TemplateCache
27
+ def initialize
28
+ @cache = {}
29
+ end
30
+
31
+ # Returns a cached template. If the template has not been cached yet, this method will run a
32
+ # lookup against the provided parameters.
33
+ #
34
+ # @param [String] path
35
+ # @param [TemplateParams] template_params
36
+ # @return [String|Proc|nil]
37
+ def ensure_in_cache(path, template_params)
38
+ return @cache[path] if @cache.key?(path)
39
+ @cache[path] = TemplateLocator.calculate_path(path, template_params)
40
+ end
41
+ end
42
+
25
43
  # Class used for locating templates.
26
44
  class TemplateLocator
27
- # Struct for holding template data.
28
- TemplateParams = Struct.new(:type, :controller, :base_dir, :cache)
29
45
  def initialize(layout_base_dir, view_base_dir)
30
46
  @layout_base_dir = layout_base_dir
31
47
  @view_base_dir = view_base_dir
32
- @layout_cache = {}
33
- @view_cache = {}
48
+ @layout_cache = TemplateCache.new
49
+ @view_cache = TemplateCache.new
34
50
  end
35
51
 
36
52
  # Returns the layout associated with the current request. On the first request to any action
@@ -53,28 +69,6 @@ module Racket
53
69
 
54
70
  private
55
71
 
56
- def calculate_path(template_params, path)
57
- type, controller, base_dir = template_params.to_a
58
- default_template = controller.settings.fetch("default_#{type}".to_sym)
59
- template =
60
- self.class.lookup_template_with_default(Utils.fs_path(base_dir, path), default_template)
61
- ::Racket::Application.inform_dev(
62
- "Using #{type} #{template.inspect} for #{controller.class}.#{controller.racket.action}."
63
- )
64
- template
65
- end
66
-
67
- # Returns a cached template. If the template has not been cached yet, this method will run a
68
- # lookup against the provided parameters.
69
- #
70
- # @param [TemplateParams] template_params
71
- # @return [String|Proc|nil]
72
- def ensure_in_cache(template_params, path)
73
- cache = template_params.cache
74
- return cache[path] if cache.key?(path)
75
- cache[path] = calculate_path(template_params, path)
76
- end
77
-
78
72
  # Tries to locate a template matching +path+ in the file system and returns the path if a
79
73
  # matching file is found. If no matching file is found, +nil+ is returned. The result is
80
74
  # cached, meaning that the filesystem lookup for a specific path will only happen once.
@@ -84,11 +78,24 @@ module Racket
84
78
  def get_template(template_params)
85
79
  klass = self.class
86
80
  path = klass.get_template_path(template_params.controller)
87
- template = ensure_in_cache(template_params, path)
88
- klass.resolve_template(template_params, path, template)
81
+ template = template_params.cache.ensure_in_cache(path, template_params)
82
+ klass.resolve_template(path, template, template_params)
83
+ end
84
+
85
+ def self.calculate_path(path, template_params)
86
+ type, controller, base_dir = template_params.to_a
87
+ default_template = controller.settings.fetch("default_#{type}".to_sym)
88
+ template =
89
+ TemplateLocator.lookup_template_with_default(
90
+ Utils.fs_path(base_dir, path), default_template
91
+ )
92
+ ::Racket::Application.inform_dev(
93
+ "Using #{type} #{template.inspect} for #{controller.class}.#{controller.racket.action}."
94
+ )
95
+ template
89
96
  end
90
97
 
91
- def self.resolve_template(template_params, path, template)
98
+ def self.resolve_template(path, template, template_params)
92
99
  return template unless template.is_a?(Proc)
93
100
  _, controller, base_dir = template_params.to_a
94
101
  lookup_template(
@@ -112,10 +119,8 @@ module Racket
112
119
  # @param [Racket::Controller] controller
113
120
  # @return [String]
114
121
  def self.call_template_proc(proc, controller)
115
- possible_proc_args =
116
- [controller.racket.action, controller.racket.params, controller.request]
117
- proc_args = []
118
- 1.upto(proc.arity) { proc_args.push(possible_proc_args.shift) }
122
+ racket = controller.racket
123
+ proc_args = [racket.action, racket.params, controller.request].slice(0...proc.arity)
119
124
  proc.call(*proc_args).to_s
120
125
  end
121
126
 
@@ -195,6 +200,9 @@ module Racket
195
200
 
196
201
  private_class_method :render_template, :send_response
197
202
  end
203
+
204
+ # Struct for holding template data.
205
+ TemplateParams = Struct.new(:type, :controller, :base_dir, :cache)
198
206
  end
199
207
  end
200
208
  end
@@ -25,7 +25,7 @@ module Racket
25
25
  # Minor version
26
26
  MINOR = 3
27
27
  # Teeny version
28
- TEENY = 2
28
+ TEENY = 3
29
29
  # Is it a prerelease?
30
30
  PRERELEASE = false
31
31
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: racket-mvc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Olsson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-28 00:00:00.000000000 Z
11
+ date: 2015-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http_router