Class: Impression::Resource
- Inherits:
-
Object
- Object
- Impression::Resource
- Defined in:
- lib/impression/resource.rb
Overview
The ‘Resource` class represents an abstract web resource. Resources are organized in tree like structure, with the structure normally corresponding to the URL path hierarchy. Other ways of organising resources, according to other taxonomies, can be implemented as long as the resources implement the same interface as the `Resource` class, which includes the following methods:
-
‘Resource#route` - returns the resource which should respond to the request.
-
‘Resource#respond` - responds to the request.
Constant Summary collapse
- FIRST_PATH_SEGMENT_REGEXP =
/^(\/[^\/]+)\//.freeze
Instance Attribute Summary collapse
-
#children ⇒ Object
readonly
A hash mapping relative paths to child resources.
-
#parent ⇒ Object
readonly
Reference to the parent resource.
-
#path ⇒ Object
readonly
The resource’s path relative to its parent.
Instance Method Summary collapse
-
#absolute_path ⇒ String
Returns the resource’s absolute path, according to its location in the resource hierarchy.
-
#add_child(child) ⇒ Impression::Resource
Adds a child reference to the children map.
-
#call(req) ⇒ void
Responds to the given request by rendering a 404 Not found response.
-
#each(&block) ⇒ Impression::Resource
Iterates over the resource and any of its sub-resources, passing each to the given block.
-
#html_response(html, **headers) ⇒ Object
Returns a callable that responds with HTML using the given parameters.
-
#initialize(parent: nil, path:, &block) ⇒ void
constructor
Initalizes a new resource instance.
-
#json_response(object, **headers) ⇒ Object
Returns a callable that responds with JSON using the given parameters.
-
#remount(parent, path) ⇒ void
Remounts the resource on a different parent and path.
-
#remove_child(child) ⇒ Impression::Resource
Removes a child reference from the children map.
-
#render_tree_to_static_files(base_path) ⇒ Impression::Resource
Renders the resource and all of its sub-resources to static files.
-
#route(req) ⇒ Impression::Resource?
Routes the request by matching self and any children against the request path, returning the target resource, or nil if there’s no match.
-
#text_response(text, **headers) ⇒ Object
Returns a callable that responds with plain text using the given parameters.
-
#to_proc ⇒ Proc
Converts the resource to a Proc, for use as a Qeweney app.
Constructor Details
#initialize(parent: nil, path:, &block) ⇒ void
Initalizes a new resource instance. If a block is given, it is used as the request handler instead of the default one, which returns ‘404 NOT FOUND`.
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/impression/resource.rb', line 36 def initialize(parent: nil, path:, &block) @parent = parent @path = normalize_route_path(path) @route_regexp = @path == '/' ? nil : /^#{@path}(\/.*)?$/.freeze @children = {} @parent&.add_child(self) if block singleton_class.define_method(:call, &block) end end |
Instance Attribute Details
#children ⇒ Object (readonly)
A hash mapping relative paths to child resources
27 28 29 |
# File 'lib/impression/resource.rb', line 27 def children @children end |
#parent ⇒ Object (readonly)
Reference to the parent resource
21 22 23 |
# File 'lib/impression/resource.rb', line 21 def parent @parent end |
#path ⇒ Object (readonly)
The resource’s path relative to its parent
24 25 26 |
# File 'lib/impression/resource.rb', line 24 def path @path end |
Instance Method Details
#absolute_path ⇒ String
Returns the resource’s absolute path, according to its location in the resource hierarchy.
64 65 66 |
# File 'lib/impression/resource.rb', line 64 def absolute_path @absoulte_path ||= File.join(@parent ? @parent.absolute_path : '/', @path) end |
#add_child(child) ⇒ Impression::Resource
Adds a child reference to the children map.
82 83 84 85 |
# File 'lib/impression/resource.rb', line 82 def add_child(child) @children[child.path] = child self end |
#call(req) ⇒ void
This method returns an undefined value.
Responds to the given request by rendering a 404 Not found response.
100 101 102 |
# File 'lib/impression/resource.rb', line 100 def call(req) req.respond(nil, ':status' => Qeweney::Status::NOT_FOUND) end |
#each(&block) ⇒ Impression::Resource
Iterates over the resource and any of its sub-resources, passing each to the given block.
72 73 74 75 76 |
# File 'lib/impression/resource.rb', line 72 def each(&block) block.(self) @children.values.each { |c| c.each(&block) } self end |
#html_response(html, **headers) ⇒ Object
Returns a callable that responds with HTML using the given parameters.
169 170 171 |
# File 'lib/impression/resource.rb', line 169 def html_response(html, **headers) ->(req) { req.respond_html(html, **headers) } end |
#json_response(object, **headers) ⇒ Object
Returns a callable that responds with JSON using the given parameters.
178 179 180 |
# File 'lib/impression/resource.rb', line 178 def json_response(object, **headers) ->(req) { req.respond_json(object, **headers) } end |
#remount(parent, path) ⇒ void
This method returns an undefined value.
Remounts the resource on a different parent and path.
54 55 56 57 58 |
# File 'lib/impression/resource.rb', line 54 def remount(parent, path) @parent&.remove_child(self) @parent = parent @path = normalize_route_path(path) end |
#remove_child(child) ⇒ Impression::Resource
Removes a child reference from the children map.
91 92 93 94 |
# File 'lib/impression/resource.rb', line 91 def remove_child(child) @children.delete(child.path) self end |
#render_tree_to_static_files(base_path) ⇒ Impression::Resource
Renders the resource and all of its sub-resources to static files.
135 136 137 138 139 140 141 142 143 |
# File 'lib/impression/resource.rb', line 135 def render_tree_to_static_files(base_path) each do |r| path = File.join(base_path, r.relative_static_file_path) dir = File.dirname(path) FileUtils.mkdir_p(dir) if !File.directory?(dir) File.open(path, 'w') { |f| r.render_to_file(f) } end self end |
#route(req) ⇒ Impression::Resource?
Routes the request by matching self and any children against the request path, returning the target resource, or nil if there’s no match.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/impression/resource.rb', line 111 def route(req) case (relative_path = req.match_resource_path?(@route_regexp)) when nil return nil when '/' return self else # naive case child = @children[relative_path] return child.route(req) if child if (m = relative_path.match(FIRST_PATH_SEGMENT_REGEXP)) child = @children[m[1]] return child.route(req) if child end return self end end |
#text_response(text, **headers) ⇒ Object
Returns a callable that responds with plain text using the given parameters.
160 161 162 |
# File 'lib/impression/resource.rb', line 160 def text_response(text, **headers) ->(req) { req.respond_text(text, **headers) } end |
#to_proc ⇒ Proc
Converts the resource to a Proc, for use as a Qeweney app.
148 149 150 151 152 153 |
# File 'lib/impression/resource.rb', line 148 def to_proc ->(req) do resource = route(req) || self resource.call(req) end end |