racket-mvc 0.3.2 → 0.3.3

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 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