Class: Utopia::Content::Middleware
- Inherits:
-
Protocol::HTTP::Middleware
- Object
- Protocol::HTTP::Middleware
- Utopia::Content::Middleware
- Includes:
- Localization::Resolver
- Defined in:
- lib/utopia/content/middleware.rb
Overview
A middleware which serves dynamically generated content based on markup files.
Constant Summary collapse
- CONTENT_NAMESPACE =
"content".freeze
- RELATIVE_NAMESPACE =
"relative".freeze
- UTOPIA_NAMESPACE =
"utopia".freeze
- CONTENT_TAG_NAME =
"utopia:content".freeze
Constants included from Localization::Resolver
Localization::Resolver::CONTENT_LANGUAGE, Localization::Resolver::CONTENT_LOCATION
Instance Attribute Summary collapse
-
#links ⇒ Object
readonly
Returns the value of attribute links.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Instance Method Summary collapse
-
#call(request) ⇒ Object
Serve or redirect filesystem-backed content, otherwise invoke the application.
-
#fetch_template(path) ⇒ Object
Load and cache a content template.
-
#freeze ⇒ Object
Freeze this object and its internal state.
-
#initialize(app, root: Utopia::default_root, namespaces: {}) ⇒ Middleware
constructor
A new instance of Middleware.
- #lookup_node(path, locale = nil) ⇒ Object
-
#lookup_tag(qualified_name, node) ⇒ Object
Look up a named tag such as
<entry />or<content:page>.... -
#resolve_link(link) ⇒ Object
Resolve a link to an existing content node.
-
#respond(link, request, localization: request.localization) ⇒ Object
Respond.
Constructor Details
#initialize(app, root: Utopia::default_root, namespaces: {}) ⇒ Middleware
Returns a new instance of Middleware.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/utopia/content/middleware.rb', line 33 def initialize(app, root: Utopia::default_root, namespaces: {}) super(app) @root = root @template_cache = Concurrent::Map.new @node_cache = Concurrent::Map.new @links = Links.new(@root) @namespaces = namespaces # Default content namespace for dynamic path based lookup: @namespaces[CONTENT_NAMESPACE] ||= self.method(:content_tag) # Resolve content relative to the logical invocation path: @namespaces[RELATIVE_NAMESPACE] ||= self.method(:relative_tag) # The core namespace for utopia specific functionality: @namespaces[UTOPIA_NAMESPACE] ||= Tags end |
Instance Attribute Details
#links ⇒ Object (readonly)
Returns the value of attribute links.
68 69 70 |
# File 'lib/utopia/content/middleware.rb', line 68 def links @links end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
67 68 69 |
# File 'lib/utopia/content/middleware.rb', line 67 def root @root end |
Instance Method Details
#call(request) ⇒ Object
Serve or redirect filesystem-backed content, otherwise invoke the application.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/utopia/content/middleware.rb', line 124 def call(request) path = request.path # Check if the request is to a non-specific index. This only works for requests with a given name: basename = path.basename directory_path = File.join(@root, path.dirname.components, basename) # If the request for /foo/bar is actually a directory, rewrite it to /foo/bar/index: if File.directory? directory_path index_path = [basename, INDEX] location = path.dirname.join(index_path).to_url_path.encoded return Utopia::Response[307, {HTTP::LOCATION => location}, []] end response = resolve_localized(request) do |localization| locale = localization&.locale if link = @links.for(path, locale, fallback: false) self.respond(link, request, localization: localization) end end if response return response end return @delegate.call(request) end |
#fetch_template(path) ⇒ Object
Load and cache a content template.
73 74 75 76 77 |
# File 'lib/utopia/content/middleware.rb', line 73 def fetch_template(path) @template_cache.fetch_or_store(path.to_s) do XRB::Template.load_file(path) end end |
#freeze ⇒ Object
Freeze this object and its internal state.
57 58 59 60 61 62 63 64 65 |
# File 'lib/utopia/content/middleware.rb', line 57 def freeze return self if frozen? @root.freeze @namespaces.values.each(&:freeze) @namespaces.freeze super end |
#lookup_node(path, locale = nil) ⇒ Object
89 90 91 92 93 |
# File 'lib/utopia/content/middleware.rb', line 89 def lookup_node(path, locale = nil) resolve_link( @links.for(path, locale) ) end |
#lookup_tag(qualified_name, node) ⇒ Object
Look up a named tag such as <entry /> or <content:page>...
80 81 82 83 84 85 86 |
# File 'lib/utopia/content/middleware.rb', line 80 def lookup_tag(qualified_name, node) namespace, name = XRB::Tag.split(qualified_name) if library = @namespaces[namespace] library.call(name, node) end end |
#resolve_link(link) ⇒ Object
Resolve a link to an existing content node.
98 99 100 101 102 103 104 |
# File 'lib/utopia/content/middleware.rb', line 98 def resolve_link(link) if full_path = link&.full_path(@root) if File.exist?(full_path) return Node.new(self, link.path, link.path, full_path) end end end |
#respond(link, request, localization: request.localization) ⇒ Object
Respond.
111 112 113 114 115 116 117 118 119 |
# File 'lib/utopia/content/middleware.rb', line 111 def respond(link, request, localization: request.localization) if node = resolve_link(link) attributes = request.variables&.to_hash || {} return node.process!(request, attributes, localization: localization) elsif redirect_uri = link[:uri] return Utopia::Response[307, {HTTP::LOCATION => redirect_uri}, []] end end |