Class: Bridgetown::Rack::Routes
- Inherits:
-
Object
- Object
- Bridgetown::Rack::Routes
- Includes:
- Prioritizable
- Defined in:
- lib/bridgetown-core/rack/routes.rb
Class Attribute Summary collapse
Class Method Summary collapse
-
.<=>(other) ⇒ Integer
Spaceship is priority [higher -> lower].
- .inherited(base) ⇒ Object
-
.load_all_routes(roda_app) ⇒ void
Run the Roda public plugin first, set up live reload if allowed, then run through all the Routes blocks.
-
.merge(roda_app) ⇒ Object
Initialize a new Routes instance and execute the route as part of the Roda app request cycle.
-
.print_routes ⇒ Object
rubocop:disable Bridgetown/NoPutsAllowed, Metrics/MethodLength.
- .reload_subclasses ⇒ void
-
.route(&block) ⇒ Object
Add a router block via the current Routes class.
- .setup_live_reload(app) ⇒ Object
- .sorted_subclasses ⇒ Array<Class(Routes)>
-
.start!(roda_app) ⇒ void
Start the Roda app request cycle.
- .track_subclass(klass) ⇒ Object
Instance Method Summary collapse
-
#handle_routes ⇒ Object
Execute the router block via the instance, passing it the Roda request.
-
#initialize(roda_app) ⇒ Routes
constructor
A new instance of Routes.
-
#method_missing(method_name, *args, **kwargs, &block) ⇒ Object
Any missing methods are passed along to the underlying Roda app if possible.
- #respond_to_missing?(method_name, include_private = false) ⇒ Boolean
Methods included from Prioritizable
Constructor Details
#initialize(roda_app) ⇒ Routes
Returns a new instance of Routes.
195 196 197 |
# File 'lib/bridgetown-core/rack/routes.rb', line 195 def initialize(roda_app) @_roda_app = roda_app end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, **kwargs, &block) ⇒ Object
Any missing methods are passed along to the underlying Roda app if possible
208 209 210 211 212 213 214 |
# File 'lib/bridgetown-core/rack/routes.rb', line 208 def method_missing(method_name, *args, **kwargs, &block) if @_roda_app.respond_to?(method_name.to_sym) @_roda_app.send method_name.to_sym, *args, **kwargs, &block else super end end |
Class Attribute Details
.router_block ⇒ Proc
58 59 60 |
# File 'lib/bridgetown-core/rack/routes.rb', line 58 def router_block @router_block end |
.tracked_subclasses ⇒ Hash<String, Class(Routes)>
55 56 57 |
# File 'lib/bridgetown-core/rack/routes.rb', line 55 def tracked_subclasses @tracked_subclasses end |
Class Method Details
.<=>(other) ⇒ Integer
Spaceship is priority [higher -> lower]
64 65 66 |
# File 'lib/bridgetown-core/rack/routes.rb', line 64 def <=>(other) "#{priorities[priority]}#{self}" <=> "#{priorities[other.priority]}#{other}" end |
.inherited(base) ⇒ Object
69 70 71 72 |
# File 'lib/bridgetown-core/rack/routes.rb', line 69 def inherited(base) Bridgetown::Rack::Routes.track_subclass base super end |
.load_all_routes(roda_app) ⇒ void
This method returns an undefined value.
Run the Roda public plugin first, set up live reload if allowed, then run through all the Routes blocks. If the file-based router plugin is available, kick off that request process next.
148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/bridgetown-core/rack/routes.rb', line 148 def load_all_routes(roda_app) roda_app.request.public if Bridgetown.env.development? && !Bridgetown::Current.preloaded_configuration.skip_live_reload setup_live_reload roda_app end Bridgetown::Rack::Routes.sorted_subclasses&.each do |klass| klass.merge roda_app end end |
.merge(roda_app) ⇒ Object
Initialize a new Routes instance and execute the route as part of the Roda app request cycle
115 116 117 118 119 |
# File 'lib/bridgetown-core/rack/routes.rb', line 115 def merge(roda_app) return unless router_block new(roda_app).handle_routes end |
.print_routes ⇒ Object
rubocop:disable Bridgetown/NoPutsAllowed, Metrics/MethodLength
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/bridgetown-core/rack/routes.rb', line 24 def print_routes # TODO: this needs to be fully documented routes = begin JSON.parse( File.read( File.join(Bridgetown::Current.preloaded_configuration.root_dir, ".routes.json") ) ) rescue StandardError [] end puts puts "Routes:" puts "=======" if routes.blank? puts "No routes found. Have you commented all of your routes?" puts "Documentation: https://github.com/jeremyevans/roda-route_list#basic-usage-" end routes.each do |route| puts [ route["methods"]&.join("|") || "GET", route["path"], route["file"] ? "\n File: #{route["file"]}" : nil, ].compact.join(" ") end puts end |
.reload_subclasses ⇒ void
This method returns an undefined value.
86 87 88 89 90 91 92 |
# File 'lib/bridgetown-core/rack/routes.rb', line 86 def reload_subclasses Bridgetown::Rack::Routes.tracked_subclasses&.each_key do |klassname| Kernel.const_get(klassname) rescue NameError Bridgetown::Rack::Routes.tracked_subclasses.delete klassname end end |
.route(&block) ⇒ Object
Add a router block via the current Routes class
Example:
class Routes::Hello < Bridgetown::Rack::Routes route do |r| r.get "hello", String do |name| { hello: "friend #name" } end end end
107 108 109 |
# File 'lib/bridgetown-core/rack/routes.rb', line 107 def route(&block) self.router_block = block end |
.setup_live_reload(app) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/bridgetown-core/rack/routes.rb', line 162 def setup_live_reload(app) # rubocop:disable Metrics sleep_interval = 0.2 file_to_check = File.join(Bridgetown::Current.preloaded_configuration.destination, "index.html") errors_file = Bridgetown.build_errors_path app.request.get "_bridgetown/live_reload" do app.response["Content-Type"] = "text/event-stream" @_mod = File.exist?(file_to_check) ? File.stat(file_to_check).mtime.to_i : 0 app.stream async: true do |out| # 5 second intervals so Puma's threads aren't all exausted (5 / sleep_interval).to_i.times do break if Bridgetown::Rack.interrupted new_mod = File.exist?(file_to_check) ? File.stat(file_to_check).mtime.to_i : 0 if @_mod < new_mod out << "data: reloaded!\n\n" break elsif File.exist?(errors_file) out << "event: builderror\ndata: #{File.read(errors_file).to_json}\n\n" else out << "data: #{new_mod}\n\n" end sleep sleep_interval end end end end |
.sorted_subclasses ⇒ Array<Class(Routes)>
81 82 83 |
# File 'lib/bridgetown-core/rack/routes.rb', line 81 def sorted_subclasses Bridgetown::Rack::Routes.tracked_subclasses&.values&.sort end |
.start!(roda_app) ⇒ void
This method returns an undefined value.
Start the Roda app request cycle. There are two different code paths
depending on if there's a site base_path
configured
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/bridgetown-core/rack/routes.rb', line 126 def start!(roda_app) if Bridgetown::Current.preloaded_configuration.base_path == "/" load_all_routes roda_app return end # Support custom base_path configurations roda_app.request.on( Bridgetown::Current.preloaded_configuration.base_path.delete_prefix("/") ) do load_all_routes roda_app end nil end |
.track_subclass(klass) ⇒ Object
75 76 77 78 |
# File 'lib/bridgetown-core/rack/routes.rb', line 75 def track_subclass(klass) Bridgetown::Rack::Routes.tracked_subclasses ||= {} Bridgetown::Rack::Routes.tracked_subclasses[klass.name] = klass end |
Instance Method Details
#handle_routes ⇒ Object
Execute the router block via the instance, passing it the Roda request
203 204 205 |
# File 'lib/bridgetown-core/rack/routes.rb', line 203 def handle_routes instance_exec(@_roda_app.request, &self.class.router_block) end |
#respond_to_missing?(method_name, include_private = false) ⇒ Boolean
216 217 218 |
# File 'lib/bridgetown-core/rack/routes.rb', line 216 def respond_to_missing?(method_name, include_private = false) @_roda_app.respond_to?(method_name.to_sym, include_private) || super end |